diff options
author | Joshua Harlow <harlowja@yahoo-inc.com> | 2012-07-11 11:20:24 -0700 |
---|---|---|
committer | Joshua Harlow <harlowja@yahoo-inc.com> | 2012-07-11 11:20:24 -0700 |
commit | eb939e7765f490529aade46e38ee0f85d8a911dd (patch) | |
tree | fff7fc071416d2e19c919bbe3136cfa3aff4ba15 /cloudinit | |
parent | 7b24230437a27779bafa0828e73ab595c5aeb202 (diff) | |
download | vyos-cloud-init-eb939e7765f490529aade46e38ee0f85d8a911dd.tar.gz vyos-cloud-init-eb939e7765f490529aade46e38ee0f85d8a911dd.zip |
Adjust the decoding of the files that are given so that a canonicalize
happens first, which will examine the incoming encoding, and decide the
neccasary decoding types needed to get the final resultant string and
then use these normalized decoding types to actually do the final decode.
Also change the name of the config key that is looked up to 'write_files'
since 'files' is pretty generic and could have clashes with other modules.
Add an example that shows how to use this in the different encoding formats
that are supported.
Diffstat (limited to 'cloudinit')
-rw-r--r-- | cloudinit/config/cc_write_files.py | 49 |
1 files changed, 41 insertions, 8 deletions
diff --git a/cloudinit/config/cc_write_files.py b/cloudinit/config/cc_write_files.py index 683eac27..9e8f63a5 100644 --- a/cloudinit/config/cc_write_files.py +++ b/cloudinit/config/cc_write_files.py @@ -25,10 +25,11 @@ from cloudinit.settings import PER_INSTANCE frequency = PER_INSTANCE DEFAULT_PERMS = 0644 +UNKNOWN_ENC = 'text/plain' def handle(name, cfg, _cloud, log, _args): - files = cfg.get('files') + files = cfg.get('write_files') if not files: log.debug(("Skipping module named %s," " no/empty 'files' key in configuration"), name) @@ -36,6 +37,29 @@ def handle(name, cfg, _cloud, log, _args): write_files(name, files, log) +def canonicalize_decoding(enc): + if not enc: + enc = '' + enc = enc.lower().strip() + # Translate to a mime-type (or set of) that will be understood + # when decoding (for now we only support a limited set of known mime-types) + # See: http://tiny.cc/m4kahw + # See: http://www.iana.org/assignments/media-types/index.html + if enc in ['gz', 'gzip']: + # Should we assume that this is 'always' base64? + # Someone might of got lucky and not had to encode it? + return ['application/x-gzip'] + if enc in ['gz+base64', 'gzip+base64', 'gz+b64', 'gzip+b64']: + return ['application/base64', 'application/x-gzip'] + if enc in ['base64', 'b64']: + return ['application/base64'] + if enc in ['base32', 'b32']: + return ['application/base32'] + if enc in ['base16', 'b16']: + return ['application/base16'] + return [UNKNOWN_ENC] + + def write_files(name, files, log): if not files: return @@ -47,8 +71,8 @@ def write_files(name, files, log): i + 1, name) continue path = os.path.abspath(path) - contents = decode_string(f_info.get('content', ''), - f_info.get('compression')) + decodings = canonicalize_decoding(f_info.get('encoding')) + contents = decode_contents(f_info.get('content', ''), decodings) (u, g) = util.extract_usergroup(f_info.get('owner')) perms = safe_int(f_info.get('permissions'), DEFAULT_PERMS) util.write_file(path, contents, mode=perms) @@ -62,8 +86,17 @@ def safe_int(text, default): return default -def decode_string(contents, content_type): - if util.is_true(content_type, addons=['gzip', 'gz']): - contents_dec = base64.b64decode(contents) - contents = util.decomp_gzip(contents_dec, quiet=False) - return contents +def decode_contents(contents, decodings): + result = str(contents) + for enc in decodings: + if enc == 'application/x-gzip': + result = util.decomp_gzip(result, quiet=False) + elif enc == 'application/base64': + result = base64.b64decode(result) + elif enc == 'application/base32': + result = base64.b32decode(result) + elif enc == 'application/base16': + result = base64.b16decode(result) + elif enc == UNKNOWN_ENC: + pass + return result |