summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cloudinit/config/cc_write_files.py64
-rw-r--r--doc/examples/cloud-config-write-files.txt27
2 files changed, 48 insertions, 43 deletions
diff --git a/cloudinit/config/cc_write_files.py b/cloudinit/config/cc_write_files.py
index ed2abe9e..061b9810 100644
--- a/cloudinit/config/cc_write_files.py
+++ b/cloudinit/config/cc_write_files.py
@@ -24,6 +24,7 @@ from cloudinit.settings import PER_INSTANCE
frequency = PER_INSTANCE
+DEFAULT_OWNER = "root:root"
DEFAULT_PERMS = 0644
UNKNOWN_ENC = 'text/plain'
@@ -37,26 +38,23 @@ 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?
+def canonicalize_extraction(compression_type, log):
+ if not compression_type:
+ compression_type = ''
+ compression_type = compression_type.lower().strip()
+ if compression_type in ['gz', 'gzip']:
return ['application/x-gzip']
- if enc in ['gz+base64', 'gzip+base64', 'gz+b64', 'gzip+b64']:
+ if compression_type in ['gz+base64', 'gzip+base64', 'gz+b64', 'gzip+b64']:
return ['application/base64', 'application/x-gzip']
- if enc in ['base64', 'b64']:
+ # Yaml already encodes binary data as base64 if it is given to the
+ # yaml file as binary, so those will be automatically decoded for you.
+ # But the above b64 is just for people that are more 'comfortable'
+ # specifing it manually (which might be a possiblity)
+ if compression_type in ['b64', 'base64']:
return ['application/base64']
- if enc in ['base32', 'b32']:
- return ['application/base32']
- if enc in ['base16', 'b16']:
- return ['application/base16']
+ if compression_type:
+ log.warn("Unknown compression type %s, assuming %s",
+ compression_type, UNKNOWN_ENC)
return [UNKNOWN_ENC]
@@ -71,32 +69,34 @@ def write_files(name, files, log):
i + 1, name)
continue
path = os.path.abspath(path)
- 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)
+ extractions = canonicalize_extraction(f_info.get('compression'), log)
+ contents = extract_contents(f_info.get('content', ''), extractions)
+ (u, g) = util.extract_usergroup(f_info.get('owner', DEFAULT_OWNER))
+ perms = decode_perms(f_info.get('permissions'), DEFAULT_PERMS, log)
util.write_file(path, contents, mode=perms)
util.chownbyname(path, u, g)
-def safe_int(text, default):
+def decode_perms(perm, default, log):
try:
- return int(text)
+ if isinstance(perm, (int, long, float)):
+ # Just 'downcast' it (if a float)
+ return int(perm)
+ else:
+ # Force to string and try octal conversion
+ return int(str(perm), 8)
except (TypeError, ValueError):
+ log.warn("Undecodable permissions %s, assuming %s", perm, default)
return default
-def decode_contents(contents, decodings):
+def extract_contents(contents, extraction_types):
result = str(contents)
- for enc in decodings:
- if enc == 'application/x-gzip':
+ for t in extraction_types:
+ if t == 'application/x-gzip':
result = util.decomp_gzip(result, quiet=False)
- elif enc == 'application/base64':
+ elif t == '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:
+ elif t == UNKNOWN_ENC:
pass
return result
diff --git a/doc/examples/cloud-config-write-files.txt b/doc/examples/cloud-config-write-files.txt
index fb0c1541..09ec12c2 100644
--- a/doc/examples/cloud-config-write-files.txt
+++ b/doc/examples/cloud-config-write-files.txt
@@ -9,9 +9,11 @@
# Note: Content strings here are truncated for example purposes.
#
write_files:
-- content: CiMgVGhpcyBmaWxlIGNvbnRyb2xzIHRoZSBzdGF0ZSBvZiBTRUxpbnV4IG9u.....
- encoding: b64
+- compression: b64
+ content: CiMgVGhpcyBmaWxlIGNvbnRyb2xzIHRoZSBzdGF0ZSBvZiBTRUxpbnV4...
+ owner: root:root
path: /etc/sysconfig/selinux
+ perms: '0644'
- content: '
# My new /etc/sysconfig/samba file
@@ -20,13 +22,16 @@ write_files:
'
path: /etc/sysconfig/samba
-- content: H4sIADXC/U8C/+1Yf2wbVx1/d7YT122TQEMpadS6kgOZqL30J+.....
- encoding: gz+b64
- path: /usr/bin/uptime
-- content: BIRSAU3FOR2GS3THOMQGM33SEB2GQZJAINJE6TRAMRQWK3LPNYXAU===
- encoding: b32
- path: /etc/sysconfig/crond
-- content: 0A232053657474696E677320666F7220746865204E4653206461656D6F6E2E0A
- encoding: b16
- path: /etc/sysconfig/nfs
+- content: !!binary |
+ f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAwARAAAAAAABAAAAAAAAAAJAVAAAAAAAAAAAAAEAAOAAI
+ AEAAHgAdAAYAAAAFAAAAQAAAAAAAAABAAEAAAAAAAEAAQAAAAAAAwAEAAAAAAADAAQAAAAAAAAgA
+ AAAAAAAAAwAAAAQAAAAAAgAAAAAAAAACQAAAAAAAAAJAAAAAAAAcAAAAAAAAABwAAAAAAAAAAQAA
+ ....
+ path: /bin/arch
+ perms: '0555'
+- compression: gzip
+ content: !!binary |
+ H4sIAIDb/U8C/1NW1E/KzNMvzuBKTc7IV8hIzcnJVyjPL8pJ4QIA6N+MVxsAAAA=
+ path: /usr/bin/hello
+ perms: '0755'