summaryrefslogtreecommitdiff
path: root/cloudinit/transforms
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/transforms')
-rw-r--r--cloudinit/transforms/__init__.py57
-rw-r--r--cloudinit/transforms/apt_pipelining.py57
-rw-r--r--cloudinit/transforms/apt_update_upgrade.py243
-rw-r--r--cloudinit/transforms/bootcmd.py56
-rw-r--r--cloudinit/transforms/byobu.py71
-rw-r--r--cloudinit/transforms/ca_certs.py99
-rw-r--r--cloudinit/transforms/chef.py128
-rw-r--r--cloudinit/transforms/disable_ec2_metadata.py36
-rw-r--r--cloudinit/transforms/final_message.py71
-rw-r--r--cloudinit/transforms/foo.py52
-rw-r--r--cloudinit/transforms/grub_dpkg.py67
-rw-r--r--cloudinit/transforms/keys_to_console.py52
-rw-r--r--cloudinit/transforms/landscape.py97
-rw-r--r--cloudinit/transforms/locale.py58
-rw-r--r--cloudinit/transforms/mcollective.py97
-rw-r--r--cloudinit/transforms/mounts.py200
-rw-r--r--cloudinit/transforms/phone_home.py111
-rw-r--r--cloudinit/transforms/puppet.py111
-rw-r--r--cloudinit/transforms/resizefs.py140
-rw-r--r--cloudinit/transforms/rightscale_userdata.py102
-rw-r--r--cloudinit/transforms/rsyslog.py102
-rw-r--r--cloudinit/transforms/runcmd.py38
-rw-r--r--cloudinit/transforms/salt_minion.py60
-rw-r--r--cloudinit/transforms/scripts_per_boot.py41
-rw-r--r--cloudinit/transforms/scripts_per_instance.py41
-rw-r--r--cloudinit/transforms/scripts_per_once.py41
-rw-r--r--cloudinit/transforms/scripts_user.py42
-rw-r--r--cloudinit/transforms/set_hostname.py35
-rw-r--r--cloudinit/transforms/set_passwords.py151
-rw-r--r--cloudinit/transforms/ssh.py131
-rw-r--r--cloudinit/transforms/ssh_import_id.py53
-rw-r--r--cloudinit/transforms/timezone.py39
-rw-r--r--cloudinit/transforms/update_etc_hosts.py60
-rw-r--r--cloudinit/transforms/update_hostname.py41
34 files changed, 0 insertions, 2780 deletions
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 <chuck.short@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-
-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 <ben.howard@canonical.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import 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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-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 <mike.milner@canonical.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from cloudinit import util
-
-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 <avishai@fewbytes.com>
-# Author: Mike Moulton <mike@meltmedia.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import 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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import 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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from cloudinit import util
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from cloudinit.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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from 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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from cloudinit import 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 <marc.cluet@canonical.com>
-# Based on code by Scott Moser <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-##
-## 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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from cloudinit import util
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from cloudinit import util
-
-
-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 <jbauer@rubic.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from cloudinit import util
-
-# 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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from cloudinit import util
-
-from cloudinit.settings import PER_ALWAYS
-
-frequency = PER_ALWAYS
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from cloudinit import util
-
-from cloudinit.settings import PER_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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from cloudinit import util
-
-from cloudinit.settings import PER_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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from cloudinit import util
-
-from cloudinit.settings import PER_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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import 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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-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 <scott.moser@canonical.com>
-# Author: Juerg Haefliger <juerg.haefliger@hp.com>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from cloudinit import util
-from cloudinit.settings import PER_ALWAYS
-
-frequency = PER_ALWAYS
-
-
-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