diff options
Diffstat (limited to 'cloudinit')
-rw-r--r-- | cloudinit/config/cc_write_files.py | 69 | ||||
-rw-r--r-- | cloudinit/stages.py | 13 | ||||
-rw-r--r-- | cloudinit/user_data.py | 2 | ||||
-rw-r--r-- | cloudinit/util.py | 29 |
4 files changed, 97 insertions, 16 deletions
diff --git a/cloudinit/config/cc_write_files.py b/cloudinit/config/cc_write_files.py new file mode 100644 index 00000000..683eac27 --- /dev/null +++ b/cloudinit/config/cc_write_files.py @@ -0,0 +1,69 @@ +# vi: ts=4 expandtab +# +# Copyright (C) 2012 Yahoo! Inc. +# +# Author: Joshua Harlow <harlowja@yahoo-inc.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import base64 +import os + +from cloudinit import util +from cloudinit.settings import PER_INSTANCE + +frequency = PER_INSTANCE + +DEFAULT_PERMS = 0644 + + +def handle(name, cfg, _cloud, log, _args): + files = cfg.get('files') + if not files: + log.debug(("Skipping module named %s," + " no/empty 'files' key in configuration"), name) + return + write_files(name, files, log) + + +def write_files(name, files, log): + if not files: + return + + for (i, f_info) in enumerate(files): + path = f_info.get('path') + if not path: + log.warn("No path provided to write for entry %s in module %s", + i + 1, name) + continue + path = os.path.abspath(path) + contents = decode_string(f_info.get('content', ''), + f_info.get('compression')) + (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) + util.chownbyname(path, u, g) + + +def safe_int(text, default): + try: + return int(text) + except (TypeError, ValueError): + 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 diff --git a/cloudinit/stages.py b/cloudinit/stages.py index 3beeb36e..2f6a566c 100644 --- a/cloudinit/stages.py +++ b/cloudinit/stages.py @@ -133,18 +133,7 @@ class Init(object): if log_file: util.ensure_file(log_file) if perms: - perms_parted = perms.split(':', 1) - u = perms_parted[0] - if len(perms_parted) == 2: - g = perms_parted[1] - else: - g = '' - u = u.strip() - g = g.strip() - if u == "-1" or u.lower() == "none": - u = None - if g == "-1" or g.lower() == "none": - g = None + u, g = util.extract_usergroup(perms) try: util.chownbyname(log_file, u, g) except OSError: diff --git a/cloudinit/user_data.py b/cloudinit/user_data.py index 0842594d..f5d01818 100644 --- a/cloudinit/user_data.py +++ b/cloudinit/user_data.py @@ -227,7 +227,7 @@ def convert_string(raw_data, headers=None): raw_data = '' if not headers: headers = {} - data = util.decomp_str(raw_data) + data = util.decomp_gzip(raw_data) if "mime-version:" in data[0:4096].lower(): msg = email.message_from_string(data) for (key, val) in headers.iteritems(): diff --git a/cloudinit/util.py b/cloudinit/util.py index e7a2ebcd..aaad2fb0 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -159,6 +159,10 @@ class MountFailedError(Exception): pass +class DecompressionError(Exception): + pass + + def ExtendedTemporaryFile(**kwargs): fh = tempfile.NamedTemporaryFile(**kwargs) # Replace its unlink with a quiet version @@ -256,13 +260,32 @@ def clean_filename(fn): return fn -def decomp_str(data): +def decomp_gzip(data, quiet=True): try: buf = StringIO(str(data)) with contextlib.closing(gzip.GzipFile(None, "rb", 1, buf)) as gh: return gh.read() - except: - return data + except Exception as e: + if quiet: + return data + else: + raise DecompressionError(str(e)) + + +def extract_usergroup(ug_pair): + if not ug_pair: + return (None, None) + ug_parted = ug_pair.split(':', 1) + u = ug_parted[0].strip() + if len(ug_parted) == 2: + g = ug_parted[1].strip() + else: + g = None + if not u or u == "-1" or u.lower() == "none": + u = None + if not g or g == "-1" or g.lower() == "none": + g = None + return (u, g) def find_modules(root_dir): |