summaryrefslogtreecommitdiff
path: root/cloudinit/config
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/config')
-rw-r--r--cloudinit/config/cc_apt_update_upgrade.py3
-rw-r--r--cloudinit/config/cc_emit_upstart.py48
-rw-r--r--cloudinit/config/cc_final_message.py17
-rw-r--r--cloudinit/config/cc_resizefs.py4
-rw-r--r--cloudinit/config/cc_rightscale_userdata.py2
-rw-r--r--cloudinit/config/cc_update_etc_hosts.py6
-rw-r--r--cloudinit/config/cc_write_files.py102
7 files changed, 165 insertions, 17 deletions
diff --git a/cloudinit/config/cc_apt_update_upgrade.py b/cloudinit/config/cc_apt_update_upgrade.py
index 5c5e510c..1bffa47d 100644
--- a/cloudinit/config/cc_apt_update_upgrade.py
+++ b/cloudinit/config/cc_apt_update_upgrade.py
@@ -255,7 +255,8 @@ def find_apt_mirror(cloud, cfg):
if mydom:
doms.append(".%s" % mydom)
- if not mirror:
+ if (not mirror and
+ util.get_cfg_option_bool(cfg, "apt_mirror_search_dns", False)):
doms.extend((".localdomain", "",))
mirror_list = []
diff --git a/cloudinit/config/cc_emit_upstart.py b/cloudinit/config/cc_emit_upstart.py
new file mode 100644
index 00000000..68b86ff6
--- /dev/null
+++ b/cloudinit/config/cc_emit_upstart.py
@@ -0,0 +1,48 @@
+# vi: ts=4 expandtab
+#
+# Copyright (C) 2009-2011 Canonical Ltd.
+# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
+#
+# Author: Scott Moser <scott.moser@canonical.com>
+# Author: Juerg Haefliger <juerg.haefliger@hp.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 os
+
+from cloudinit import util
+from cloudinit.settings import PER_ALWAYS
+
+frequency = PER_ALWAYS
+
+distros = ['ubuntu', 'debian']
+
+
+def handle(name, _cfg, cloud, log, args):
+ event_names = args
+ if not event_names:
+ # Default to the 'cloud-config'
+ # event for backwards compat.
+ event_names = ['cloud-config']
+ if not os.path.isfile("/sbin/initctl"):
+ log.debug(("Skipping module named %s,"
+ " no /sbin/initctl located"), name)
+ return
+ cfgpath = cloud.paths.get_ipath_cur("cloud_config")
+ for n in event_names:
+ cmd = ['initctl', 'emit', str(n), 'CLOUD_CFG=%s' % cfgpath]
+ try:
+ util.subp(cmd)
+ except Exception as e:
+ # TODO, use log exception from utils??
+ log.warn("Emission of upstart event %s failed due to: %s", n, e)
diff --git a/cloudinit/config/cc_final_message.py b/cloudinit/config/cc_final_message.py
index b1caca47..aff03c4e 100644
--- a/cloudinit/config/cc_final_message.py
+++ b/cloudinit/config/cc_final_message.py
@@ -26,23 +26,20 @@ from cloudinit.settings import PER_ALWAYS
frequency = PER_ALWAYS
-FINAL_MESSAGE_DEF = ("Cloud-init v. {{version}} finished at {{timestamp}}."
- " Up {{uptime}} seconds.")
+# Cheetah formated default message
+FINAL_MESSAGE_DEF = ("Cloud-init v. ${version} finished at ${timestamp}."
+ " Up ${uptime} seconds.")
def handle(_name, cfg, cloud, log, args):
- msg_in = None
+ msg_in = ''
if len(args) != 0:
- msg_in = args[0]
+ msg_in = str(args[0])
else:
- msg_in = util.get_cfg_option_str(cfg, "final_message")
-
- if not msg_in:
- template_fn = cloud.get_template_filename('final_message')
- if template_fn:
- msg_in = util.load_file(template_fn)
+ msg_in = util.get_cfg_option_str(cfg, "final_message", "")
+ msg_in = msg_in.strip()
if not msg_in:
msg_in = FINAL_MESSAGE_DEF
diff --git a/cloudinit/config/cc_resizefs.py b/cloudinit/config/cc_resizefs.py
index 69cd8872..256a194f 100644
--- a/cloudinit/config/cc_resizefs.py
+++ b/cloudinit/config/cc_resizefs.py
@@ -134,7 +134,7 @@ def do_resize(resize_cmd, log):
except util.ProcessExecutionError:
util.logexc(log, "Failed to resize filesystem (cmd=%s)", resize_cmd)
raise
- tot_time = int(time.time() - start)
- log.debug("Resizing took %s seconds", tot_time)
+ tot_time = time.time() - start
+ log.debug("Resizing took %.3f seconds", tot_time)
# TODO: Should we add a fsck check after this to make
# sure we didn't corrupt anything?
diff --git a/cloudinit/config/cc_rightscale_userdata.py b/cloudinit/config/cc_rightscale_userdata.py
index 7a134569..45d41b3f 100644
--- a/cloudinit/config/cc_rightscale_userdata.py
+++ b/cloudinit/config/cc_rightscale_userdata.py
@@ -53,7 +53,7 @@ def handle(name, _cfg, cloud, log, _args):
try:
ud = cloud.get_userdata_raw()
except:
- log.warn("Failed to get raw userdata in module %s", name)
+ log.debug("Failed to get raw userdata in module %s", name)
return
try:
diff --git a/cloudinit/config/cc_update_etc_hosts.py b/cloudinit/config/cc_update_etc_hosts.py
index c148b12e..38108da7 100644
--- a/cloudinit/config/cc_update_etc_hosts.py
+++ b/cloudinit/config/cc_update_etc_hosts.py
@@ -36,11 +36,11 @@ def handle(name, cfg, cloud, log, _args):
return
# Render from a template file
- distro_n = cloud.distro.name
- tpl_fn_name = cloud.get_template_filename("hosts.%s" % (distro_n))
+ tpl_fn_name = cloud.get_template_filename("hosts.%s" %
+ (cloud.distro.name))
if not tpl_fn_name:
raise RuntimeError(("No hosts template could be"
- " found for distro %s") % (distro_n))
+ " found for distro %s") % (cloud.distro.name))
out_fn = cloud.paths.join(False, '/etc/hosts')
templater.render_to_file(tpl_fn_name, out_fn,
diff --git a/cloudinit/config/cc_write_files.py b/cloudinit/config/cc_write_files.py
new file mode 100644
index 00000000..1bfa4c25
--- /dev/null
+++ b/cloudinit/config/cc_write_files.py
@@ -0,0 +1,102 @@
+# 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_OWNER = "root:root"
+DEFAULT_PERMS = 0644
+UNKNOWN_ENC = 'text/plain'
+
+
+def handle(name, cfg, _cloud, log, _args):
+ files = cfg.get('write_files')
+ if not files:
+ log.debug(("Skipping module named %s,"
+ " no/empty 'write_files' key in configuration"), name)
+ return
+ write_files(name, files, log)
+
+
+def canonicalize_extraction(encoding_type, log):
+ if not encoding_type:
+ encoding_type = ''
+ encoding_type = encoding_type.lower().strip()
+ if encoding_type in ['gz', 'gzip']:
+ return ['application/x-gzip']
+ if encoding_type in ['gz+base64', 'gzip+base64', 'gz+b64', 'gzip+b64']:
+ return ['application/base64', 'application/x-gzip']
+ # 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 encoding_type in ['b64', 'base64']:
+ return ['application/base64']
+ if encoding_type:
+ log.warn("Unknown encoding type %s, assuming %s",
+ encoding_type, UNKNOWN_ENC)
+ return [UNKNOWN_ENC]
+
+
+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)
+ extractions = canonicalize_extraction(f_info.get('encoding'), 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 decode_perms(perm, default, log):
+ try:
+ 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 extract_contents(contents, extraction_types):
+ result = str(contents)
+ for t in extraction_types:
+ if t == 'application/x-gzip':
+ result = util.decomp_gzip(result, quiet=False)
+ elif t == 'application/base64':
+ result = base64.b64decode(result)
+ elif t == UNKNOWN_ENC:
+ pass
+ return result