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:
parent
15dcabe012
commit
366e6ab360
1 changed files with 22 additions and 49 deletions
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue