From 787377dbc08f689e4de2a112b5446f89b46d769e Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Wed, 20 Jun 2012 16:37:10 -0700 Subject: The 'cfg' module has been removed and moved to 'helpers' to avoid confusion. These modules used the 'cfg' modules so adjusted them. --- cloudinit/transforms/__init__.py | 57 ------- cloudinit/transforms/apt_pipelining.py | 57 ------- cloudinit/transforms/apt_update_upgrade.py | 243 --------------------------- cloudinit/transforms/bootcmd.py | 56 ------ cloudinit/transforms/byobu.py | 71 -------- cloudinit/transforms/ca_certs.py | 99 ----------- cloudinit/transforms/chef.py | 128 -------------- cloudinit/transforms/disable_ec2_metadata.py | 36 ---- cloudinit/transforms/final_message.py | 71 -------- cloudinit/transforms/foo.py | 52 ------ cloudinit/transforms/grub_dpkg.py | 67 -------- cloudinit/transforms/keys_to_console.py | 52 ------ cloudinit/transforms/landscape.py | 97 ----------- cloudinit/transforms/locale.py | 58 ------- cloudinit/transforms/mcollective.py | 97 ----------- cloudinit/transforms/mounts.py | 200 ---------------------- cloudinit/transforms/phone_home.py | 111 ------------ cloudinit/transforms/puppet.py | 111 ------------ cloudinit/transforms/resizefs.py | 140 --------------- cloudinit/transforms/rightscale_userdata.py | 102 ----------- cloudinit/transforms/rsyslog.py | 102 ----------- cloudinit/transforms/runcmd.py | 38 ----- cloudinit/transforms/salt_minion.py | 60 ------- cloudinit/transforms/scripts_per_boot.py | 41 ----- cloudinit/transforms/scripts_per_instance.py | 41 ----- cloudinit/transforms/scripts_per_once.py | 41 ----- cloudinit/transforms/scripts_user.py | 42 ----- cloudinit/transforms/set_hostname.py | 35 ---- cloudinit/transforms/set_passwords.py | 151 ----------------- cloudinit/transforms/ssh.py | 131 --------------- cloudinit/transforms/ssh_import_id.py | 53 ------ cloudinit/transforms/timezone.py | 39 ----- cloudinit/transforms/update_etc_hosts.py | 60 ------- cloudinit/transforms/update_hostname.py | 41 ----- 34 files changed, 2780 deletions(-) delete mode 100644 cloudinit/transforms/__init__.py delete mode 100644 cloudinit/transforms/apt_pipelining.py delete mode 100644 cloudinit/transforms/apt_update_upgrade.py delete mode 100644 cloudinit/transforms/bootcmd.py delete mode 100644 cloudinit/transforms/byobu.py delete mode 100644 cloudinit/transforms/ca_certs.py delete mode 100644 cloudinit/transforms/chef.py delete mode 100644 cloudinit/transforms/disable_ec2_metadata.py delete mode 100644 cloudinit/transforms/final_message.py delete mode 100644 cloudinit/transforms/foo.py delete mode 100644 cloudinit/transforms/grub_dpkg.py delete mode 100644 cloudinit/transforms/keys_to_console.py delete mode 100644 cloudinit/transforms/landscape.py delete mode 100644 cloudinit/transforms/locale.py delete mode 100644 cloudinit/transforms/mcollective.py delete mode 100644 cloudinit/transforms/mounts.py delete mode 100644 cloudinit/transforms/phone_home.py delete mode 100644 cloudinit/transforms/puppet.py delete mode 100644 cloudinit/transforms/resizefs.py delete mode 100644 cloudinit/transforms/rightscale_userdata.py delete mode 100644 cloudinit/transforms/rsyslog.py delete mode 100644 cloudinit/transforms/runcmd.py delete mode 100644 cloudinit/transforms/salt_minion.py delete mode 100644 cloudinit/transforms/scripts_per_boot.py delete mode 100644 cloudinit/transforms/scripts_per_instance.py delete mode 100644 cloudinit/transforms/scripts_per_once.py delete mode 100644 cloudinit/transforms/scripts_user.py delete mode 100644 cloudinit/transforms/set_hostname.py delete mode 100644 cloudinit/transforms/set_passwords.py delete mode 100644 cloudinit/transforms/ssh.py delete mode 100644 cloudinit/transforms/ssh_import_id.py delete mode 100644 cloudinit/transforms/timezone.py delete mode 100644 cloudinit/transforms/update_etc_hosts.py delete mode 100644 cloudinit/transforms/update_hostname.py (limited to 'cloudinit/transforms') diff --git a/cloudinit/transforms/__init__.py b/cloudinit/transforms/__init__.py deleted file mode 100644 index 5cd08575..00000000 --- a/cloudinit/transforms/__init__.py +++ /dev/null @@ -1,57 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2008-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Chuck Short -# Author: Juerg Haefliger -# -# 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 . -# - -from cloudinit.settings import (PER_INSTANCE, FREQUENCIES) - -from cloudinit import log as logging - -LOG = logging.getLogger(__name__) - -# TODO remove this from being a prefix?? -TRANSFORM_PREFIX = '' # "cc_" - - -def form_transform_name(name, mod=__name__): - canon_name = name.replace("-", "_") - if canon_name.lower().endswith(".py"): - canon_name = canon_name[0:(len(canon_name) - 3)] - canon_name = canon_name.strip() - if not canon_name: - return None - if not canon_name.startswith(TRANSFORM_PREFIX): - canon_name = '%s%s' % (TRANSFORM_PREFIX, canon_name) - return ".".join([str(mod), str(canon_name)]) - - -def fixup_transform(mod, def_freq=PER_INSTANCE): - if not hasattr(mod, 'frequency'): - setattr(mod, 'frequency', def_freq) - else: - freq = mod.frequency - if freq and freq not in FREQUENCIES: - LOG.warn("Transform %s has an unknown frequency %s", mod, freq) - if not hasattr(mod, 'handle'): - def empty_handle(_name, _cfg, _cloud, _log, _args): - pass - setattr(mod, 'handle', empty_handle) - if not hasattr(mod, 'distros'): - setattr(mod, 'distros', None) - return mod diff --git a/cloudinit/transforms/apt_pipelining.py b/cloudinit/transforms/apt_pipelining.py deleted file mode 100644 index f460becb..00000000 --- a/cloudinit/transforms/apt_pipelining.py +++ /dev/null @@ -1,57 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# -# Author: Ben Howard -# -# 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 . - -from cloudinit import util -from cloudinit.settings import PER_INSTANCE - -frequency = PER_INSTANCE - -distros = ['ubuntu', 'debian'] - -DEFAULT_FILE = "/etc/apt/apt.conf.d/90cloud-init-pipelining" - -# Acquire::http::Pipeline-Depth can be a value -# from 0 to 5 indicating how many outstanding requests APT should send. -# A value of zero MUST be specified if the remote host does not properly linger -# on TCP connections - otherwise data corruption will occur. - - -def handle(_name, cfg, cloud, log, _args): - - apt_pipe_value = util.get_cfg_option_str(cfg, "apt_pipelining", False) - apt_pipe_value_s = str(apt_pipe_value).lower().strip() - - if apt_pipe_value_s == "false": - write_apt_snippet(cloud, "0", log, DEFAULT_FILE) - elif apt_pipe_value_s in ("none", "unchanged", "os"): - return - elif apt_pipe_value_s in [str(b) for b in xrange(0, 6)]: - write_apt_snippet(cloud, apt_pipe_value_s, log, DEFAULT_FILE) - else: - log.warn("Invalid option for apt_pipeling: %s", apt_pipe_value) - - -def write_apt_snippet(cloud, setting, log, f_name): - """ Writes f_name with apt pipeline depth 'setting' """ - - file_contents = ("//Written by cloud-init per 'apt_pipelining'\n" - 'Acquire::http::Pipeline-Depth "%s";\n') % (setting) - - util.write_file(cloud.paths.join(False, f_name), file_contents) - - log.debug("Wrote %s with apt pipeline depth setting %s", f_name, setting) diff --git a/cloudinit/transforms/apt_update_upgrade.py b/cloudinit/transforms/apt_update_upgrade.py deleted file mode 100644 index f5b4b58f..00000000 --- a/cloudinit/transforms/apt_update_upgrade.py +++ /dev/null @@ -1,243 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import glob -import os - -from cloudinit import templater -from cloudinit import util - -distros = ['ubuntu', 'debian'] - -PROXY_TPL = "Acquire::HTTP::Proxy \"%s\";\n" - - -def handle(_name, cfg, cloud, log, _args): - update = util.get_cfg_option_bool(cfg, 'apt_update', False) - upgrade = util.get_cfg_option_bool(cfg, 'apt_upgrade', False) - - release = get_release() - - mirror = find_apt_mirror(cloud, cfg) - - log.debug("Selected mirror at: %s" % mirror) - - if not util.get_cfg_option_bool(cfg, - 'apt_preserve_sources_list', False): - generate_sources_list(release, mirror, cloud, log) - old_mir = util.get_cfg_option_str(cfg, 'apt_old_mirror', - "archive.ubuntu.com/ubuntu") - rename_apt_lists(old_mir, mirror) - - # Set up any apt proxy - proxy = cfg.get("apt_proxy", None) - proxy_filename = "/etc/apt/apt.conf.d/95cloud-init-proxy" - if proxy: - try: - # See man 'apt.conf' - contents = PROXY_TPL % (proxy) - util.write_file(cloud.paths.join(False, proxy_filename), - contents) - except Exception as e: - util.logexc(log, "Failed to write proxy to %s", proxy_filename) - elif os.path.isfile(proxy_filename): - util.del_file(proxy_filename) - - # Process 'apt_sources' - if 'apt_sources' in cfg: - errors = add_sources(cloud, cfg['apt_sources'], - {'MIRROR': mirror, 'RELEASE': release}) - for e in errors: - log.warn("Source Error: %s", ':'.join(e)) - - dconf_sel = util.get_cfg_option_str(cfg, 'debconf_selections', False) - if dconf_sel: - log.debug("setting debconf selections per cloud config") - try: - util.subp(('debconf-set-selections', '-'), dconf_sel) - except: - util.logexc(log, "Failed to run debconf-set-selections") - - pkglist = util.get_cfg_option_list(cfg, 'packages', []) - - errors = [] - if update or len(pkglist) or upgrade: - try: - cloud.distro.update_package_sources() - except Exception as e: - util.logexc(log, "Package update failed") - errors.append(e) - - if upgrade: - try: - cloud.distro.package_command("upgrade") - except Exception as e: - util.logexc(log, "Package upgrade failed") - errors.append(e) - - if len(pkglist): - try: - cloud.distro.install_packages(pkglist) - except Exception as e: - util.logexc(log, "Failed to install packages: %s ", pkglist) - errors.append(e) - - if len(errors): - log.warn("%s failed with exceptions, re-raising the last one", - len(errors)) - raise errors[-1] - - -def mirror2lists_fileprefix(mirror): - string = mirror - # take of http:// or ftp:// - if string.endswith("/"): - string = string[0:-1] - pos = string.find("://") - if pos >= 0: - string = string[pos + 3:] - string = string.replace("/", "_") - return string - - -def rename_apt_lists(omirror, new_mirror, lists_d="/var/lib/apt/lists"): - oprefix = "%s/%s" % (lists_d, mirror2lists_fileprefix(omirror)) - nprefix = "%s/%s" % (lists_d, mirror2lists_fileprefix(new_mirror)) - if oprefix == nprefix: - return - olen = len(oprefix) - for filename in glob.glob("%s_*" % oprefix): - # TODO use the cloud.paths.join... - util.rename(filename, "%s%s" % (nprefix, filename[olen:])) - - -def get_release(): - (stdout, _stderr) = util.subp(['lsb_release', '-cs']) - return stdout.strip() - - -def generate_sources_list(codename, mirror, cloud, log): - template_fn = cloud.get_template_filename('sources.list') - if template_fn: - params = {'mirror': mirror, 'codename': codename} - out_fn = cloud.paths.join(False, '/etc/apt/sources.list') - templater.render_to_file(template_fn, out_fn, params) - else: - log.warn("No template found, not rendering /etc/apt/sources.list") - - -def add_sources(cloud, srclist, template_params=None): - """ - add entries in /etc/apt/sources.list.d for each abbreviated - sources.list entry in 'srclist'. When rendering template, also - include the values in dictionary searchList - """ - if template_params is None: - template_params = {} - - errorlist = [] - for ent in srclist: - if 'source' not in ent: - errorlist.append(["", "missing source"]) - continue - - source = ent['source'] - if source.startswith("ppa:"): - try: - util.subp(["add-apt-repository", source]) - except: - errorlist.append([source, "add-apt-repository failed"]) - continue - - source = templater.render_string(source, template_params) - - if 'filename' not in ent: - ent['filename'] = 'cloud_config_sources.list' - - if not ent['filename'].startswith("/"): - ent['filename'] = os.path.join("/etc/apt/sources.list.d/", - ent['filename']) - - if ('keyid' in ent and 'key' not in ent): - ks = "keyserver.ubuntu.com" - if 'keyserver' in ent: - ks = ent['keyserver'] - try: - ent['key'] = util.getkeybyid(ent['keyid'], ks) - except: - errorlist.append([source, "failed to get key from %s" % ks]) - continue - - if 'key' in ent: - try: - util.subp(('apt-key', 'add', '-'), ent['key']) - except: - errorlist.append([source, "failed add key"]) - - try: - contents = "%s\n" % (source) - util.write_file(cloud.paths.join(False, ent['filename']), - contents, omode="ab") - except: - errorlist.append([source, - "failed write to file %s" % ent['filename']]) - - return errorlist - - -def find_apt_mirror(cloud, cfg): - """ find an apt_mirror given the cloud and cfg provided """ - - mirror = None - - cfg_mirror = cfg.get("apt_mirror", None) - if cfg_mirror: - mirror = cfg["apt_mirror"] - elif "apt_mirror_search" in cfg: - mirror = util.search_for_mirror(cfg['apt_mirror_search']) - else: - mirror = cloud.get_local_mirror() - - mydom = "" - - doms = [] - - if not mirror: - # if we have a fqdn, then search its domain portion first - (_hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud) - mydom = ".".join(fqdn.split(".")[1:]) - if mydom: - doms.append(".%s" % mydom) - - if not mirror: - doms.extend((".localdomain", "",)) - - mirror_list = [] - distro = cloud.distro.name - mirrorfmt = "http://%s-mirror%s/%s" % (distro, "%s", distro) - for post in doms: - mirror_list.append(mirrorfmt % (post)) - - mirror = util.search_for_mirror(mirror_list) - - if not mirror: - mirror = cloud.distro.get_package_mirror() - - return mirror diff --git a/cloudinit/transforms/bootcmd.py b/cloudinit/transforms/bootcmd.py deleted file mode 100644 index 635e3a1f..00000000 --- a/cloudinit/transforms/bootcmd.py +++ /dev/null @@ -1,56 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os -import tempfile - -from cloudinit import util -from cloudinit.settings import PER_ALWAYS - -frequency = PER_ALWAYS - - -def handle(name, cfg, cloud, log, _args): - - if "bootcmd" not in cfg: - log.debug(("Skipping transform named %s," - " no 'bootcmd' key in configuration"), name) - return - - with tempfile.NamedTemporaryFile(suffix=".sh") as tmpf: - try: - content = util.shellify(cfg["bootcmd"]) - tmpf.write(content) - tmpf.flush() - except: - util.logexc(log, "Failed to shellify bootcmd") - raise - - try: - env = os.environ.copy() - iid = cloud.get_instance_id() - if iid: - env['INSTANCE_ID'] = str(iid) - cmd = ['/bin/sh', tmpf.name] - util.subp(cmd, env=env, capture=False) - except: - util.logexc(log, - ("Failed to run bootcmd transform %s"), name) - raise diff --git a/cloudinit/transforms/byobu.py b/cloudinit/transforms/byobu.py deleted file mode 100644 index 741aa934..00000000 --- a/cloudinit/transforms/byobu.py +++ /dev/null @@ -1,71 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -from cloudinit import util - -distros = ['ubuntu', 'debian'] - - -def handle(name, cfg, _cloud, log, args): - if len(args) != 0: - value = args[0] - else: - value = util.get_cfg_option_str(cfg, "byobu_by_default", "") - - if not value: - log.debug("Skipping transform named %s, no 'byobu' values found", name) - return - - if value == "user" or value == "system": - value = "enable-%s" % value - - valid = ("enable-user", "enable-system", "enable", - "disable-user", "disable-system", "disable") - if not value in valid: - log.warn("Unknown value %s for byobu_by_default", value) - - mod_user = value.endswith("-user") - mod_sys = value.endswith("-system") - if value.startswith("enable"): - bl_inst = "install" - dc_val = "byobu byobu/launch-by-default boolean true" - mod_sys = True - else: - if value == "disable": - mod_user = True - mod_sys = True - bl_inst = "uninstall" - dc_val = "byobu byobu/launch-by-default boolean false" - - shcmd = "" - if mod_user: - user = util.get_cfg_option_str(cfg, "user", "ubuntu") - shcmd += " sudo -Hu \"%s\" byobu-launcher-%s" % (user, bl_inst) - shcmd += " || X=$(($X+1)); " - if mod_sys: - shcmd += "echo \"%s\" | debconf-set-selections" % dc_val - shcmd += " && dpkg-reconfigure byobu --frontend=noninteractive" - shcmd += " || X=$(($X+1)); " - - cmd = ["/bin/sh", "-c", "%s %s %s" % ("X=0;", shcmd, "exit $X")] - - log.debug("Setting byobu to %s", value) - - util.subp(cmd) diff --git a/cloudinit/transforms/ca_certs.py b/cloudinit/transforms/ca_certs.py deleted file mode 100644 index 56c41561..00000000 --- a/cloudinit/transforms/ca_certs.py +++ /dev/null @@ -1,99 +0,0 @@ -# vi: ts=4 expandtab -# -# Author: Mike Milner -# -# 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 . - -import os - -from cloudinit import util - -CA_CERT_PATH = "/usr/share/ca-certificates/" -CA_CERT_FILENAME = "cloud-init-ca-certs.crt" -CA_CERT_CONFIG = "/etc/ca-certificates.conf" -CA_CERT_SYSTEM_PATH = "/etc/ssl/certs/" - -distros = ['ubuntu'] - - -def update_ca_certs(): - """ - Updates the CA certificate cache on the current machine. - """ - util.subp(["update-ca-certificates"]) - - -def add_ca_certs(cloud, certs): - """ - Adds certificates to the system. To actually apply the new certificates - you must also call L{update_ca_certs}. - - @param certs: A list of certificate strings. - """ - if certs: - # First ensure they are strings... - cert_file_contents = "\n".join([str(c) for c in certs]) - cert_file_fullpath = os.path.join(CA_CERT_PATH, CA_CERT_FILENAME) - cert_file_fullpath = cloud.paths.join(False, cert_file_fullpath) - util.write_file(cert_file_fullpath, cert_file_contents, mode=0644) - # Append cert filename to CA_CERT_CONFIG file. - util.write_file(cloud.paths.join(False, CA_CERT_CONFIG), - "\n%s" % CA_CERT_FILENAME, omode="ab") - - -def remove_default_ca_certs(cloud): - """ - Removes all default trusted CA certificates from the system. To actually - apply the change you must also call L{update_ca_certs}. - """ - util.delete_dir_contents(cloud.paths.join(False, CA_CERT_PATH)) - util.delete_dir_contents(cloud.paths.join(False, CA_CERT_SYSTEM_PATH)) - util.write_file(cloud.paths.join(False, CA_CERT_CONFIG), "", mode=0644) - debconf_sel = "ca-certificates ca-certificates/trust_new_crts select no" - util.subp(('debconf-set-selections', '-'), debconf_sel) - - -def handle(name, cfg, cloud, log, _args): - """ - Call to handle ca-cert sections in cloud-config file. - - @param name: The module name "ca-cert" from cloud.cfg - @param cfg: A nested dict containing the entire cloud config contents. - @param cloud: The L{CloudInit} object in use. - @param log: Pre-initialized Python logger object to use for logging. - @param args: Any module arguments from cloud.cfg - """ - # If there isn't a ca-certs section in the configuration don't do anything - if "ca-certs" not in cfg: - log.debug(("Skipping transform named %s," - " no 'ca-certs' key in configuration"), name) - return - - ca_cert_cfg = cfg['ca-certs'] - - # If there is a remove-defaults option set to true, remove the system - # default trusted CA certs first. - if ca_cert_cfg.get("remove-defaults", False): - log.debug("Removing default certificates") - remove_default_ca_certs(cloud) - - # If we are given any new trusted CA certs to add, add them. - if "trusted" in ca_cert_cfg: - trusted_certs = util.get_cfg_option_list(ca_cert_cfg, "trusted") - if trusted_certs: - log.debug("Adding %d certificates" % len(trusted_certs)) - add_ca_certs(cloud, trusted_certs) - - # Update the system with the new cert configuration. - log.debug("Updating certificates") - update_ca_certs() diff --git a/cloudinit/transforms/chef.py b/cloudinit/transforms/chef.py deleted file mode 100644 index 4e8ef346..00000000 --- a/cloudinit/transforms/chef.py +++ /dev/null @@ -1,128 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Avishai Ish-Shalom -# Author: Mike Moulton -# Author: Juerg Haefliger -# -# 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 . - -import json -import os - -from cloudinit import templater -from cloudinit import util - -ruby_version_default = "1.8" - - -def handle(name, cfg, cloud, log, _args): - - # If there isn't a chef key in the configuration don't do anything - if 'chef' not in cfg: - log.debug(("Skipping transform named %s," - " no 'chef' key in configuration"), name) - return - chef_cfg = cfg['chef'] - - # Ensure the chef directories we use exist - c_dirs = [ - '/etc/chef', - '/var/log/chef', - '/var/lib/chef', - '/var/cache/chef', - '/var/backups/chef', - '/var/run/chef', - ] - for d in c_dirs: - util.ensure_dir(cloud.paths.join(False, d)) - - # Set the validation key based on the presence of either 'validation_key' - # or 'validation_cert'. In the case where both exist, 'validation_key' - # takes precedence - for key in ('validation_key', 'validation_cert'): - if key in chef_cfg and chef_cfg[key]: - v_fn = cloud.paths.join(False, '/etc/chef/validation.pem') - util.write_file(v_fn, chef_cfg[key]) - break - - # Create the chef config from template - template_fn = cloud.get_template_filename('chef_client.rb') - if template_fn: - iid = str(cloud.datasource.get_instance_id()) - params = { - 'server_url': chef_cfg['server_url'], - 'node_name': util.get_cfg_option_str(chef_cfg, 'node_name', iid), - 'environment': util.get_cfg_option_str(chef_cfg, 'environment', - '_default'), - 'validation_name': chef_cfg['validation_name'] - } - out_fn = cloud.paths.join(False, '/etc/chef/client.rb') - templater.render_to_file(template_fn, out_fn, params) - else: - log.warn("No template found, not rendering to /etc/chef/client.rb") - - # set the firstboot json - initial_json = {} - if 'run_list' in chef_cfg: - initial_json['run_list'] = chef_cfg['run_list'] - if 'initial_attributes' in chef_cfg: - initial_attributes = chef_cfg['initial_attributes'] - for k in list(initial_attributes.keys()): - initial_json[k] = initial_attributes[k] - firstboot_fn = cloud.paths.join(False, '/etc/chef/firstboot.json') - util.write_file(firstboot_fn, json.dumps(initial_json)) - - # If chef is not installed, we install chef based on 'install_type' - if not os.path.isfile('/usr/bin/chef-client'): - install_type = util.get_cfg_option_str(chef_cfg, 'install_type', - 'packages') - if install_type == "gems": - # this will install and run the chef-client from gems - chef_version = util.get_cfg_option_str(chef_cfg, 'version', None) - ruby_version = util.get_cfg_option_str(chef_cfg, 'ruby_version', - ruby_version_default) - install_chef_from_gems(cloud.distro, ruby_version, chef_version) - # and finally, run chef-client - log.debug('Running chef-client') - util.subp(['/usr/bin/chef-client', '-d', '-i', '1800', '-s', '20']) - elif install_type == 'packages': - # this will install and run the chef-client from packages - cloud.distro.install_packages(('chef',)) - else: - log.warn("Unknown chef install type %s", install_type) - - -def get_ruby_packages(version): - # return a list of packages needed to install ruby at version - pkgs = ['ruby%s' % version, 'ruby%s-dev' % version] - if version == "1.8": - pkgs.extend(('libopenssl-ruby1.8', 'rubygems1.8')) - return pkgs - - -def install_chef_from_gems(ruby_version, chef_version, distro): - distro.install_packages(get_ruby_packages(ruby_version)) - if not os.path.exists('/usr/bin/gem'): - util.sym_link('/usr/bin/gem%s' % ruby_version, '/usr/bin/gem') - if not os.path.exists('/usr/bin/ruby'): - util.sym_link('/usr/bin/ruby%s' % ruby_version, '/usr/bin/ruby') - if chef_version: - util.subp(['/usr/bin/gem', 'install', 'chef', - '-v %s' % chef_version, '--no-ri', - '--no-rdoc', '--bindir', '/usr/bin', '-q']) - else: - util.subp(['/usr/bin/gem', 'install', 'chef', - '--no-ri', '--no-rdoc', '--bindir', - '/usr/bin', '-q']) diff --git a/cloudinit/transforms/disable_ec2_metadata.py b/cloudinit/transforms/disable_ec2_metadata.py deleted file mode 100644 index c7d26029..00000000 --- a/cloudinit/transforms/disable_ec2_metadata.py +++ /dev/null @@ -1,36 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -from cloudinit import util - -from cloudinit.settings import PER_ALWAYS - -frequency = PER_ALWAYS - -reject_cmd = ['route', 'add', '-host', '169.254.169.254', 'reject'] - - -def handle(name, cfg, _cloud, log, _args): - disabled = util.get_cfg_option_bool(cfg, "disable_ec2_metadata", False) - if disabled: - util.subp(reject_cmd) - else: - log.debug(("Skipping transform named %s," - " disabling the ec2 route not enabled"), name) diff --git a/cloudinit/transforms/final_message.py b/cloudinit/transforms/final_message.py deleted file mode 100644 index c257b6d0..00000000 --- a/cloudinit/transforms/final_message.py +++ /dev/null @@ -1,71 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import sys - -from cloudinit import templater -from cloudinit import util -from cloudinit import version - -from cloudinit.settings import PER_ALWAYS - -frequency = PER_ALWAYS - -final_message_def = ("Cloud-init v. {{version}} finished at {{timestamp}}." - " Up {{uptime}} seconds.") - - -def handle(_name, cfg, cloud, log, args): - - msg_in = None - if len(args) != 0: - msg_in = 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) - - if not msg_in: - msg_in = final_message_def - - uptime = util.uptime() - ts = util.time_rfc2822() - cver = version.version_string() - try: - subs = { - 'uptime': uptime, - 'timestamp': ts, - 'version': cver, - } - # Use stdout, stderr or the logger?? - content = templater.render_string(msg_in, subs) - sys.stderr.write("%s\n" % (content)) - except Exception: - util.logexc(log, "Failed to render final message template") - - boot_fin_fn = cloud.paths.boot_finished - try: - contents = "%s - %s - v. %s\n" % (uptime, ts, cver) - util.write_file(boot_fin_fn, contents) - except: - util.logexc(log, "Failed to write boot finished file %s", boot_fin_fn) diff --git a/cloudinit/transforms/foo.py b/cloudinit/transforms/foo.py deleted file mode 100644 index 99135704..00000000 --- a/cloudinit/transforms/foo.py +++ /dev/null @@ -1,52 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -from cloudinit.settings import PER_INSTANCE - -# Modules are expected to have the following attributes. -# 1. A required 'handle' method which takes the following params. -# a) The name will not be this files name, but instead -# the name specified in configuration (which is the name -# which will be used to find this module). -# b) A configuration object that is the result of the merging -# of cloud configs configuration with legacy configuration -# as well as any datasource provided configuration -# c) A cloud object that can be used to access various -# datasource and paths for the given distro and data provided -# by the various datasource instance types. -# d) A argument list that may or may not be empty to this module. -# Typically those are from module configuration where the module -# is defined with some extra configuration that will eventually -# be translated from yaml into arguments to this module. -# 2. A optional 'frequency' that defines how often this module should be ran. -# Typically one of PER_INSTANCE, PER_ALWAYS, PER_ONCE. If not -# provided PER_INSTANCE will be assumed. -# See settings.py for these constants. -# 3. A optional 'distros' array/set/tuple that defines the known distros -# this module will work with (if not all of them). This is used to write -# a warning out if a module is being ran on a untested distribution for -# informational purposes. If non existent all distros are assumed and -# no warning occurs. - -frequency = PER_INSTANCE - - -def handle(name, _cfg, _cloud, log, _args): - log.debug("Hi from transform %s", name) diff --git a/cloudinit/transforms/grub_dpkg.py b/cloudinit/transforms/grub_dpkg.py deleted file mode 100644 index 02f05ce3..00000000 --- a/cloudinit/transforms/grub_dpkg.py +++ /dev/null @@ -1,67 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os - -from cloudinit import util - -distros = ['ubuntu', 'debian'] - - -def handle(_name, cfg, _cloud, log, _args): - idevs = None - idevs_empty = None - - if "grub-dpkg" in cfg: - idevs = util.get_cfg_option_str(cfg["grub-dpkg"], - "grub-pc/install_devices", None) - idevs_empty = util.get_cfg_option_str(cfg["grub-dpkg"], - "grub-pc/install_devices_empty", None) - - if ((os.path.exists("/dev/sda1") and not os.path.exists("/dev/sda")) or - (os.path.exists("/dev/xvda1") and not os.path.exists("/dev/xvda"))): - if idevs == None: - idevs = "" - if idevs_empty == None: - idevs_empty = "true" - else: - if idevs_empty == None: - idevs_empty = "false" - if idevs == None: - idevs = "/dev/sda" - for dev in ("/dev/sda", "/dev/vda", "/dev/sda1", "/dev/vda1"): - if os.path.exists(dev): - idevs = dev - break - - # now idevs and idevs_empty are set to determined values - # or, those set by user - - dconf_sel = (("grub-pc grub-pc/install_devices string %s\n" - "grub-pc grub-pc/install_devices_empty boolean %s\n") % - (idevs, idevs_empty)) - - log.debug("Setting grub debconf-set-selections with '%s','%s'" % - (idevs, idevs_empty)) - - try: - util.subp(['debconf-set-selections'], dconf_sel) - except: - util.logexc(log, "Failed to run debconf-set-selections for grub-dpkg") diff --git a/cloudinit/transforms/keys_to_console.py b/cloudinit/transforms/keys_to_console.py deleted file mode 100644 index 40758198..00000000 --- a/cloudinit/transforms/keys_to_console.py +++ /dev/null @@ -1,52 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os - -from cloudinit.settings import PER_INSTANCE -from cloudinit import util - -frequency = PER_INSTANCE - -# This is a tool that cloud init provides -helper_tool = '/usr/lib/cloud-init/write-ssh-key-fingerprints' - - -def handle(name, cfg, cloud, log, _args): - if not os.path.exists(helper_tool): - log.warn(("Unable to activate transform %s," - " helper tool not found at %s"), name, helper_tool) - return - - fp_blacklist = util.get_cfg_option_list(cfg, - "ssh_fp_console_blacklist", []) - key_blacklist = util.get_cfg_option_list(cfg, - "ssh_key_console_blacklist", - ["ssh-dss"]) - - try: - cmd = [helper_tool] - cmd.append(','.join(fp_blacklist)) - cmd.append(','.join(key_blacklist)) - (stdout, _stderr) = util.subp(cmd) - util.write_file(cloud.paths.join(False, '/dev/console'), stdout) - except: - log.warn("Writing keys to /dev/console failed!") - raise diff --git a/cloudinit/transforms/landscape.py b/cloudinit/transforms/landscape.py deleted file mode 100644 index 29ce41b9..00000000 --- a/cloudinit/transforms/landscape.py +++ /dev/null @@ -1,97 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os - -from StringIO import StringIO - -try: - from configobj import ConfigObj -except ImportError: - ConfigObj = None - -from cloudinit import util - -from cloudinit.settings import PER_INSTANCE - -frequency = PER_INSTANCE - -LSC_CLIENT_CFG_FILE = "/etc/landscape/client.conf" - -distros = ['ubuntu'] - -# defaults taken from stock client.conf in landscape-client 11.07.1.1-0ubuntu2 -LSC_BUILTIN_CFG = { - 'client': { - 'log_level': "info", - 'url': "https://landscape.canonical.com/message-system", - 'ping_url': "http://landscape.canonical.com/ping", - 'data_path': "/var/lib/landscape/client", - } -} - - -def handle(name, cfg, cloud, log, _args): - """ - Basically turn a top level 'landscape' entry with a 'client' dict - and render it to ConfigObj format under '[client]' section in - /etc/landscape/client.conf - """ - if not ConfigObj: - log.warn(("'ConfigObj' support not available," - " running transform %s disabled"), name) - return - - ls_cloudcfg = cfg.get("landscape", {}) - - if not isinstance(ls_cloudcfg, dict): - raise Exception(("'landscape' key existed in config," - " but not a dictionary type," - " is a %s instead"), util.obj_name(ls_cloudcfg)) - - lsc_client_fn = cloud.paths.join(True, LSC_CLIENT_CFG_FILE) - merged = merge_together([LSC_BUILTIN_CFG, lsc_client_fn, ls_cloudcfg]) - - lsc_dir = cloud.paths.join(False, os.path.dirname(lsc_client_fn)) - if not os.path.isdir(lsc_dir): - util.ensure_dir(lsc_dir) - - contents = StringIO() - merged.write(contents) - contents.flush() - - util.write_file(lsc_client_fn, contents.getvalue()) - log.debug("Wrote landscape config file to %s", lsc_client_fn) - - -def merge_together(objs): - """ - merge together ConfigObj objects or things that ConfigObj() will take in - later entries override earlier - """ - cfg = ConfigObj({}) - for obj in objs: - if not obj: - continue - if isinstance(obj, ConfigObj): - cfg.merge(obj) - else: - cfg.merge(ConfigObj(obj)) - return cfg diff --git a/cloudinit/transforms/locale.py b/cloudinit/transforms/locale.py deleted file mode 100644 index 7f273123..00000000 --- a/cloudinit/transforms/locale.py +++ /dev/null @@ -1,58 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os - -from cloudinit import templater -from cloudinit import util - - -def apply_locale(locale, cfgfile, cloud, log): - # TODO this command might not work on RH... - if os.path.exists('/usr/sbin/locale-gen'): - util.subp(['locale-gen', locale], capture=False) - if os.path.exists('/usr/sbin/update-locale'): - util.subp(['update-locale', locale], capture=False) - if not cfgfile: - return - template_fn = cloud.get_template_filename('default-locale') - if not template_fn: - log.warn("No template filename found to write to %s", cfgfile) - else: - templater.render_to_file(template_fn, cfgfile, {'locale': locale}) - - -def handle(name, cfg, cloud, log, args): - if len(args) != 0: - locale = args[0] - else: - locale = util.get_cfg_option_str(cfg, "locale", cloud.get_locale()) - - locale_cfgfile = util.get_cfg_option_str(cfg, "locale_configfile", - "/etc/default/locale") - - if not locale: - log.debug(("Skipping transform named %s, " - "no 'locale' configuration found"), name) - return - - log.debug("Setting locale to %s", locale) - - apply_locale(locale, locale_cfgfile, cloud, log) diff --git a/cloudinit/transforms/mcollective.py b/cloudinit/transforms/mcollective.py deleted file mode 100644 index 9754d6b8..00000000 --- a/cloudinit/transforms/mcollective.py +++ /dev/null @@ -1,97 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Marc Cluet -# Based on code by Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -from StringIO import StringIO - -from cloudinit import cfg as config -from cloudinit import util - -PUBCERT_FILE = "/etc/mcollective/ssl/server-public.pem" -PRICERT_FILE = "/etc/mcollective/ssl/server-private.pem" - - -def handle(name, cfg, cloud, log, _args): - - # If there isn't a mcollective key in the configuration don't do anything - if 'mcollective' not in cfg: - log.debug(("Skipping transform named %s, " - "no 'mcollective' key in configuration"), name) - return - - mcollective_cfg = cfg['mcollective'] - - # Start by installing the mcollective package ... - cloud.distro.install_packages(("mcollective",)) - - # ... and then update the mcollective configuration - if 'conf' in mcollective_cfg: - # Create object for reading server.cfg values - mcollective_config = config.DefaultingConfigParser() - # Read server.cfg values from original file in order to be able to mix - # the rest up - server_cfg_fn = cloud.paths.join(True, '/etc/mcollective/server.cfg') - old_contents = util.load_file(server_cfg_fn) - # It doesn't contain any sections so just add one temporarily - # Use a hash id based off the contents, - # just incase of conflicts... (try to not have any...) - # This is so that an error won't occur when reading (and no - # sections exist in the file) - section_tpl = "[nullsection_%s]" - attempts = 0 - section_head = section_tpl % (attempts) - while old_contents.find(section_head) != -1: - attempts += 1 - section_head = section_tpl % (attempts) - sectioned_contents = "%s\n%s" % (section_head, old_contents) - mcollective_config.readfp(StringIO(sectioned_contents), - filename=server_cfg_fn) - for (cfg_name, cfg) in mcollective_cfg['conf'].iteritems(): - if cfg_name == 'public-cert': - pubcert_fn = cloud.paths.join(True, PUBCERT_FILE) - util.write_file(pubcert_fn, cfg, mode=0644) - mcollective_config.set(cfg_name, - 'plugin.ssl_server_public', pubcert_fn) - mcollective_config.set(cfg_name, 'securityprovider', 'ssl') - elif cfg_name == 'private-cert': - pricert_fn = cloud.paths.join(True, PRICERT_FILE) - util.write_file(pricert_fn, cfg, mode=0600) - mcollective_config.set(cfg_name, - 'plugin.ssl_server_private', pricert_fn) - mcollective_config.set(cfg_name, 'securityprovider', 'ssl') - else: - # Iterate throug the config items, we'll use ConfigParser.set - # to overwrite or create new items as needed - for (o, v) in cfg.iteritems(): - mcollective_config.set(cfg_name, o, v) - # We got all our config as wanted we'll rename - # the previous server.cfg and create our new one - old_fn = "%s.old" % (server_cfg_fn) - util.rename(server_cfg_fn, old_fn) - # Now we got the whole file, write to disk except the section - # we added so that config parser won't error out when trying to read. - # Note below, that we've just used ConfigParser because it generally - # works. Below, we remove the initial 'nullsection' header. - contents = mcollective_config.stringify() - contents = contents.replace("%s\n" % (section_head), "") - util.write_file(server_cfg_fn, contents, mode=0644) - - # Start mcollective - util.subp(['service', 'mcollective', 'start'], capture=False) diff --git a/cloudinit/transforms/mounts.py b/cloudinit/transforms/mounts.py deleted file mode 100644 index 700fbc44..00000000 --- a/cloudinit/transforms/mounts.py +++ /dev/null @@ -1,200 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -from string import whitespace # pylint: disable=W0402 - -import re - -from cloudinit import util - -# shortname matches 'sda', 'sda1', 'xvda', 'hda', 'sdb', xvdb, vda, vdd1 -shortname_filter = r"^[x]{0,1}[shv]d[a-z][0-9]*$" -shortname = re.compile(shortname_filter) -ws = re.compile("[%s]+" % (whitespace)) - - -def is_mdname(name): - # return true if this is a metadata service name - if name in ["ami", "root", "swap"]: - return True - # names 'ephemeral0' or 'ephemeral1' - # 'ebs[0-9]' appears when '--block-device-mapping sdf=snap-d4d90bbc' - for enumname in ("ephemeral", "ebs"): - if name.startswith(enumname) and name.find(":") == -1: - return True - return False - - -def handle(_name, cfg, cloud, log, _args): - # fs_spec, fs_file, fs_vfstype, fs_mntops, fs-freq, fs_passno - defvals = [None, None, "auto", "defaults,nobootwait", "0", "2"] - defvals = cfg.get("mount_default_fields", defvals) - - # these are our default set of mounts - defmnts = [["ephemeral0", "/mnt", "auto", defvals[3], "0", "2"], - ["swap", "none", "swap", "sw", "0", "0"]] - - cfgmnt = [] - if "mounts" in cfg: - cfgmnt = cfg["mounts"] - - - for i in range(len(cfgmnt)): - # skip something that wasn't a list - if not isinstance(cfgmnt[i], list): - log.warn("Mount option %s not a list, got a %s instead", - (i + 1), util.obj_name(cfgmnt[i])) - continue - - startname = str(cfgmnt[i][0]) - log.debug("Attempting to determine the real name of %s", startname) - - # workaround, allow user to specify 'ephemeral' - # rather than more ec2 correct 'ephemeral0' - if startname == "ephemeral": - cfgmnt[i][0] = "ephemeral0" - log.debug(("Adjusted mount option %s " - "name from ephemeral to ephemeral0"), (i + 1)) - - if is_mdname(startname): - newname = cloud.device_name_to_device(startname) - if not newname: - log.debug("Ignoring nonexistant named mount %s", startname) - cfgmnt[i][1] = None - else: - renamed = newname - if not newname.startswith("/"): - renamed = "/dev/%s" % newname - cfgmnt[i][0] = renamed - log.debug("Mapped metadata name %s to %s", startname, renamed) - else: - if shortname.match(startname): - renamed = "/dev/%s" % startname - log.debug("Mapped shortname name %s to %s", startname, renamed) - cfgmnt[i][0] = renamed - - # in case the user did not quote a field (likely fs-freq, fs_passno) - # but do not convert None to 'None' (LP: #898365) - for j in range(len(cfgmnt[i])): - if j is None: - continue - else: - cfgmnt[i][j] = str(cfgmnt[i][j]) - - for i in range(len(cfgmnt)): - # fill in values with defaults from defvals above - for j in range(len(defvals)): - if len(cfgmnt[i]) <= j: - cfgmnt[i].append(defvals[j]) - elif cfgmnt[i][j] is None: - cfgmnt[i][j] = defvals[j] - - # if the second entry in the list is 'None' this - # clears all previous entries of that same 'fs_spec' - # (fs_spec is the first field in /etc/fstab, ie, that device) - if cfgmnt[i][1] is None: - for j in range(i): - if cfgmnt[j][0] == cfgmnt[i][0]: - cfgmnt[j][1] = None - - # for each of the "default" mounts, add them only if no other - # entry has the same device name - for defmnt in defmnts: - startname = defmnt[0] - devname = cloud.device_name_to_device(startname) - if devname is None: - log.debug("Ignoring nonexistant named default mount %s", startname) - continue - if devname.startswith("/"): - defmnt[0] = devname - else: - defmnt[0] = "/dev/%s" % devname - - log.debug("Mapped default device %s to %s", startname, defmnt[0]) - - cfgmnt_has = False - for cfgm in cfgmnt: - if cfgm[0] == defmnt[0]: - cfgmnt_has = True - break - - if cfgmnt_has: - log.debug(("Not including %s, already" - " previously included"), startname) - continue - cfgmnt.append(defmnt) - - # now, each entry in the cfgmnt list has all fstab values - # if the second field is None (not the string, the value) we skip it - actlist = [] - for x in cfgmnt: - if x[1] is None: - log.debug("Skipping non-existent device named %s", x[0]) - else: - actlist.append(x) - - if len(actlist) == 0: - log.debug("No modifications to fstab needed.") - return - - comment = "comment=cloudconfig" - cc_lines = [] - needswap = False - dirs = [] - for line in actlist: - # write 'comment' in the fs_mntops, entry, claiming this - line[3] = "%s,%s" % (line[3], comment) - if line[2] == "swap": - needswap = True - if line[1].startswith("/"): - dirs.append(line[1]) - cc_lines.append('\t'.join(line)) - - fstab_lines = [] - fstab = util.load_file(cloud.paths.join(True, "/etc/fstab")) - for line in fstab.splitlines(): - try: - toks = ws.split(line) - if toks[3].find(comment) != -1: - continue - except: - pass - fstab_lines.append(line) - - fstab_lines.extend(cc_lines) - contents = "%s\n" % ('\n'.join(fstab_lines)) - util.write_file(cloud.paths.join(False, "/etc/fstab"), contents) - - if needswap: - try: - util.subp(("swapon", "-a")) - except: - util.logexc(log, "Activating swap via 'swapon -a' failed") - - for d in dirs: - try: - util.ensure_dir(cloud.paths.join(False, d)) - except: - util.logexc(log, "Failed to make '%s' config-mount", d) - - try: - util.subp(("mount", "-a")) - except: - util.logexc(log, "Activating mounts via 'mount -a' failed") diff --git a/cloudinit/transforms/phone_home.py b/cloudinit/transforms/phone_home.py deleted file mode 100644 index a8752527..00000000 --- a/cloudinit/transforms/phone_home.py +++ /dev/null @@ -1,111 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -from cloudinit import templater -from cloudinit import url_helper as uhelp -from cloudinit import util - -from cloudinit.settings import PER_INSTANCE - -frequency = PER_INSTANCE - -post_list_all = ['pub_key_dsa', 'pub_key_rsa', 'pub_key_ecdsa', - 'instance_id', 'hostname'] - - -# phone_home: -# url: http://my.foo.bar/$INSTANCE/ -# post: all -# tries: 10 -# -# phone_home: -# url: http://my.foo.bar/$INSTANCE_ID/ -# post: [ pub_key_dsa, pub_key_rsa, pub_key_ecdsa, instance_id -# -def handle(name, cfg, cloud, log, args): - if len(args) != 0: - ph_cfg = util.read_conf(args[0]) - else: - if not 'phone_home' in cfg: - return - ph_cfg = cfg['phone_home'] - - if 'url' not in ph_cfg: - log.warn(("Skipping transform named %s, " - "no 'url' found in 'phone_home' configuration"), name) - return - - url = ph_cfg['url'] - post_list = ph_cfg.get('post', 'all') - tries = ph_cfg.get('tries', 10) - try: - tries = int(tries) - except: - tries = 10 - util.logexc(log, ("Configuration entry 'tries'" - " is not an integer, using %s instead"), tries) - - if post_list == "all": - post_list = post_list_all - - all_keys = {} - all_keys['instance_id'] = cloud.get_instance_id() - all_keys['hostname'] = cloud.get_hostname() - - pubkeys = { - 'pub_key_dsa': '/etc/ssh/ssh_host_dsa_key.pub', - 'pub_key_rsa': '/etc/ssh/ssh_host_rsa_key.pub', - 'pub_key_ecdsa': '/etc/ssh/ssh_host_ecdsa_key.pub', - } - - for (n, path) in pubkeys.iteritems(): - try: - all_keys[n] = util.load_file(cloud.paths.join(True, path)) - except: - util.logexc(log, ("%s: failed to open, can not" - " phone home that data"), path) - - submit_keys = {} - for k in post_list: - if k in all_keys: - submit_keys[k] = all_keys[k] - else: - submit_keys[k] = None - log.warn(("Requested key %s from 'post'" - " configuration list not available"), k) - - # Get them read to be posted - real_submit_keys = {} - for (k, v) in submit_keys.iteritems(): - if v is None: - real_submit_keys[k] = 'N/A' - else: - real_submit_keys[k] = str(v) - - # Incase the url is parameterized - url_params = { - 'INSTANCE_ID': all_keys['instance_id'], - } - url = templater.render_string(url, url_params) - try: - uhelp.readurl(url, data=real_submit_keys, retries=tries, sec_between=3) - except: - util.logexc(log, ("Failed to post phone home data to" - " %s in %s tries"), url, tries) diff --git a/cloudinit/transforms/puppet.py b/cloudinit/transforms/puppet.py deleted file mode 100644 index d55118ea..00000000 --- a/cloudinit/transforms/puppet.py +++ /dev/null @@ -1,111 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -from StringIO import StringIO - -import os -import pwd -import socket - -from cloudinit import cfg as config -from cloudinit import util - - -def handle(name, cfg, cloud, log, _args): - # If there isn't a puppet key in the configuration don't do anything - if 'puppet' not in cfg: - log.debug(("Skipping transform named %s," - " no 'puppet' configuration found"), name) - return - - puppet_cfg = cfg['puppet'] - - # Start by installing the puppet package ... - cloud.distro.install_packages(["puppet"]) - - # ... and then update the puppet configuration - if 'conf' in puppet_cfg: - # Add all sections from the conf object to puppet.conf - puppet_conf_fn = cloud.paths.join(False, '/etc/puppet/puppet.conf') - contents = util.load_file(puppet_conf_fn) - # Create object for reading puppet.conf values - puppet_config = config.DefaultingConfigParser() - # Read puppet.conf values from original file in order to be able to - # mix the rest up. First clean them up (TODO is this really needed??) - cleaned_lines = [i.lstrip() for i in contents.splitlines()] - cleaned_contents = '\n'.join(cleaned_lines) - puppet_config.readfp(StringIO(cleaned_contents), - filename=puppet_conf_fn) - for (cfg_name, cfg) in puppet_cfg['conf'].iteritems(): - # Cert configuration is a special case - # Dump the puppet master ca certificate in the correct place - if cfg_name == 'ca_cert': - # Puppet ssl sub-directory isn't created yet - # Create it with the proper permissions and ownership - pp_ssl_dir = cloud.paths.join(False, '/var/lib/puppet/ssl') - util.ensure_dir(pp_ssl_dir, 0771) - util.chownbyid(pp_ssl_dir, - pwd.getpwnam('puppet').pw_uid, 0) - pp_ssl_certs = cloud.paths.join(False, - '/var/lib/puppet/ssl/certs/') - util.ensure_dir(pp_ssl_certs) - util.chownbyid(pp_ssl_certs, - pwd.getpwnam('puppet').pw_uid, 0) - pp_ssl_ca_certs = cloud.paths.join(False, - ('/var/lib/puppet/' - 'ssl/certs/ca.pem')) - util.write_file(pp_ssl_ca_certs, cfg) - util.chownbyid(pp_ssl_ca_certs, - pwd.getpwnam('puppet').pw_uid, 0) - else: - # Iterate throug the config items, we'll use ConfigParser.set - # to overwrite or create new items as needed - for (o, v) in cfg.iteritems(): - if o == 'certname': - # Expand %f as the fqdn - # TODO should this use the cloud fqdn?? - v = v.replace("%f", socket.getfqdn()) - # Expand %i as the instance id - v = v.replace("%i", cloud.get_instance_id()) - # certname needs to be downcased - v = v.lower() - puppet_config.set(cfg_name, o, v) - # We got all our config as wanted we'll rename - # the previous puppet.conf and create our new one - puppet_conf_old_fn = "%s.old" % (puppet_conf_fn) - util.rename(puppet_conf_fn, puppet_conf_old_fn) - util.write_file(puppet_conf_fn, puppet_config.stringify()) - - # Set puppet to automatically start - if os.path.exists('/etc/default/puppet'): - util.subp(['sed', '-i', - '-e', 's/^START=.*/START=yes/', - '/etc/default/puppet'], capture=False) - elif os.path.exists('/bin/systemctl'): - util.subp(['/bin/systemctl', 'enable', 'puppet.service'], - capture=False) - elif os.path.exists('/sbin/chkconfig'): - util.subp(['/sbin/chkconfig', 'puppet', 'on'], capture=False) - else: - log.warn(("Sorry we do not know how to enable" - " puppet services on this system")) - - # Start puppetd - util.subp(['service', 'puppet', 'start'], capture=False) diff --git a/cloudinit/transforms/resizefs.py b/cloudinit/transforms/resizefs.py deleted file mode 100644 index 1690094a..00000000 --- a/cloudinit/transforms/resizefs.py +++ /dev/null @@ -1,140 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os -import stat -import time - -from cloudinit import util -from cloudinit.settings import PER_ALWAYS - -frequency = PER_ALWAYS - -resize_fs_prefixes_cmds = [ - ('ext', 'resize2fs'), - ('xfs', 'xfs_growfs'), -] - - -def nodeify_path(devpth, where, log): - try: - st_dev = os.stat(where).st_dev - dev = os.makedev(os.major(st_dev), os.minor(st_dev)) - os.mknod(devpth, 0400 | stat.S_IFBLK, dev) - return st_dev - except: - if util.is_container(): - log.debug("Inside container, ignoring mknod failure in resizefs") - return - log.warn("Failed to make device node to resize %s at %s", - where, devpth) - raise - - -def get_fs_type(st_dev, path, log): - try: - dev_entries = util.find_devs_with(tag='TYPE', oformat='value', - no_cache=True, path=path) - if not dev_entries: - return None - return dev_entries[0].strip() - except util.ProcessExecutionError: - util.logexc(log, ("Failed to get filesystem type" - " of maj=%s, min=%s for path %s"), - os.major(st_dev), os.minor(st_dev), path) - raise - - -def handle(name, cfg, cloud, log, args): - if len(args) != 0: - resize_root = args[0] - else: - resize_root = util.get_cfg_option_str(cfg, "resize_rootfs", True) - - if not util.translate_bool(resize_root): - log.debug("Skipping transform named %s, resizing disabled", name) - return - - # TODO is the directory ok to be used?? - resize_root_d = util.get_cfg_option_str(cfg, "resize_rootfs_tmp", "/run") - resize_root_d = cloud.paths.join(False, resize_root_d) - util.ensure_dir(resize_root_d) - - # TODO: allow what is to be resized to be configurable?? - resize_what = cloud.paths.join(False, "/") - with util.SilentTemporaryFile(prefix="cloudinit.resizefs.", - dir=resize_root_d, delete=True) as tfh: - devpth = tfh.name - - # Delete the file so that mknod will work - # but don't change the file handle to know that its - # removed so that when a later call that recreates - # occurs this temporary file will still benefit from - # auto deletion - tfh.unlink_now() - - st_dev = nodeify_path(devpth, resize_what, log) - fs_type = get_fs_type(st_dev, devpth, log) - if not fs_type: - log.warn("Could not determine filesystem type of %s", resize_what) - return - - resizer = None - fstype_lc = fs_type.lower() - for (pfix, root_cmd) in resize_fs_prefixes_cmds: - if fstype_lc.startswith(pfix): - resizer = root_cmd - break - - if not resizer: - log.warn("Not resizing unknown filesystem type %s for %s", - fs_type, resize_what) - return - - log.debug("Resizing %s (%s) using %s", resize_what, fs_type, resizer) - resize_cmd = [resizer, devpth] - - if resize_root == "noblock": - # Fork to a child that will run - # the resize command - util.fork_cb(do_resize, resize_cmd, log) - # Don't delete the file now in the parent - tfh.delete = False - else: - do_resize(resize_cmd, log) - - action = 'Resized' - if resize_root == "noblock": - action = 'Resizing (via forking)' - log.debug("%s root filesystem (type=%s, maj=%i, min=%i, val=%s)", - action, fs_type, os.major(st_dev), os.minor(st_dev), resize_root) - - -def do_resize(resize_cmd, log): - start = time.time() - try: - util.subp(resize_cmd) - 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) - # TODO: Should we add a fsck check after this to make - # sure we didn't corrupt anything? diff --git a/cloudinit/transforms/rightscale_userdata.py b/cloudinit/transforms/rightscale_userdata.py deleted file mode 100644 index 8385e281..00000000 --- a/cloudinit/transforms/rightscale_userdata.py +++ /dev/null @@ -1,102 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -## -## The purpose of this script is to allow cloud-init to consume -## rightscale style userdata. rightscale user data is key-value pairs -## in a url-query-string like format. -## -## for cloud-init support, there will be a key named -## 'CLOUD_INIT_REMOTE_HOOK'. -## -## This cloud-config module will -## - read the blob of data from raw user data, and parse it as key/value -## - for each key that is found, download the content to -## the local instance/scripts directory and set them executable. -## - the files in that directory will be run by the user-scripts module -## Therefore, this must run before that. -## -## - -import os - -from cloudinit import url_helper as uhelp -from cloudinit import util -from cloudinit.settings import PER_INSTANCE - -from urlparse import parse_qs - -frequency = PER_INSTANCE - -MY_NAME = "cc_rightscale_userdata" -MY_HOOKNAME = 'CLOUD_INIT_REMOTE_HOOK' - - -def handle(name, _cfg, cloud, log, _args): - try: - ud = cloud.get_userdata_raw() - except: - log.warn("Failed to get raw userdata in transform %s", name) - return - - try: - mdict = parse_qs(ud) - if not mdict or not MY_HOOKNAME in mdict: - log.debug(("Skipping transform %s, " - "did not find %s in parsed" - " raw userdata"), name, MY_HOOKNAME) - return - except: - util.logexc(log, ("Failed to parse query string %s" - " into a dictionary"), ud) - raise - - wrote_fns = [] - captured_excps = [] - - # These will eventually be then ran by the cc_scripts_user - # TODO: maybe this should just be a new user data handler?? - # Instead of a late transform that acts like a user data handler? - scripts_d = cloud.get_ipath_cur('scripts') - urls = mdict[MY_HOOKNAME] - for (i, url) in enumerate(urls): - fname = os.path.join(scripts_d, "rightscale-%02i" % (i)) - try: - resp = uhelp.readurl(url) - # Ensure its a valid http response (and something gotten) - if resp.ok() and resp.contents: - util.write_file(fname, str(resp), mode=0700) - wrote_fns.append(fname) - except Exception as e: - captured_excps.append(e) - util.logexc(log, "%s failed to read %s and write %s", - MY_NAME, url, fname) - - if wrote_fns: - log.debug("Wrote out rightscale userdata to %s files", len(wrote_fns)) - - if len(wrote_fns) != len(urls): - skipped = len(urls) - len(wrote_fns) - log.debug("%s urls were skipped or failed", skipped) - - if captured_excps: - log.warn("%s failed with exceptions, re-raising the last one", - len(captured_excps)) - raise captured_excps[-1] diff --git a/cloudinit/transforms/rsyslog.py b/cloudinit/transforms/rsyslog.py deleted file mode 100644 index f2c1de1e..00000000 --- a/cloudinit/transforms/rsyslog.py +++ /dev/null @@ -1,102 +0,0 @@ -# vi: ts=4 expandtab syntax=python -# -# Copyright (C) 2009-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os - -from cloudinit import util - -DEF_FILENAME = "20-cloud-config.conf" -DEF_DIR = "/etc/rsyslog.d" - - -def handle(name, cfg, cloud, log, _args): - # rsyslog: - # - "*.* @@192.158.1.1" - # - content: "*.* @@192.0.2.1:10514" - # - filename: 01-examplecom.conf - # content: | - # *.* @@syslogd.example.com - - # process 'rsyslog' - if not 'rsyslog' in cfg: - log.debug(("Skipping transform named %s," - " no 'rsyslog' key in configuration"), name) - return - - def_dir = cfg.get('rsyslog_dir', DEF_DIR) - def_fname = cfg.get('rsyslog_filename', DEF_FILENAME) - - files = [] - for i, ent in enumerate(cfg['rsyslog']): - if isinstance(ent, dict): - if not "content" in ent: - log.warn("No 'content' entry in config entry %s", i + 1) - continue - content = ent['content'] - filename = ent.get("filename", def_fname) - else: - content = ent - filename = def_fname - - filename = filename.strip() - if not filename: - log.warn("Entry %s has an empty filename", i + 1) - continue - - if not filename.startswith("/"): - filename = os.path.join(def_dir, filename) - - # Truncate filename first time you see it - omode = "ab" - if filename not in files: - omode = "wb" - files.append(filename) - - try: - contents = "%s\n" % (content) - util.write_file(cloud.paths.join(False, filename), - contents, omode=omode) - except Exception: - util.logexc(log, "Failed to write to %s", filename) - - # Attempt to restart syslogd - restarted = False - try: - # If this config module is running at cloud-init time - # (before rsyslog is running) we don't actually have to - # restart syslog. - # - # Upstart actually does what we want here, in that it doesn't - # start a service that wasn't running already on 'restart' - # it will also return failure on the attempt, so 'restarted' - # won't get set. - log.debug("Restarting rsyslog") - util.subp(['service', 'rsyslog', 'restart']) - restarted = True - except Exception: - util.logexc(log, "Failed restarting rsyslog") - - if restarted: - # This only needs to run if we *actually* restarted - # syslog above. - cloud.cycle_logging() - # This should now use rsyslog if - # the logging was setup to use it... - log.debug("%s configured %s files", name, files) diff --git a/cloudinit/transforms/runcmd.py b/cloudinit/transforms/runcmd.py deleted file mode 100644 index f121484b..00000000 --- a/cloudinit/transforms/runcmd.py +++ /dev/null @@ -1,38 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os - -from cloudinit import util - - -def handle(name, cfg, cloud, log, _args): - if "runcmd" not in cfg: - log.debug(("Skipping transform named %s," - " no 'runcmd' key in configuration"), name) - return - - out_fn = os.path.join(cloud.get_ipath('scripts'), "runcmd") - cmd = cfg["runcmd"] - try: - content = util.shellify(cmd) - util.write_file(cloud.paths.join(False, out_fn), content, 0700) - except: - util.logexc(log, "Failed to shellify %s into file %s", cmd, out_fn) diff --git a/cloudinit/transforms/salt_minion.py b/cloudinit/transforms/salt_minion.py deleted file mode 100644 index 16f5286d..00000000 --- a/cloudinit/transforms/salt_minion.py +++ /dev/null @@ -1,60 +0,0 @@ -# vi: ts=4 expandtab -# -# Author: Jeff Bauer -# -# 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 . - -import os - -from cloudinit import util - -# Note: see http://saltstack.org/topics/installation/ - - -def handle(name, cfg, cloud, log, _args): - # If there isn't a salt key in the configuration don't do anything - if 'salt_minion' not in cfg: - log.debug(("Skipping transform named %s," - " no 'salt_minion' key in configuration"), name) - return - - salt_cfg = cfg['salt_minion'] - - # Start by installing the salt package ... - cloud.distro.install_packages(["salt"]) - - # Ensure we can configure files at the right dir - config_dir = salt_cfg.get("config_dir", '/etc/salt') - config_dir = cloud.paths.join(False, config_dir) - util.ensure_dir(config_dir) - - # ... and then update the salt configuration - if 'conf' in salt_cfg: - # Add all sections from the conf object to /etc/salt/minion - minion_config = os.path.join(config_dir, 'minion') - minion_data = util.yaml_dumps(salt_cfg.get('conf')) - util.write_file(minion_config, minion_data) - - # ... copy the key pair if specified - if 'public_key' in salt_cfg and 'private_key' in salt_cfg: - pki_dir = salt_cfg.get('pki_dir', '/etc/salt/pki') - pki_dir = cloud.paths.join(pki_dir) - with util.umask(077): - util.ensure_dir(pki_dir) - pub_name = os.path.join(pki_dir, 'minion.pub') - pem_name = os.path.join(pki_dir, 'minion.pem') - util.write_file(pub_name, salt_cfg['public_key']) - util.write_file(pem_name, salt_cfg['private_key']) - - # Start salt-minion - util.subp(['service', 'salt-minion', 'start'], capture=False) diff --git a/cloudinit/transforms/scripts_per_boot.py b/cloudinit/transforms/scripts_per_boot.py deleted file mode 100644 index 364e1d02..00000000 --- a/cloudinit/transforms/scripts_per_boot.py +++ /dev/null @@ -1,41 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os - -from cloudinit import util - -from cloudinit.settings import PER_ALWAYS - -frequency = PER_ALWAYS - -script_subdir = 'per-boot' - - -def handle(name, _cfg, cloud, log, _args): - # Comes from the following: - # https://forums.aws.amazon.com/thread.jspa?threadID=96918 - runparts_path = os.path.join(cloud.get_cpath(), 'scripts', script_subdir) - try: - util.runparts(runparts_path) - except: - log.warn("Failed to run transform %s (%s in %s)", - name, script_subdir, runparts_path) - raise diff --git a/cloudinit/transforms/scripts_per_instance.py b/cloudinit/transforms/scripts_per_instance.py deleted file mode 100644 index d75ab47d..00000000 --- a/cloudinit/transforms/scripts_per_instance.py +++ /dev/null @@ -1,41 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os - -from cloudinit import util - -from cloudinit.settings import PER_INSTANCE - -frequency = PER_INSTANCE - -script_subdir = 'per-instance' - - -def handle(name, _cfg, cloud, log, _args): - # Comes from the following: - # https://forums.aws.amazon.com/thread.jspa?threadID=96918 - runparts_path = os.path.join(cloud.get_cpath(), 'scripts', script_subdir) - try: - util.runparts(runparts_path) - except: - log.warn("Failed to run transform %s (%s in %s)", - name, script_subdir, runparts_path) - raise diff --git a/cloudinit/transforms/scripts_per_once.py b/cloudinit/transforms/scripts_per_once.py deleted file mode 100644 index 80f8c325..00000000 --- a/cloudinit/transforms/scripts_per_once.py +++ /dev/null @@ -1,41 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os - -from cloudinit import util - -from cloudinit.settings import PER_ONCE - -frequency = PER_ONCE - -script_subdir = 'per-once' - - -def handle(name, _cfg, cloud, log, _args): - # Comes from the following: - # https://forums.aws.amazon.com/thread.jspa?threadID=96918 - runparts_path = os.path.join(cloud.get_cpath(), 'scripts', script_subdir) - try: - util.runparts(runparts_path) - except: - log.warn("Failed to run transform %s (%s in %s)", - name, script_subdir, runparts_path) - raise diff --git a/cloudinit/transforms/scripts_user.py b/cloudinit/transforms/scripts_user.py deleted file mode 100644 index f4fe3a2a..00000000 --- a/cloudinit/transforms/scripts_user.py +++ /dev/null @@ -1,42 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os - -from cloudinit import util - -from cloudinit.settings import PER_INSTANCE - -frequency = PER_INSTANCE - -script_subdir = 'scripts' - - -def handle(name, _cfg, cloud, log, _args): - # This is written to by the user data handlers - # Ie, any custom shell scripts that come down - # go here... - runparts_path = os.path.join(cloud.get_ipath_cur(), script_subdir) - try: - util.runparts(runparts_path) - except: - log.warn("Failed to run transform %s (%s in %s)", - name, script_subdir, runparts_path) - raise diff --git a/cloudinit/transforms/set_hostname.py b/cloudinit/transforms/set_hostname.py deleted file mode 100644 index 3ac8a8fa..00000000 --- a/cloudinit/transforms/set_hostname.py +++ /dev/null @@ -1,35 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -from cloudinit import util - - -def handle(name, cfg, cloud, log, _args): - if util.get_cfg_option_bool(cfg, "preserve_hostname", False): - log.debug(("Configuration option 'preserve_hostname' is set," - " not setting the hostname in transform %s"), name) - return - - (hostname, _fqdn) = util.get_hostname_fqdn(cfg, cloud) - try: - log.debug("Setting hostname to %s", hostname) - cloud.distro.set_hostname(hostname) - except Exception: - util.logexc(log, "Failed to set hostname to %s", hostname) diff --git a/cloudinit/transforms/set_passwords.py b/cloudinit/transforms/set_passwords.py deleted file mode 100644 index e7049f22..00000000 --- a/cloudinit/transforms/set_passwords.py +++ /dev/null @@ -1,151 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import sys - -from cloudinit import util - -from string import letters, digits # pylint: disable=W0402 - -# We are removing certain 'painful' letters/numbers -pw_set = (letters.translate(None, 'loLOI') + - digits.translate(None, '01')) - - -def handle(_name, cfg, cloud, log, args): - if len(args) != 0: - # if run from command line, and give args, wipe the chpasswd['list'] - password = args[0] - if 'chpasswd' in cfg and 'list' in cfg['chpasswd']: - del cfg['chpasswd']['list'] - else: - password = util.get_cfg_option_str(cfg, "password", None) - - expire = True - pw_auth = "no" - change_pwauth = False - plist = None - - if 'chpasswd' in cfg: - chfg = cfg['chpasswd'] - plist = util.get_cfg_option_str(chfg, 'list', plist) - expire = util.get_cfg_option_bool(chfg, 'expire', expire) - - if not plist and password: - user = util.get_cfg_option_str(cfg, "user", "ubuntu") - plist = "%s:%s" % (user, password) - - errors = [] - if plist: - plist_in = [] - randlist = [] - users = [] - for line in plist.splitlines(): - u, p = line.split(':', 1) - if p == "R" or p == "RANDOM": - p = rand_user_password() - randlist.append("%s:%s" % (u, p)) - plist_in.append("%s:%s" % (u, p)) - users.append(u) - - ch_in = '\n'.join(plist_in) - try: - log.debug("Changing password for %s:", users) - util.subp(['chpasswd'], ch_in) - except Exception as e: - errors.append(e) - util.logexc(log, - "Failed to set passwords with chpasswd for %s", users) - - if len(randlist): - blurb = ("Set the following 'random' passwords\n", - '\n'.join(randlist)) - sys.stderr.write("%s\n%s\n" % blurb) - - if expire: - expired_users = [] - for u in users: - try: - util.subp(['passwd', '--expire', u]) - expired_users.append(u) - except Exception as e: - errors.append(e) - util.logexc(log, "Failed to set 'expire' for %s", u) - if expired_users: - log.debug("Expired passwords for: %s users", expired_users) - - change_pwauth = False - pw_auth = None - if 'ssh_pwauth' in cfg: - change_pwauth = True - if util.is_true_str(cfg['ssh_pwauth']): - pw_auth = 'yes' - if util.is_false_str(cfg['ssh_pwauth']): - pw_auth = 'no' - - if change_pwauth: - new_lines = [] - replaced_auth = False - replacement = "PasswordAuthentication %s" % (pw_auth) - - # See http://linux.die.net/man/5/sshd_config - old_lines = util.load_file('/etc/ssh/sshd_config').splitlines() - for i, line in enumerate(old_lines): - if not line.strip() or line.startswith("#"): - new_lines.append(line) - continue - splitup = line.split(None, 1) - if len(splitup) <= 1: - new_lines.append(line) - continue - (cmd, args) = splitup - # Keywords are case-insensitive and arguments are case-sensitive - cmd = cmd.lower().strip() - if cmd == 'passwordauthentication': - log.debug("Replacing auth line %s with %s", i + 1, replacement) - replaced_auth = True - new_lines.append(replacement) - else: - new_lines.append(line) - - if not replaced_auth: - log.debug("Adding new auth line %s", replacement) - replaced_auth = True - new_lines.append(replacement) - - util.write_file(cloud.paths.join(False, '/etc/ssh/sshd_config'), - "\n".join(new_lines)) - - try: - cmd = ['service'] - cmd.append(cloud.distro.get_option('ssh_svcname', 'ssh')) - cmd.append('restart') - util.subp(cmd) - log.debug("Restarted the ssh daemon") - except: - util.logexc(log, "Restarting of the ssh daemon failed") - - if len(errors): - log.debug("%s errors occured, re-raising the last one", len(errors)) - raise errors[-1] - - -def rand_user_password(pwlen=9): - return util.rand_str(pwlen, select_from=pw_set) diff --git a/cloudinit/transforms/ssh.py b/cloudinit/transforms/ssh.py deleted file mode 100644 index e5e99560..00000000 --- a/cloudinit/transforms/ssh.py +++ /dev/null @@ -1,131 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os -import glob - -from cloudinit import util -from cloudinit import ssh_util - -DISABLE_ROOT_OPTS = ( "no-port-forwarding,no-agent-forwarding," -"no-X11-forwarding,command=\"echo \'Please login as the user \\\"$USER\\\" " -"rather than the user \\\"root\\\".\';echo;sleep 10\"") - -key2file = { - "rsa_private": ("/etc/ssh/ssh_host_rsa_key", 0600), - "rsa_public": ("/etc/ssh/ssh_host_rsa_key.pub", 0644), - "dsa_private": ("/etc/ssh/ssh_host_dsa_key", 0600), - "dsa_public": ("/etc/ssh/ssh_host_dsa_key.pub", 0644), - "ecdsa_private": ("/etc/ssh/ssh_host_ecdsa_key", 0600), - "ecdsa_public": ("/etc/ssh/ssh_host_ecdsa_key.pub", 0644), -} - -priv2pub = { - 'rsa_private': 'rsa_public', - 'dsa_private': 'dsa_public', - 'ecdsa_private': 'ecdsa_public', -} - -key_gen_tpl = 'o=$(ssh-keygen -yf "%s") && echo "$o" root@localhost > "%s"' - -generate_keys = ['rsa', 'dsa', 'ecdsa'] - - -def handle(_name, cfg, cloud, log, _args): - - # remove the static keys from the pristine image - if cfg.get("ssh_deletekeys", True): - key_pth = cloud.paths.join(False, "/etc/ssh/", "ssh_host_*key*") - for f in glob.glob(key_pth): - try: - util.del_file(f) - except: - util.logexc(log, "Failed deleting key file %s", f) - - if "ssh_keys" in cfg: - # if there are keys in cloud-config, use them - for (key, val) in cfg["ssh_keys"].iteritems(): - if key in key2file: - tgt_fn = key2file[key][0] - tgt_perms = key2file[key][1] - util.write_file(cloud.paths.join(False, tgt_fn), - val, tgt_perms) - - for (priv, pub) in priv2pub.iteritems(): - if pub in cfg['ssh_keys'] or not priv in cfg['ssh_keys']: - continue - pair = (key2file[priv][0], key2file[pub][0]) - cmd = ['sh', '-xc', key_gen_tpl % pair] - try: - # TODO: Is this guard needed? - with util.SeLinuxGuard("/etc/ssh", recursive=True): - util.subp(cmd, capture=False) - log.debug("Generated a key for %s from %s", pair[0], pair[1]) - except: - util.logexc(log, ("Failed generated a key" - " for %s from %s"), pair[0], pair[1]) - else: - # if not, generate them - genkeys = util.get_cfg_option_list(cfg, - 'ssh_genkeytypes', - generate_keys) - for keytype in genkeys: - keyfile = '/etc/ssh/ssh_host_%s_key' % (keytype) - keyfile = cloud.paths.join(False, keyfile) - util.ensure_dir(os.path.dirname(keyfile)) - if not os.path.exists(keyfile): - cmd = ['ssh-keygen', '-t', keytype, '-N', '', '-f', keyfile] - try: - # TODO: Is this guard needed? - with util.SeLinuxGuard("/etc/ssh", recursive=True): - util.subp(cmd, capture=False) - except: - util.logexc(log, ("Failed generating key type" - " %s to file %s"), keytype, keyfile) - - try: - user = util.get_cfg_option_str(cfg, 'user') - disable_root = util.get_cfg_option_bool(cfg, "disable_root", True) - disable_root_opts = util.get_cfg_option_str(cfg, "disable_root_opts", - DISABLE_ROOT_OPTS) - - keys = cloud.get_public_ssh_keys() or [] - if "ssh_authorized_keys" in cfg: - cfgkeys = cfg["ssh_authorized_keys"] - keys.extend(cfgkeys) - - apply_credentials(keys, user, cloud.paths, - disable_root, disable_root_opts) - except: - util.logexc(log, "Applying ssh credentials failed!") - - -def apply_credentials(keys, user, paths, disable_root, disable_root_opts): - - keys = set(keys) - if user: - ssh_util.setup_user_keys(keys, user, '', paths) - - if disable_root and user: - key_prefix = disable_root_opts.replace('$USER', user) - else: - key_prefix = '' - - ssh_util.setup_user_keys(keys, 'root', key_prefix, paths) diff --git a/cloudinit/transforms/ssh_import_id.py b/cloudinit/transforms/ssh_import_id.py deleted file mode 100644 index d57e4665..00000000 --- a/cloudinit/transforms/ssh_import_id.py +++ /dev/null @@ -1,53 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -from cloudinit import util - -# The ssh-import-id only seems to exist on ubuntu (for now) -# https://launchpad.net/ssh-import-id -distros = ['ubuntu'] - - -def handle(name, cfg, _cloud, log, args): - if len(args) != 0: - user = args[0] - ids = [] - if len(args) > 1: - ids = args[1:] - else: - user = util.get_cfg_option_str(cfg, "user", "ubuntu") - ids = util.get_cfg_option_list(cfg, "ssh_import_id", []) - - if len(ids) == 0: - log.debug("Skipping transform named %s, no ids found to import", name) - return - - if not user: - log.debug("Skipping transform named %s, no user found to import", name) - return - - cmd = ["sudo", "-Hu", user, "ssh-import-id"] + ids - log.debug("Importing ssh ids for user %s.", user) - - try: - util.subp(cmd, capture=False) - except util.ProcessExecutionError as e: - util.logexc(log, "Failed to run command to import %s ssh ids", user) - raise e diff --git a/cloudinit/transforms/timezone.py b/cloudinit/transforms/timezone.py deleted file mode 100644 index 747c436c..00000000 --- a/cloudinit/transforms/timezone.py +++ /dev/null @@ -1,39 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2009-2010 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -from cloudinit import util - -from cloudinit.settings import PER_INSTANCE - -frequency = PER_INSTANCE - - -def handle(name, cfg, cloud, log, args): - if len(args) != 0: - timezone = args[0] - else: - timezone = util.get_cfg_option_str(cfg, "timezone", False) - - if not timezone: - log.debug("Skipping transform named %s, no 'timezone' specified", name) - return - - # Let the distro handle settings its timezone - cloud.distro.set_timezone(timezone) diff --git a/cloudinit/transforms/update_etc_hosts.py b/cloudinit/transforms/update_etc_hosts.py deleted file mode 100644 index 75615db1..00000000 --- a/cloudinit/transforms/update_etc_hosts.py +++ /dev/null @@ -1,60 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -from cloudinit import util -from cloudinit import templater - -from cloudinit.settings import PER_ALWAYS - -frequency = PER_ALWAYS - - -def handle(name, cfg, cloud, log, _args): - manage_hosts = util.get_cfg_option_str(cfg, "manage_etc_hosts", False) - if util.translate_bool(manage_hosts, addons=['template']): - (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud) - if not hostname: - log.warn(("Option 'manage_etc_hosts' was set," - " but no hostname was found")) - return - - # Render from a template file - distro_n = cloud.distro.name - tpl_fn_name = cloud.get_template_filename("hosts.%s" % (distro_n)) - if not tpl_fn_name: - raise Exception(("No hosts template could be" - " found for distro %s") % (distro_n)) - - out_fn = cloud.paths.join(False, '/etc/hosts') - templater.render_to_file(tpl_fn_name, out_fn, - {'hostname': hostname, 'fqdn': fqdn}) - - elif manage_hosts == "localhost": - (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud) - if not hostname: - log.warn(("Option 'manage_etc_hosts' was set," - " but no hostname was found")) - return - - log.debug("Managing localhost in /etc/hosts") - cloud.distro.update_etc_hosts(hostname, fqdn) - else: - log.debug(("Configuration option 'manage_etc_hosts' is not set," - " not managing /etc/hosts in transform %s"), name) diff --git a/cloudinit/transforms/update_hostname.py b/cloudinit/transforms/update_hostname.py deleted file mode 100644 index 58444fab..00000000 --- a/cloudinit/transforms/update_hostname.py +++ /dev/null @@ -1,41 +0,0 @@ -# vi: ts=4 expandtab -# -# Copyright (C) 2011 Canonical Ltd. -# Copyright (C) 2012 Hewlett-Packard Development Company, L.P. -# -# Author: Scott Moser -# Author: Juerg Haefliger -# -# 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 . - -import os - -from cloudinit import util -from cloudinit.settings import PER_ALWAYS - -frequency = PER_ALWAYS - - -def handle(name, cfg, cloud, log, _args): - if util.get_cfg_option_bool(cfg, "preserve_hostname", False): - log.debug(("Configuration option 'preserve_hostname' is set," - " not updating the hostname in transform %s"), name) - return - - (hostname, _fqdn) = util.get_hostname_fqdn(cfg, cloud) - try: - prev_fn = os.path.join(cloud.get_cpath('data'), "previous-hostname") - cloud.distro.update_hostname(hostname, prev_fn) - except Exception: - util.logexc(log, "Failed to set the hostname to %s", hostname) - raise -- cgit v1.2.3