From 2bdfea4a4396b136b618aa6946da9a9233f118b1 Mon Sep 17 00:00:00 2001 From: Vladimir Mihailenco Date: Fri, 1 May 2015 13:31:44 +0300 Subject: [PATCH] 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`. --- .../cloud/rackspace/rax_files_objects.py | 71 ++++++------------- 1 file changed, 22 insertions(+), 49 deletions(-) diff --git a/lib/ansible/modules/cloud/rackspace/rax_files_objects.py b/lib/ansible/modules/cloud/rackspace/rax_files_objects.py index 6da7b1882f0..bdeee6ad424 100644 --- a/lib/ansible/modules/cloud/rackspace/rax_files_objects.py +++ b/lib/ansible/modules/cloud/rackspace/rax_files_objects.py @@ -200,18 +200,30 @@ def _get_container(module, cf, container): 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): """ Uploads a single object or a folder to Cloud Files Optionally sets an metadata, TTL value (expires), or Content-Disposition and Content-Encoding headers. """ - c = _get_container(module, cf, container) - - num_objs_before = len(c.get_object_names()) - if not src: module.fail_json(msg='src must be specified when uploading') + c = _get_container(module, cf, container) src = os.path.abspath(os.path.expanduser(src)) is_dir = os.path.isdir(src) @@ -222,68 +234,29 @@ def upload(module, cf, container, src, dest, meta, expires): 'directories are uploaded') cont_obj = None + total_bytes = 0 if dest and not is_dir: 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: module.fail_json(msg=e.message) elif is_dir: 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: module.fail_json(msg=e.message) - - while True: - bytes = cf.get_uploaded(id) - if bytes == total_bytes: - break - time.sleep(1) else: try: - cont_obj = c.upload_file(src, ttl=expires) + cont_obj = c.upload_file(src, ttl=expires, headers=meta) except Exception, e: 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['container'] = 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 - if meta_result: + if meta: EXIT_DICT['meta'] = dict(updated=True) if cont_obj: