rackspace: set headers when uploading files to CF.

Otherwise CDN (Akamai) downloads file without the headers. The sequence
is following:
1. Ansible uploads file to CF.
2. Akamai downloads the file and caches it in CDN.
3. Ansible sets headers.

As a result Akamai serves file without headers.

This is backwards incompatible change, because headers keys are not
prefixed with `x-object-meta-`. Which allows user to set headers like
`Access-Control-Allow-Origin`.
This commit is contained in:
Vladimir Mihailenco 2015-05-01 13:31:44 +03:00
parent 15dcabe012
commit 366e6ab360

View file

@ -200,18 +200,30 @@ def _get_container(module, cf, container):
module.fail_json(msg=e.message) module.fail_json(msg=e.message)
def _upload_folder(cf, folder, container, ttl=None, headers=None):
""" Uploads a folder to Cloud Files.
"""
total_bytes = 0
for root, dirs, files in os.walk(folder):
for fname in files:
full_path = os.path.join(root, fname)
obj_name = os.path.relpath(full_path, folder)
obj_size = os.path.getsize(full_path)
cf.upload_file(container, full_path,
obj_name=obj_name, return_none=True, ttl=ttl, headers=headers)
total_bytes += obj_size
return total_bytes
def upload(module, cf, container, src, dest, meta, expires): def upload(module, cf, container, src, dest, meta, expires):
""" Uploads a single object or a folder to Cloud Files Optionally sets an """ Uploads a single object or a folder to Cloud Files Optionally sets an
metadata, TTL value (expires), or Content-Disposition and Content-Encoding metadata, TTL value (expires), or Content-Disposition and Content-Encoding
headers. headers.
""" """
c = _get_container(module, cf, container)
num_objs_before = len(c.get_object_names())
if not src: if not src:
module.fail_json(msg='src must be specified when uploading') module.fail_json(msg='src must be specified when uploading')
c = _get_container(module, cf, container)
src = os.path.abspath(os.path.expanduser(src)) src = os.path.abspath(os.path.expanduser(src))
is_dir = os.path.isdir(src) is_dir = os.path.isdir(src)
@ -222,68 +234,29 @@ def upload(module, cf, container, src, dest, meta, expires):
'directories are uploaded') 'directories are uploaded')
cont_obj = None cont_obj = None
total_bytes = 0
if dest and not is_dir: if dest and not is_dir:
try: try:
cont_obj = c.upload_file(src, obj_name=dest, ttl=expires) cont_obj = c.upload_file(src, obj_name=dest, ttl=expires, headers=meta)
except Exception, e: except Exception, e:
module.fail_json(msg=e.message) module.fail_json(msg=e.message)
elif is_dir: elif is_dir:
try: try:
id, total_bytes = cf.upload_folder(src, container=c.name, ttl=expires) total_bytes = _upload_folder(cf, src, c, ttl=expires, headers=meta)
except Exception, e: except Exception, e:
module.fail_json(msg=e.message) module.fail_json(msg=e.message)
while True:
bytes = cf.get_uploaded(id)
if bytes == total_bytes:
break
time.sleep(1)
else: else:
try: try:
cont_obj = c.upload_file(src, ttl=expires) cont_obj = c.upload_file(src, ttl=expires, headers=meta)
except Exception, e: except Exception, e:
module.fail_json(msg=e.message) module.fail_json(msg=e.message)
num_objs_after = len(c.get_object_names())
if not meta:
meta = dict()
meta_result = dict()
if meta:
if cont_obj:
meta_result = cont_obj.set_metadata(meta)
else:
def _set_meta(objs, meta):
""" Sets metadata on a list of objects specified by name """
for obj in objs:
try:
result = c.get_object(obj).set_metadata(meta)
except Exception, e:
module.fail_json(msg=e.message)
else:
meta_result[obj] = result
return meta_result
def _walker(objs, path, filenames):
""" Callback func for os.path.walk """
prefix = ''
if path != src:
prefix = path.split(src)[-1].lstrip('/')
filenames = [os.path.join(prefix, name) for name in filenames
if not os.path.isdir(os.path.join(path, name))]
objs += filenames
_objs = []
os.path.walk(src, _walker, _objs)
meta_result = _set_meta(_objs, meta)
EXIT_DICT['success'] = True EXIT_DICT['success'] = True
EXIT_DICT['container'] = c.name EXIT_DICT['container'] = c.name
EXIT_DICT['msg'] = "Uploaded %s to container: %s" % (src, c.name) EXIT_DICT['msg'] = "Uploaded %s to container: %s" % (src, c.name)
if cont_obj or locals().get('bytes'): if cont_obj or total_bytes > 0:
EXIT_DICT['changed'] = True EXIT_DICT['changed'] = True
if meta_result: if meta:
EXIT_DICT['meta'] = dict(updated=True) EXIT_DICT['meta'] = dict(updated=True)
if cont_obj: if cont_obj: