summaryrefslogtreecommitdiff
path: root/cloudinit/handlers
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@yahoo-inc.com>2012-06-15 17:35:07 -0700
committerJoshua Harlow <harlowja@yahoo-inc.com>2012-06-15 17:35:07 -0700
commit4d74f499a0257a4f27f7def4b76402bcbde63567 (patch)
treef21599d717c026946722baf17c16b668ae84c106 /cloudinit/handlers
parent2631a5cea83ae32ea992d8d4dc9a01ff3da7725d (diff)
downloadvyos-cloud-init-4d74f499a0257a4f27f7def4b76402bcbde63567.tar.gz
vyos-cloud-init-4d74f499a0257a4f27f7def4b76402bcbde63567.zip
Moved the handlers from a user_data directory to a handler directory.
Diffstat (limited to 'cloudinit/handlers')
-rw-r--r--cloudinit/handlers/__init__.py221
-rw-r--r--cloudinit/handlers/boot_hook.py66
-rw-r--r--cloudinit/handlers/cc_apt_pipelining.py53
-rw-r--r--cloudinit/handlers/cc_apt_update_upgrade.py241
-rw-r--r--cloudinit/handlers/cc_bootcmd.py48
-rw-r--r--cloudinit/handlers/cc_byobu.py77
-rw-r--r--cloudinit/handlers/cc_ca_certs.py90
-rw-r--r--cloudinit/handlers/cc_chef.py119
-rw-r--r--cloudinit/handlers/cc_disable_ec2_metadata.py30
-rw-r--r--cloudinit/handlers/cc_final_message.py58
-rw-r--r--cloudinit/handlers/cc_foo.py29
-rw-r--r--cloudinit/handlers/cc_grub_dpkg.py64
-rw-r--r--cloudinit/handlers/cc_keys_to_console.py42
-rw-r--r--cloudinit/handlers/cc_landscape.py75
-rw-r--r--cloudinit/handlers/cc_locale.py54
-rw-r--r--cloudinit/handlers/cc_mcollective.py99
-rw-r--r--cloudinit/handlers/cc_mounts.py179
-rw-r--r--cloudinit/handlers/cc_phone_home.py106
-rw-r--r--cloudinit/handlers/cc_puppet.py108
-rw-r--r--cloudinit/handlers/cc_resizefs.py108
-rw-r--r--cloudinit/handlers/cc_rightscale_userdata.py78
-rw-r--r--cloudinit/handlers/cc_rsyslog.py101
-rw-r--r--cloudinit/handlers/cc_runcmd.py32
-rw-r--r--cloudinit/handlers/cc_salt_minion.py56
-rw-r--r--cloudinit/handlers/cc_scripts_per_boot.py34
-rw-r--r--cloudinit/handlers/cc_scripts_per_instance.py34
-rw-r--r--cloudinit/handlers/cc_scripts_per_once.py34
-rw-r--r--cloudinit/handlers/cc_scripts_user.py34
-rw-r--r--cloudinit/handlers/cc_set_hostname.py42
-rw-r--r--cloudinit/handlers/cc_set_passwords.py129
-rw-r--r--cloudinit/handlers/cc_ssh.py106
-rw-r--r--cloudinit/handlers/cc_ssh_import_id.py50
-rw-r--r--cloudinit/handlers/cc_timezone.py67
-rw-r--r--cloudinit/handlers/cc_update_etc_hosts.py87
-rw-r--r--cloudinit/handlers/cc_update_hostname.py101
35 files changed, 66 insertions, 2786 deletions
diff --git a/cloudinit/handlers/__init__.py b/cloudinit/handlers/__init__.py
deleted file mode 100644
index 5d70ac43..00000000
--- a/cloudinit/handlers/__init__.py
+++ /dev/null
@@ -1,221 +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/>.
-#
-
-import os
-import subprocess
-import sys
-import time
-import traceback
-
-import yaml
-
-from cloudinit.settings import (PER_INSTANCE, PER_ALWAYS, PER_ONCE)
-
-from cloudinit import log as logging
-from cloudinit import util
-
-LOG = logging.getLogger(__name__)
-
-DEF_HANDLER_VERSION = 1
-DEF_FREQ = PER_INSTANCE
-
-
-# reads a cloudconfig module list, returns
-# a 2 dimensional array suitable to pass to run_cc_modules
-def read_cc_modules(cfg, name):
- if name not in cfg:
- return([])
- module_list = []
- # create 'module_list', an array of arrays
- # where array[0] = config
- # array[1] = freq
- # array[2:] = arguemnts
- for item in cfg[name]:
- if isinstance(item, str):
- module_list.append((item,))
- elif isinstance(item, list):
- module_list.append(item)
- else:
- raise TypeError("failed to read '%s' item in config")
- return(module_list)
-
-
-def run_cc_modules(cc, module_list, log):
- failures = []
- for cfg_mod in module_list:
- name = cfg_mod[0]
- freq = None
- run_args = []
- if len(cfg_mod) > 1:
- freq = cfg_mod[1]
- if len(cfg_mod) > 2:
- run_args = cfg_mod[2:]
-
- try:
- log.debug("handling %s with freq=%s and args=%s" %
- (name, freq, run_args))
- cc.handle(name, run_args, freq=freq)
- except:
- log.warn(traceback.format_exc())
- log.error("config handling of %s, %s, %s failed\n" %
- (name, freq, run_args))
- failures.append(name)
-
- return(failures)
-
-
-# always returns well formated values
-# cfg is expected to have an entry 'output' in it, which is a dictionary
-# that includes entries for 'init', 'config', 'final' or 'all'
-# init: /var/log/cloud.out
-# config: [ ">> /var/log/cloud-config.out", /var/log/cloud-config.err ]
-# final:
-# output: "| logger -p"
-# error: "> /dev/null"
-# this returns the specific 'mode' entry, cleanly formatted, with value
-# None if if none is given
-def get_output_cfg(cfg, mode="init"):
- ret = [None, None]
- if not 'output' in cfg:
- return ret
-
- outcfg = cfg['output']
- if mode in outcfg:
- modecfg = outcfg[mode]
- else:
- if 'all' not in outcfg:
- return ret
- # if there is a 'all' item in the output list
- # then it applies to all users of this (init, config, final)
- modecfg = outcfg['all']
-
- # if value is a string, it specifies stdout and stderr
- if isinstance(modecfg, str):
- ret = [modecfg, modecfg]
-
- # if its a list, then we expect (stdout, stderr)
- if isinstance(modecfg, list):
- if len(modecfg) > 0:
- ret[0] = modecfg[0]
- if len(modecfg) > 1:
- ret[1] = modecfg[1]
-
- # if it is a dictionary, expect 'out' and 'error'
- # items, which indicate out and error
- if isinstance(modecfg, dict):
- if 'output' in modecfg:
- ret[0] = modecfg['output']
- if 'error' in modecfg:
- ret[1] = modecfg['error']
-
- # if err's entry == "&1", then make it same as stdout
- # as in shell syntax of "echo foo >/dev/null 2>&1"
- if ret[1] == "&1":
- ret[1] = ret[0]
-
- swlist = [">>", ">", "|"]
- for i in range(len(ret)):
- if not ret[i]:
- continue
- val = ret[i].lstrip()
- found = False
- for s in swlist:
- if val.startswith(s):
- val = "%s %s" % (s, val[len(s):].strip())
- found = True
- break
- if not found:
- # default behavior is append
- val = "%s %s" % (">>", val.strip())
- ret[i] = val
-
- return(ret)
-
-
-# redirect_output(outfmt, errfmt, orig_out, orig_err)
-# replace orig_out and orig_err with filehandles specified in outfmt or errfmt
-# fmt can be:
-# > FILEPATH
-# >> FILEPATH
-# | program [ arg1 [ arg2 [ ... ] ] ]
-#
-# with a '|', arguments are passed to shell, so one level of
-# shell escape is required.
-def redirect_output(outfmt, errfmt, o_out=sys.stdout, o_err=sys.stderr):
- if outfmt:
- (mode, arg) = outfmt.split(" ", 1)
- if mode == ">" or mode == ">>":
- owith = "ab"
- if mode == ">":
- owith = "wb"
- new_fp = open(arg, owith)
- elif mode == "|":
- proc = subprocess.Popen(arg, shell=True, stdin=subprocess.PIPE)
- new_fp = proc.stdin
- else:
- raise TypeError("invalid type for outfmt: %s" % outfmt)
-
- if o_out:
- os.dup2(new_fp.fileno(), o_out.fileno())
- if errfmt == outfmt:
- os.dup2(new_fp.fileno(), o_err.fileno())
- return
-
- if errfmt:
- (mode, arg) = errfmt.split(" ", 1)
- if mode == ">" or mode == ">>":
- owith = "ab"
- if mode == ">":
- owith = "wb"
- new_fp = open(arg, owith)
- elif mode == "|":
- proc = subprocess.Popen(arg, shell=True, stdin=subprocess.PIPE)
- new_fp = proc.stdin
- else:
- raise TypeError("invalid type for outfmt: %s" % outfmt)
-
- if o_err:
- os.dup2(new_fp.fileno(), o_err.fileno())
- return
-
-
-def form_module_name(name):
- canon_name = name.replace("-", "_")
- if canon_name.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("cc_"):
- canon_name = 'cc_%s' % (canon_name)
- return canon_name
-
-
-def fixup_module(mod):
- freq = getattr(mod, "frequency", None)
- if not freq:
- setattr(mod, 'frequency', PER_INSTANCE)
- handler = getattr(mod, "handle", None)
- if not handler:
- def empty_handle(_name, _cfg, _cloud, _log, _args):
- pass
- setattr(mod, 'handle', empty_handle)
- return mod
diff --git a/cloudinit/handlers/boot_hook.py b/cloudinit/handlers/boot_hook.py
new file mode 100644
index 00000000..c75aeb72
--- /dev/null
+++ b/cloudinit/handlers/boot_hook.py
@@ -0,0 +1,66 @@
+# vi: ts=4 expandtab
+#
+# Copyright (C) 2012 Canonical Ltd.
+# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
+# Copyright (C) 2012 Yahoo! Inc.
+#
+# Author: Scott Moser <scott.moser@canonical.com>
+# Author: Juerg Haefliger <juerg.haefliger@hp.com>
+# Author: Joshua Harlow <harlowja@yahoo-inc.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+
+from cloudinit import log as logging
+from cloudinit import user_data as ud
+from cloudinit import util
+
+from cloudinit.settings import (PER_ALWAYS)
+
+LOG = logging.getLogger(__name__)
+
+
+class BootHookPartHandler(ud.PartHandler):
+ def __init__(self, boothook_dir, instance_id):
+ ud.PartHandler.__init__(self, PER_ALWAYS)
+ self.boothook_dir = boothook_dir
+ self.instance_id = instance_id
+
+ def list_types(self):
+ return [
+ ud.type_from_starts_with("#cloud-boothook"),
+ ]
+
+ def _handle_part(self, _data, ctype, filename, payload, _frequency):
+ if ctype in ud.CONTENT_SIGNALS:
+ return
+
+ filename = util.clean_filename(filename)
+ payload = util.dos2unix(payload)
+ prefix = "#cloud-boothook"
+ start = 0
+ if payload.startswith(prefix):
+ start = len(prefix) + 1
+
+ filepath = os.path.join(self.boothook_dir, filename)
+ util.write_file(filepath, payload[start:], 0700)
+ try:
+ env = os.environ.copy()
+ env['INSTANCE_ID'] = str(self.instance_id)
+ util.subp([filepath], env=env)
+ except util.ProcessExecutionError as e:
+ util.logexc(LOG, "Boothooks script %s execution error", filepath)
+ except Exception as e:
+ util.logexc(LOG, ("Boothooks unknown "
+ "error when running %s"), filepath)
diff --git a/cloudinit/handlers/cc_apt_pipelining.py b/cloudinit/handlers/cc_apt_pipelining.py
deleted file mode 100644
index 0286a9ae..00000000
--- a/cloudinit/handlers/cc_apt_pipelining.py
+++ /dev/null
@@ -1,53 +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/>.
-
-import cloudinit.util as util
-from cloudinit.CloudConfig import per_instance
-
-frequency = per_instance
-default_file = "/etc/apt/apt.conf.d/90cloud-init-pipelining"
-
-
-def handle(_name, cfg, _cloud, log, _args):
-
- apt_pipe_value = util.get_cfg_option_str(cfg, "apt_pipelining", False)
- apt_pipe_value = str(apt_pipe_value).lower()
-
- if apt_pipe_value == "false":
- write_apt_snippet("0", log)
-
- elif apt_pipe_value in ("none", "unchanged", "os"):
- return
-
- elif apt_pipe_value in str(range(0, 6)):
- write_apt_snippet(apt_pipe_value, log)
-
- else:
- log.warn("Invalid option for apt_pipeling: %s" % apt_pipe_value)
-
-
-def write_apt_snippet(setting, log, f_name=default_file):
- """ Writes f_name with apt pipeline depth 'setting' """
-
- acquire_pipeline_depth = 'Acquire::http::Pipeline-Depth "%s";\n'
- file_contents = ("//Written by cloud-init per 'apt_pipelining'\n"
- + (acquire_pipeline_depth % setting))
-
- util.write_file(f_name, file_contents)
-
- log.debug("Wrote %s with APT pipeline setting" % f_name)
diff --git a/cloudinit/handlers/cc_apt_update_upgrade.py b/cloudinit/handlers/cc_apt_update_upgrade.py
deleted file mode 100644
index a7049bce..00000000
--- a/cloudinit/handlers/cc_apt_update_upgrade.py
+++ /dev/null
@@ -1,241 +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 cloudinit.util as util
-import subprocess
-import traceback
-import os
-import glob
-import cloudinit.CloudConfig as cc
-
-
-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)
- old_mir = util.get_cfg_option_str(cfg, 'apt_old_mirror', \
- "archive.ubuntu.com/ubuntu")
- rename_apt_lists(old_mir, mirror)
-
- # set up proxy
- proxy = cfg.get("apt_proxy", None)
- proxy_filename = "/etc/apt/apt.conf.d/95cloud-init-proxy"
- if proxy:
- try:
- contents = "Acquire::HTTP::Proxy \"%s\";\n"
- with open(proxy_filename, "w") as fp:
- fp.write(contents % proxy)
- except Exception as e:
- log.warn("Failed to write proxy to %s" % proxy_filename)
- elif os.path.isfile(proxy_filename):
- os.unlink(proxy_filename)
-
- # process 'apt_sources'
- if 'apt_sources' in cfg:
- errors = add_sources(cfg['apt_sources'],
- {'MIRROR': mirror, 'RELEASE': release})
- for e in errors:
- log.warn("Source Error: %s\n" % ':'.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:
- log.error("Failed to run debconf-set-selections")
- log.debug(traceback.format_exc())
-
- pkglist = util.get_cfg_option_list_or_str(cfg, 'packages', [])
-
- errors = []
- if update or len(pkglist) or upgrade:
- try:
- cc.update_package_sources()
- except subprocess.CalledProcessError as e:
- log.warn("apt-get update failed")
- log.debug(traceback.format_exc())
- errors.append(e)
-
- if upgrade:
- try:
- cc.apt_get("upgrade")
- except subprocess.CalledProcessError as e:
- log.warn("apt upgrade failed")
- log.debug(traceback.format_exc())
- errors.append(e)
-
- if len(pkglist):
- try:
- cc.install_packages(pkglist)
- except subprocess.CalledProcessError as e:
- log.warn("Failed to install packages: %s " % pkglist)
- log.debug(traceback.format_exc())
- errors.append(e)
-
- if len(errors):
- raise errors[0]
-
- return(True)
-
-
-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):
- os.rename(filename, "%s%s" % (nprefix, filename[olen:]))
-
-
-def get_release():
- stdout, _stderr = subprocess.Popen(['lsb_release', '-cs'],
- stdout=subprocess.PIPE).communicate()
- return(str(stdout).strip())
-
-
-def generate_sources_list(codename, mirror):
- util.render_to_file('sources.list', '/etc/apt/sources.list', \
- {'mirror': mirror, 'codename': codename})
-
-
-def add_sources(srclist, searchList=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 searchList is None:
- searchList = {}
- elst = []
-
- for ent in srclist:
- if 'source' not in ent:
- elst.append(["", "missing source"])
- continue
-
- source = ent['source']
- if source.startswith("ppa:"):
- try:
- util.subp(["add-apt-repository", source])
- except:
- elst.append([source, "add-apt-repository failed"])
- continue
-
- source = util.render_string(source, searchList)
-
- if 'filename' not in ent:
- ent['filename'] = 'cloud_config_sources.list'
-
- if not ent['filename'].startswith("/"):
- ent['filename'] = "%s/%s" % \
- ("/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:
- elst.append([source, "failed to get key from %s" % ks])
- continue
-
- if 'key' in ent:
- try:
- util.subp(('apt-key', 'add', '-'), ent['key'])
- except:
- elst.append([source, "failed add key"])
-
- try:
- util.write_file(ent['filename'], source + "\n", omode="ab")
- except:
- elst.append([source, "failed write to file %s" % ent['filename']])
-
- return(elst)
-
-
-def find_apt_mirror(cloud, cfg):
- """ find an apt_mirror given the cloud and cfg provided """
-
- # TODO: distro and defaults should be configurable
- distro = "ubuntu"
- defaults = {
- 'ubuntu': "http://archive.ubuntu.com/ubuntu",
- 'debian': "http://archive.debian.org/debian",
- }
- 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:
- if cloud:
- mirror = cloud.get_mirror()
-
- mydom = ""
-
- doms = []
-
- if not mirror and cloud:
- # 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 = []
- 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 = defaults[distro]
-
- return mirror
diff --git a/cloudinit/handlers/cc_bootcmd.py b/cloudinit/handlers/cc_bootcmd.py
deleted file mode 100644
index f584da02..00000000
--- a/cloudinit/handlers/cc_bootcmd.py
+++ /dev/null
@@ -1,48 +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 cloudinit.util as util
-import subprocess
-import tempfile
-import os
-from cloudinit.CloudConfig import per_always
-frequency = per_always
-
-
-def handle(_name, cfg, cloud, log, _args):
- if "bootcmd" not in cfg:
- return
-
- try:
- content = util.shellify(cfg["bootcmd"])
- tmpf = tempfile.TemporaryFile()
- tmpf.write(content)
- tmpf.seek(0)
- except:
- log.warn("failed to shellify bootcmd")
- raise
-
- try:
- env = os.environ.copy()
- env['INSTANCE_ID'] = cloud.get_instance_id()
- subprocess.check_call(['/bin/sh'], env=env, stdin=tmpf)
- tmpf.close()
- except:
- log.warn("failed to run commands from bootcmd")
- raise
diff --git a/cloudinit/handlers/cc_byobu.py b/cloudinit/handlers/cc_byobu.py
deleted file mode 100644
index e821b261..00000000
--- a/cloudinit/handlers/cc_byobu.py
+++ /dev/null
@@ -1,77 +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 cloudinit.util as util
-import subprocess
-import traceback
-
-
-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:
- 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)
-
- try:
- subprocess.check_call(cmd)
- except subprocess.CalledProcessError as e:
- log.debug(traceback.format_exc(e))
- raise Exception("Cmd returned %s: %s" % (e.returncode, cmd))
- except OSError as e:
- log.debug(traceback.format_exc(e))
- raise Exception("Cmd failed to execute: %s" % (cmd))
diff --git a/cloudinit/handlers/cc_ca_certs.py b/cloudinit/handlers/cc_ca_certs.py
deleted file mode 100644
index 3af6238a..00000000
--- a/cloudinit/handlers/cc_ca_certs.py
+++ /dev/null
@@ -1,90 +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 subprocess import check_call
-from cloudinit.util import (write_file, get_cfg_option_list_or_str,
- delete_dir_contents, subp)
-
-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/"
-
-
-def update_ca_certs():
- """
- Updates the CA certificate cache on the current machine.
- """
- check_call(["update-ca-certificates"])
-
-
-def add_ca_certs(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:
- cert_file_contents = "\n".join(certs)
- cert_file_fullpath = os.path.join(CA_CERT_PATH, CA_CERT_FILENAME)
- write_file(cert_file_fullpath, cert_file_contents, mode=0644)
- # Append cert filename to CA_CERT_CONFIG file.
- write_file(CA_CERT_CONFIG, "\n%s" % CA_CERT_FILENAME, omode="a")
-
-
-def remove_default_ca_certs():
- """
- Removes all default trusted CA certificates from the system. To actually
- apply the change you must also call L{update_ca_certs}.
- """
- delete_dir_contents(CA_CERT_PATH)
- delete_dir_contents(CA_CERT_SYSTEM_PATH)
- write_file(CA_CERT_CONFIG, "", mode=0644)
- debconf_sel = "ca-certificates ca-certificates/trust_new_crts select no"
- 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:
- 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()
-
- # If we are given any new trusted CA certs to add, add them.
- if "trusted" in ca_cert_cfg:
- trusted_certs = get_cfg_option_list_or_str(ca_cert_cfg, "trusted")
- if trusted_certs:
- log.debug("adding %d certificates" % len(trusted_certs))
- add_ca_certs(trusted_certs)
-
- # Update the system with the new cert configuration.
- update_ca_certs()
diff --git a/cloudinit/handlers/cc_chef.py b/cloudinit/handlers/cc_chef.py
deleted file mode 100644
index 941e04fe..00000000
--- a/cloudinit/handlers/cc_chef.py
+++ /dev/null
@@ -1,119 +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 os
-import subprocess
-import json
-import cloudinit.CloudConfig as cc
-import cloudinit.util as 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:
- return
- chef_cfg = cfg['chef']
-
- # ensure the chef directories we use exist
- mkdirs(['/etc/chef', '/var/log/chef', '/var/lib/chef',
- '/var/cache/chef', '/var/backups/chef', '/var/run/chef'])
-
- # 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]:
- with open('/etc/chef/validation.pem', 'w') as validation_key_fh:
- validation_key_fh.write(chef_cfg[key])
- break
-
- # create the chef config from template
- util.render_to_file('chef_client.rb', '/etc/chef/client.rb',
- {'server_url': chef_cfg['server_url'],
- 'node_name': util.get_cfg_option_str(chef_cfg, 'node_name',
- cloud.datasource.get_instance_id()),
- 'environment': util.get_cfg_option_str(chef_cfg, 'environment',
- '_default'),
- 'validation_name': chef_cfg['validation_name']})
-
- # set the firstboot json
- with open('/etc/chef/firstboot.json', 'w') as firstboot_json_fh:
- 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 initial_attributes.keys():
- initial_json[k] = initial_attributes[k]
- firstboot_json_fh.write(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(ruby_version, chef_version)
- # and finally, run chef-client
- log.debug('running chef-client')
- subprocess.check_call(['/usr/bin/chef-client', '-d', '-i', '1800',
- '-s', '20'])
- else:
- # this will install and run the chef-client from packages
- cc.install_packages(('chef',))
-
-
-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=None):
- cc.install_packages(get_ruby_packages(ruby_version))
- if not os.path.exists('/usr/bin/gem'):
- os.symlink('/usr/bin/gem%s' % ruby_version, '/usr/bin/gem')
- if not os.path.exists('/usr/bin/ruby'):
- os.symlink('/usr/bin/ruby%s' % ruby_version, '/usr/bin/ruby')
- if chef_version:
- subprocess.check_call(['/usr/bin/gem', 'install', 'chef',
- '-v %s' % chef_version, '--no-ri',
- '--no-rdoc', '--bindir', '/usr/bin', '-q'])
- else:
- subprocess.check_call(['/usr/bin/gem', 'install', 'chef',
- '--no-ri', '--no-rdoc', '--bindir',
- '/usr/bin', '-q'])
-
-
-def ensure_dir(d):
- if not os.path.exists(d):
- os.makedirs(d)
-
-
-def mkdirs(dirs):
- for d in dirs:
- ensure_dir(d)
diff --git a/cloudinit/handlers/cc_disable_ec2_metadata.py b/cloudinit/handlers/cc_disable_ec2_metadata.py
deleted file mode 100644
index 6b31ea8e..00000000
--- a/cloudinit/handlers/cc_disable_ec2_metadata.py
+++ /dev/null
@@ -1,30 +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 cloudinit.util as util
-import subprocess
-from cloudinit.CloudConfig import per_always
-
-frequency = per_always
-
-
-def handle(_name, cfg, _cloud, _log, _args):
- if util.get_cfg_option_bool(cfg, "disable_ec2_metadata", False):
- fwall = "route add -host 169.254.169.254 reject"
- subprocess.call(fwall.split(' '))
diff --git a/cloudinit/handlers/cc_final_message.py b/cloudinit/handlers/cc_final_message.py
deleted file mode 100644
index abb4ca32..00000000
--- a/cloudinit/handlers/cc_final_message.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/>.
-
-from cloudinit.CloudConfig import per_always
-import sys
-from cloudinit import util, boot_finished
-import time
-
-frequency = per_always
-
-final_message = "cloud-init boot finished at $TIMESTAMP. Up $UPTIME seconds"
-
-
-def handle(_name, cfg, _cloud, log, args):
- if len(args) != 0:
- msg_in = args[0]
- else:
- msg_in = util.get_cfg_option_str(cfg, "final_message", final_message)
-
- try:
- uptimef = open("/proc/uptime")
- uptime = uptimef.read().split(" ")[0]
- uptimef.close()
- except IOError as e:
- log.warn("unable to open /proc/uptime\n")
- uptime = "na"
-
- try:
- ts = time.strftime("%a, %d %b %Y %H:%M:%S %z", time.gmtime())
- except:
- ts = "na"
-
- try:
- subs = {'UPTIME': uptime, 'TIMESTAMP': ts}
- sys.stdout.write("%s\n" % util.render_string(msg_in, subs))
- except Exception as e:
- log.warn("failed to render string to stdout: %s" % e)
-
- fp = open(boot_finished, "wb")
- fp.write(uptime + "\n")
- fp.close()
diff --git a/cloudinit/handlers/cc_foo.py b/cloudinit/handlers/cc_foo.py
deleted file mode 100644
index 35ec3fa7..00000000
--- a/cloudinit/handlers/cc_foo.py
+++ /dev/null
@@ -1,29 +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 cloudinit
-#import cloudinit.util as util
-from cloudinit.CloudConfig import per_instance
-
-frequency = per_instance
-
-
-def handle(_name, _cfg, _cloud, _log, _args):
- print "hi"
diff --git a/cloudinit/handlers/cc_grub_dpkg.py b/cloudinit/handlers/cc_grub_dpkg.py
deleted file mode 100644
index 9f3a7eaf..00000000
--- a/cloudinit/handlers/cc_grub_dpkg.py
+++ /dev/null
@@ -1,64 +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 cloudinit.util as util
-import traceback
-import os
-
-
-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" % idevs + \
- "grub-pc grub-pc/install_devices_empty boolean %s\n" % idevs_empty
- log.debug("setting grub debconf-set-selections with '%s','%s'" %
- (idevs, idevs_empty))
-
- try:
- util.subp(('debconf-set-selections'), dconf_sel)
- except:
- log.error("Failed to run debconf-set-selections for grub-dpkg")
- log.debug(traceback.format_exc())
diff --git a/cloudinit/handlers/cc_keys_to_console.py b/cloudinit/handlers/cc_keys_to_console.py
deleted file mode 100644
index 73a477c0..00000000
--- a/cloudinit/handlers/cc_keys_to_console.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/>.
-
-from cloudinit.CloudConfig import per_instance
-import cloudinit.util as util
-import subprocess
-
-frequency = per_instance
-
-
-def handle(_name, cfg, _cloud, log, _args):
- cmd = ['/usr/lib/cloud-init/write-ssh-key-fingerprints']
- fp_blacklist = util.get_cfg_option_list_or_str(cfg,
- "ssh_fp_console_blacklist", [])
- key_blacklist = util.get_cfg_option_list_or_str(cfg,
- "ssh_key_console_blacklist", ["ssh-dss"])
- try:
- confp = open('/dev/console', "wb")
- cmd.append(','.join(fp_blacklist))
- cmd.append(','.join(key_blacklist))
- subprocess.call(cmd, stdout=confp)
- confp.close()
- except:
- log.warn("writing keys to console value")
- raise
diff --git a/cloudinit/handlers/cc_landscape.py b/cloudinit/handlers/cc_landscape.py
deleted file mode 100644
index a4113cbe..00000000
--- a/cloudinit/handlers/cc_landscape.py
+++ /dev/null
@@ -1,75 +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 os.path
-from cloudinit.CloudConfig import per_instance
-from configobj import ConfigObj
-
-frequency = per_instance
-
-lsc_client_cfg_file = "/etc/landscape/client.conf"
-
-# defaults taken from stock client.conf in landscape-client 11.07.1.1-0ubuntu2
-lsc_builtincfg = {
- '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
- """
-
- ls_cloudcfg = cfg.get("landscape", {})
-
- if not isinstance(ls_cloudcfg, dict):
- raise(Exception("'landscape' existed in config, but not a dict"))
-
- merged = mergeTogether([lsc_builtincfg, lsc_client_cfg_file, ls_cloudcfg])
-
- if not os.path.isdir(os.path.dirname(lsc_client_cfg_file)):
- os.makedirs(os.path.dirname(lsc_client_cfg_file))
-
- with open(lsc_client_cfg_file, "w") as fp:
- merged.write(fp)
-
- log.debug("updated %s" % lsc_client_cfg_file)
-
-
-def mergeTogether(objs):
- """
- merge together ConfigObj objects or things that ConfigObj() will take in
- later entries override earlier
- """
- cfg = ConfigObj({})
- for obj in objs:
- if isinstance(obj, ConfigObj):
- cfg.merge(obj)
- else:
- cfg.merge(ConfigObj(obj))
- return cfg
diff --git a/cloudinit/handlers/cc_locale.py b/cloudinit/handlers/cc_locale.py
deleted file mode 100644
index 2bb22fdb..00000000
--- a/cloudinit/handlers/cc_locale.py
+++ /dev/null
@@ -1,54 +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 cloudinit.util as util
-import os.path
-import subprocess
-import traceback
-
-
-def apply_locale(locale, cfgfile):
- if os.path.exists('/usr/sbin/locale-gen'):
- subprocess.Popen(['locale-gen', locale]).communicate()
- if os.path.exists('/usr/sbin/update-locale'):
- subprocess.Popen(['update-locale', locale]).communicate()
-
- util.render_to_file('default-locale', 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:
- return
-
- log.debug("setting locale to %s" % locale)
-
- try:
- apply_locale(locale, locale_cfgfile)
- except Exception as e:
- log.debug(traceback.format_exc(e))
- raise Exception("failed to apply locale %s" % locale)
diff --git a/cloudinit/handlers/cc_mcollective.py b/cloudinit/handlers/cc_mcollective.py
deleted file mode 100644
index a2a6230c..00000000
--- a/cloudinit/handlers/cc_mcollective.py
+++ /dev/null
@@ -1,99 +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/>.
-
-import os
-import subprocess
-import StringIO
-import ConfigParser
-import cloudinit.CloudConfig as cc
-import cloudinit.util as util
-
-pubcert_file = "/etc/mcollective/ssl/server-public.pem"
-pricert_file = "/etc/mcollective/ssl/server-private.pem"
-
-
-# Our fake header section
-class FakeSecHead(object):
- def __init__(self, fp):
- self.fp = fp
- self.sechead = '[nullsection]\n'
-
- def readline(self):
- if self.sechead:
- try:
- return self.sechead
- finally:
- self.sechead = None
- else:
- return self.fp.readline()
-
-
-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:
- return
- mcollective_cfg = cfg['mcollective']
- # Start by installing the mcollective package ...
- cc.install_packages(("mcollective",))
-
- # ... and then update the mcollective configuration
- if 'conf' in mcollective_cfg:
- # Create object for reading server.cfg values
- mcollective_config = ConfigParser.ConfigParser()
- # Read server.cfg values from original file in order to be able to mix
- # the rest up
- mcollective_config.readfp(FakeSecHead(open('/etc/mcollective/'
- 'server.cfg')))
- for cfg_name, cfg in mcollective_cfg['conf'].iteritems():
- if cfg_name == 'public-cert':
- util.write_file(pubcert_file, cfg, mode=0644)
- mcollective_config.set(cfg_name,
- 'plugin.ssl_server_public', pubcert_file)
- mcollective_config.set(cfg_name, 'securityprovider', 'ssl')
- elif cfg_name == 'private-cert':
- util.write_file(pricert_file, cfg, mode=0600)
- mcollective_config.set(cfg_name,
- 'plugin.ssl_server_private', pricert_file)
- 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
- os.rename('/etc/mcollective/server.cfg',
- '/etc/mcollective/server.cfg.old')
- outputfile = StringIO.StringIO()
- mcollective_config.write(outputfile)
- # Now we got the whole file, write to disk except first line
- # Note below, that we've just used ConfigParser because it generally
- # works. Below, we remove the initial 'nullsection' header
- # and then change 'key = value' to 'key: value'. The global
- # search and replace of '=' with ':' could be problematic though.
- # this most likely needs fixing.
- util.write_file('/etc/mcollective/server.cfg',
- outputfile.getvalue().replace('[nullsection]\n', '').replace(' =',
- ':'),
- mode=0644)
-
- # Start mcollective
- subprocess.check_call(['service', 'mcollective', 'start'])
diff --git a/cloudinit/handlers/cc_mounts.py b/cloudinit/handlers/cc_mounts.py
deleted file mode 100644
index 6cdd74e8..00000000
--- a/cloudinit/handlers/cc_mounts.py
+++ /dev/null
@@ -1,179 +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 cloudinit.util as util
-import os
-import re
-from string import whitespace # pylint: disable=W0402
-
-
-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"]
-
- # 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)
-
- for i in range(len(cfgmnt)):
- # skip something that wasn't a list
- if not isinstance(cfgmnt[i], list):
- continue
-
- # workaround, allow user to specify 'ephemeral'
- # rather than more ec2 correct 'ephemeral0'
- if cfgmnt[i][0] == "ephemeral":
- cfgmnt[i][0] = "ephemeral0"
-
- if is_mdname(cfgmnt[i][0]):
- newname = cloud.device_name_to_device(cfgmnt[i][0])
- if not newname:
- log.debug("ignoring nonexistant named mount %s" % cfgmnt[i][0])
- cfgmnt[i][1] = None
- else:
- if newname.startswith("/"):
- cfgmnt[i][0] = newname
- else:
- cfgmnt[i][0] = "/dev/%s" % newname
- else:
- if shortname.match(cfgmnt[i][0]):
- cfgmnt[i][0] = "/dev/%s" % cfgmnt[i][0]
-
- # 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 isinstance(cfgmnt[i][j], int):
- 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:
- devname = cloud.device_name_to_device(defmnt[0])
- if devname is None:
- continue
- if devname.startswith("/"):
- defmnt[0] = devname
- else:
- defmnt[0] = "/dev/%s" % devname
-
- cfgmnt_has = False
- for cfgm in cfgmnt:
- if cfgm[0] == defmnt[0]:
- cfgmnt_has = True
- break
-
- if cfgmnt_has:
- 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 = [x for x in cfgmnt if x[1] is not None]
-
- if len(actlist) == 0:
- 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,comment=cloudconfig" % line[3]
- if line[2] == "swap":
- needswap = True
- if line[1].startswith("/"):
- dirs.append(line[1])
- cc_lines.append('\t'.join(line))
-
- fstab_lines = []
- fstab = open("/etc/fstab", "r+")
- ws = re.compile("[%s]+" % whitespace)
- for line in fstab.read().splitlines():
- try:
- toks = ws.split(line)
- if toks[3].find(comment) != -1:
- continue
- except:
- pass
- fstab_lines.append(line)
-
- fstab_lines.extend(cc_lines)
-
- fstab.seek(0)
- fstab.write("%s\n" % '\n'.join(fstab_lines))
- fstab.truncate()
- fstab.close()
-
- if needswap:
- try:
- util.subp(("swapon", "-a"))
- except:
- log.warn("Failed to enable swap")
-
- for d in dirs:
- if os.path.exists(d):
- continue
- try:
- os.makedirs(d)
- except:
- log.warn("Failed to make '%s' config-mount\n", d)
-
- try:
- util.subp(("mount", "-a"))
- except:
- log.warn("'mount -a' failed")
diff --git a/cloudinit/handlers/cc_phone_home.py b/cloudinit/handlers/cc_phone_home.py
deleted file mode 100644
index a7ff74e1..00000000
--- a/cloudinit/handlers/cc_phone_home.py
+++ /dev/null
@@ -1,106 +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.CloudConfig import per_instance
-import cloudinit.util as util
-from time import sleep
-
-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("no 'url' token in phone_home")
- return
-
- url = ph_cfg['url']
- post_list = ph_cfg.get('post', 'all')
- tries = ph_cfg.get('tries', 10)
- try:
- tries = int(tries)
- except:
- log.warn("tries is not an integer. using 10")
- tries = 10
-
- 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:
- fp = open(path, "rb")
- all_keys[n] = fp.read()
- fp.close()
- except:
- log.warn("%s: failed to open in phone_home" % path)
-
- submit_keys = {}
- for k in post_list:
- if k in all_keys:
- submit_keys[k] = all_keys[k]
- else:
- submit_keys[k] = "N/A"
- log.warn("requested key %s from 'post' list not available")
-
- url = util.render_string(url, {'INSTANCE_ID': all_keys['instance_id']})
-
- null_exc = object()
- last_e = null_exc
- for i in range(0, tries):
- try:
- util.readurl(url, submit_keys)
- log.debug("succeeded submit to %s on try %i" % (url, i + 1))
- return
- except Exception as e:
- log.debug("failed to post to %s on try %i" % (url, i + 1))
- last_e = e
- sleep(3)
-
- log.warn("failed to post to %s in %i tries" % (url, tries))
- if last_e is not null_exc:
- raise(last_e)
-
- return
diff --git a/cloudinit/handlers/cc_puppet.py b/cloudinit/handlers/cc_puppet.py
deleted file mode 100644
index 6fc475f6..00000000
--- a/cloudinit/handlers/cc_puppet.py
+++ /dev/null
@@ -1,108 +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 os.path
-import pwd
-import socket
-import subprocess
-import StringIO
-import ConfigParser
-import cloudinit.CloudConfig as cc
-import cloudinit.util as 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:
- return
- puppet_cfg = cfg['puppet']
- # Start by installing the puppet package ...
- cc.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_fh = open('/etc/puppet/puppet.conf', 'r')
- # Create object for reading puppet.conf values
- puppet_config = ConfigParser.ConfigParser()
- # Read puppet.conf values from original file in order to be able to
- # mix the rest up
- puppet_config.readfp(StringIO.StringIO(''.join(i.lstrip() for i in
- puppet_conf_fh.readlines())))
- # Close original file, no longer needed
- puppet_conf_fh.close()
- for cfg_name, cfg in puppet_cfg['conf'].iteritems():
- # ca_cert configuration is a special case
- # Dump the puppetmaster 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
- os.makedirs('/var/lib/puppet/ssl')
- os.chmod('/var/lib/puppet/ssl', 0771)
- os.chown('/var/lib/puppet/ssl',
- pwd.getpwnam('puppet').pw_uid, 0)
- os.makedirs('/var/lib/puppet/ssl/certs/')
- os.chown('/var/lib/puppet/ssl/certs/',
- pwd.getpwnam('puppet').pw_uid, 0)
- ca_fh = open('/var/lib/puppet/ssl/certs/ca.pem', 'w')
- ca_fh.write(cfg)
- ca_fh.close()
- os.chown('/var/lib/puppet/ssl/certs/ca.pem',
- pwd.getpwnam('puppet').pw_uid, 0)
- util.restorecon_if_possible('/var/lib/puppet', recursive=True)
- else:
- #puppet_conf_fh.write("\n[%s]\n" % (cfg_name))
- # If puppet.conf already has this section we don't want to
- # write it again
- if puppet_config.has_section(cfg_name) == False:
- puppet_config.add_section(cfg_name)
- # 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
- v = v.replace("%f", socket.getfqdn())
- # Expand %i as the instance id
- v = v.replace("%i",
- cloud.datasource.get_instance_id())
- # certname needs to be downcase
- v = v.lower()
- puppet_config.set(cfg_name, o, v)
- #puppet_conf_fh.write("%s=%s\n" % (o, v))
- # We got all our config as wanted we'll rename
- # the previous puppet.conf and create our new one
- os.rename('/etc/puppet/puppet.conf', '/etc/puppet/puppet.conf.old')
- with open('/etc/puppet/puppet.conf', 'wb') as configfile:
- puppet_config.write(configfile)
- util.restorecon_if_possible('/etc/puppet/puppet.conf')
- # Set puppet to automatically start
- if os.path.exists('/etc/default/puppet'):
- subprocess.check_call(['sed', '-i',
- '-e', 's/^START=.*/START=yes/',
- '/etc/default/puppet'])
- elif os.path.exists('/bin/systemctl'):
- subprocess.check_call(['/bin/systemctl', 'enable', 'puppet.service'])
- elif os.path.exists('/sbin/chkconfig'):
- subprocess.check_call(['/sbin/chkconfig', 'puppet', 'on'])
- else:
- log.warn("Do not know how to enable puppet service on this system")
- # Start puppetd
- subprocess.check_call(['service', 'puppet', 'start'])
diff --git a/cloudinit/handlers/cc_resizefs.py b/cloudinit/handlers/cc_resizefs.py
deleted file mode 100644
index 2dc66def..00000000
--- a/cloudinit/handlers/cc_resizefs.py
+++ /dev/null
@@ -1,108 +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 cloudinit.util as util
-import subprocess
-import os
-import stat
-import sys
-import time
-import tempfile
-from cloudinit.CloudConfig import per_always
-
-frequency = per_always
-
-
-def handle(_name, cfg, _cloud, log, args):
- if len(args) != 0:
- resize_root = False
- if str(args[0]).lower() in ['true', '1', 'on', 'yes']:
- resize_root = True
- else:
- resize_root = util.get_cfg_option_str(cfg, "resize_rootfs", True)
-
- if str(resize_root).lower() in ['false', '0']:
- return
-
- # we use mktemp rather than mkstemp because early in boot nothing
- # else should be able to race us for this, and we need to mknod.
- devpth = tempfile.mktemp(prefix="cloudinit.resizefs.", dir="/run")
-
- try:
- st_dev = os.stat("/").st_dev
- dev = os.makedev(os.major(st_dev), os.minor(st_dev))
- os.mknod(devpth, 0400 | stat.S_IFBLK, 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 /")
- raise
-
- cmd = ['blkid', '-c', '/dev/null', '-sTYPE', '-ovalue', devpth]
- try:
- (fstype, _err) = util.subp(cmd)
- except subprocess.CalledProcessError as e:
- log.warn("Failed to get filesystem type of maj=%s, min=%s via: %s" %
- (os.major(st_dev), os.minor(st_dev), cmd))
- log.warn("output=%s\nerror=%s\n", e.output[0], e.output[1])
- os.unlink(devpth)
- raise
-
- if str(fstype).startswith("ext"):
- resize_cmd = ['resize2fs', devpth]
- elif fstype == "xfs":
- resize_cmd = ['xfs_growfs', devpth]
- else:
- os.unlink(devpth)
- log.debug("not resizing unknown filesystem %s" % fstype)
- return
-
- if resize_root == "noblock":
- fid = os.fork()
- if fid == 0:
- try:
- do_resize(resize_cmd, devpth, log)
- os._exit(0) # pylint: disable=W0212
- except Exception as exc:
- sys.stderr.write("Failed: %s" % exc)
- os._exit(1) # pylint: disable=W0212
- else:
- do_resize(resize_cmd, devpth, log)
-
- log.debug("resizing root filesystem (type=%s, maj=%i, min=%i, val=%s)" %
- (str(fstype).rstrip("\n"), os.major(st_dev), os.minor(st_dev),
- resize_root))
-
- return
-
-
-def do_resize(resize_cmd, devpth, log):
- try:
- start = time.time()
- util.subp(resize_cmd)
- except subprocess.CalledProcessError as e:
- log.warn("Failed to resize filesystem (%s)" % resize_cmd)
- log.warn("output=%s\nerror=%s\n", e.output[0], e.output[1])
- os.unlink(devpth)
- raise
-
- os.unlink(devpth)
- log.debug("resize took %s seconds" % (time.time() - start))
diff --git a/cloudinit/handlers/cc_rightscale_userdata.py b/cloudinit/handlers/cc_rightscale_userdata.py
deleted file mode 100644
index 5ed0848f..00000000
--- a/cloudinit/handlers/cc_rightscale_userdata.py
+++ /dev/null
@@ -1,78 +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 cloudinit.util as util
-from cloudinit.CloudConfig import per_instance
-from cloudinit import get_ipath_cur
-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 %s" % my_name)
- return
-
- try:
- mdict = parse_qs(ud)
- if not my_hookname in mdict:
- return
- except:
- log.warn("failed to urlparse.parse_qa(userdata_raw())")
- raise
-
- scripts_d = get_ipath_cur('scripts')
- i = 0
- first_e = None
- for url in mdict[my_hookname]:
- fname = "%s/rightscale-%02i" % (scripts_d, i)
- i = i + 1
- try:
- content = util.readurl(url)
- util.write_file(fname, content, mode=0700)
- except Exception as e:
- if not first_e:
- first_e = None
- log.warn("%s failed to read %s: %s" % (my_name, url, e))
-
- if first_e:
- raise(e)
diff --git a/cloudinit/handlers/cc_rsyslog.py b/cloudinit/handlers/cc_rsyslog.py
deleted file mode 100644
index ac7f2c74..00000000
--- a/cloudinit/handlers/cc_rsyslog.py
+++ /dev/null
@@ -1,101 +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 cloudinit
-import logging
-import cloudinit.util as util
-import traceback
-
-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:
- return
-
- def_dir = cfg.get('rsyslog_dir', DEF_DIR)
- def_fname = cfg.get('rsyslog_filename', DEF_FILENAME)
-
- files = []
- elst = []
- for ent in cfg['rsyslog']:
- if isinstance(ent, dict):
- if not "content" in ent:
- elst.append((ent, "no 'content' entry"))
- continue
- content = ent['content']
- filename = ent.get("filename", def_fname)
- else:
- content = ent
- filename = def_fname
-
- if not filename.startswith("/"):
- filename = "%s/%s" % (def_dir, filename)
-
- omode = "ab"
- # truncate filename first time you see it
- if filename not in files:
- omode = "wb"
- files.append(filename)
-
- try:
- util.write_file(filename, content + "\n", omode=omode)
- except Exception as e:
- log.debug(traceback.format_exc(e))
- elst.append((content, "failed to write to %s" % filename))
-
- # need 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 as e:
- elst.append(("restart", str(e)))
-
- if restarted:
- # this only needs to run if we *actually* restarted
- # syslog above.
- cloudinit.logging_set_from_cfg_file()
- log = logging.getLogger()
- log.debug("rsyslog configured %s" % files)
-
- for e in elst:
- log.warn("rsyslog error: %s\n" % ':'.join(e))
-
- return
diff --git a/cloudinit/handlers/cc_runcmd.py b/cloudinit/handlers/cc_runcmd.py
deleted file mode 100644
index f7e8c671..00000000
--- a/cloudinit/handlers/cc_runcmd.py
+++ /dev/null
@@ -1,32 +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 cloudinit.util as util
-
-
-def handle(_name, cfg, cloud, log, _args):
- if "runcmd" not in cfg:
- return
- outfile = "%s/runcmd" % cloud.get_ipath('scripts')
- try:
- content = util.shellify(cfg["runcmd"])
- util.write_file(outfile, content, 0700)
- except:
- log.warn("failed to open %s for runcmd" % outfile)
diff --git a/cloudinit/handlers/cc_salt_minion.py b/cloudinit/handlers/cc_salt_minion.py
deleted file mode 100644
index 1a3b5039..00000000
--- a/cloudinit/handlers/cc_salt_minion.py
+++ /dev/null
@@ -1,56 +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
-import os.path
-import subprocess
-import cloudinit.CloudConfig as cc
-import yaml
-
-
-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:
- return
- salt_cfg = cfg['salt_minion']
- # Start by installing the salt package ...
- cc.install_packages(("salt",))
- config_dir = '/etc/salt'
- if not os.path.isdir(config_dir):
- os.makedirs(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')
- yaml.dump(salt_cfg['conf'],
- file(minion_config, 'w'),
- default_flow_style=False)
- # ... copy the key pair if specified
- if 'public_key' in salt_cfg and 'private_key' in salt_cfg:
- pki_dir = '/etc/salt/pki'
- cumask = os.umask(077)
- if not os.path.isdir(pki_dir):
- os.makedirs(pki_dir)
- pub_name = os.path.join(pki_dir, 'minion.pub')
- pem_name = os.path.join(pki_dir, 'minion.pem')
- with open(pub_name, 'w') as f:
- f.write(salt_cfg['public_key'])
- with open(pem_name, 'w') as f:
- f.write(salt_cfg['private_key'])
- os.umask(cumask)
-
- # Start salt-minion
- subprocess.check_call(['service', 'salt-minion', 'start'])
diff --git a/cloudinit/handlers/cc_scripts_per_boot.py b/cloudinit/handlers/cc_scripts_per_boot.py
deleted file mode 100644
index 41a74754..00000000
--- a/cloudinit/handlers/cc_scripts_per_boot.py
+++ /dev/null
@@ -1,34 +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 cloudinit.util as util
-from cloudinit.CloudConfig import per_always
-from cloudinit import get_cpath
-
-frequency = per_always
-runparts_path = "%s/%s" % (get_cpath(), "scripts/per-boot")
-
-
-def handle(_name, _cfg, _cloud, log, _args):
- try:
- util.runparts(runparts_path)
- except:
- log.warn("failed to run-parts in %s" % runparts_path)
- raise
diff --git a/cloudinit/handlers/cc_scripts_per_instance.py b/cloudinit/handlers/cc_scripts_per_instance.py
deleted file mode 100644
index a2981eab..00000000
--- a/cloudinit/handlers/cc_scripts_per_instance.py
+++ /dev/null
@@ -1,34 +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 cloudinit.util as util
-from cloudinit.CloudConfig import per_instance
-from cloudinit import get_cpath
-
-frequency = per_instance
-runparts_path = "%s/%s" % (get_cpath(), "scripts/per-instance")
-
-
-def handle(_name, _cfg, _cloud, log, _args):
- try:
- util.runparts(runparts_path)
- except:
- log.warn("failed to run-parts in %s" % runparts_path)
- raise
diff --git a/cloudinit/handlers/cc_scripts_per_once.py b/cloudinit/handlers/cc_scripts_per_once.py
deleted file mode 100644
index a69151da..00000000
--- a/cloudinit/handlers/cc_scripts_per_once.py
+++ /dev/null
@@ -1,34 +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 cloudinit.util as util
-from cloudinit.CloudConfig import per_once
-from cloudinit import get_cpath
-
-frequency = per_once
-runparts_path = "%s/%s" % (get_cpath(), "scripts/per-once")
-
-
-def handle(_name, _cfg, _cloud, log, _args):
- try:
- util.runparts(runparts_path)
- except:
- log.warn("failed to run-parts in %s" % runparts_path)
- raise
diff --git a/cloudinit/handlers/cc_scripts_user.py b/cloudinit/handlers/cc_scripts_user.py
deleted file mode 100644
index 933aa4e0..00000000
--- a/cloudinit/handlers/cc_scripts_user.py
+++ /dev/null
@@ -1,34 +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 cloudinit.util as util
-from cloudinit.CloudConfig import per_instance
-from cloudinit import get_ipath_cur
-
-frequency = per_instance
-runparts_path = "%s/%s" % (get_ipath_cur(), "scripts")
-
-
-def handle(_name, _cfg, _cloud, log, _args):
- try:
- util.runparts(runparts_path)
- except:
- log.warn("failed to run-parts in %s" % runparts_path)
- raise
diff --git a/cloudinit/handlers/cc_set_hostname.py b/cloudinit/handlers/cc_set_hostname.py
deleted file mode 100644
index acea74d9..00000000
--- a/cloudinit/handlers/cc_set_hostname.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 cloudinit.util as util
-
-
-def handle(_name, cfg, cloud, log, _args):
- if util.get_cfg_option_bool(cfg, "preserve_hostname", False):
- log.debug("preserve_hostname is set. not setting hostname")
- return(True)
-
- (hostname, _fqdn) = util.get_hostname_fqdn(cfg, cloud)
- try:
- set_hostname(hostname, log)
- except Exception:
- util.logexc(log)
- log.warn("failed to set hostname to %s\n", hostname)
-
- return(True)
-
-
-def set_hostname(hostname, log):
- util.subp(['hostname', hostname])
- util.write_file("/etc/hostname", "%s\n" % hostname, 0644)
- log.debug("populated /etc/hostname with %s on first boot", hostname)
diff --git a/cloudinit/handlers/cc_set_passwords.py b/cloudinit/handlers/cc_set_passwords.py
deleted file mode 100644
index 9d0bbdb8..00000000
--- a/cloudinit/handlers/cc_set_passwords.py
+++ /dev/null
@@ -1,129 +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 cloudinit.util as util
-import sys
-import random
-from string import letters, digits # pylint: disable=W0402
-
-
-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:
- util.subp(['chpasswd'], ch_in)
- log.debug("changed password for %s:" % users)
- except Exception as e:
- errors.append(e)
- log.warn("failed to set passwords with chpasswd: %s" % e)
-
- if len(randlist):
- sys.stdout.write("%s\n%s\n" % ("Set the following passwords\n",
- '\n'.join(randlist)))
-
- if expire:
- enum = len(errors)
- for u in users:
- try:
- util.subp(['passwd', '--expire', u])
- except Exception as e:
- errors.append(e)
- log.warn("failed to expire account for %s" % u)
- if enum == len(errors):
- log.debug("expired passwords for: %s" % u)
-
- if 'ssh_pwauth' in cfg:
- val = str(cfg['ssh_pwauth']).lower()
- if val in ("true", "1", "yes"):
- pw_auth = "yes"
- change_pwauth = True
- elif val in ("false", "0", "no"):
- pw_auth = "no"
- change_pwauth = True
- else:
- change_pwauth = False
-
- if change_pwauth:
- pa_s = "\(#*\)\(PasswordAuthentication[[:space:]]\+\)\(yes\|no\)"
- msg = "set PasswordAuthentication to '%s'" % pw_auth
- try:
- cmd = ['sed', '-i', 's,%s,\\2%s,' % (pa_s, pw_auth),
- '/etc/ssh/sshd_config']
- util.subp(cmd)
- log.debug(msg)
- except Exception as e:
- log.warn("failed %s" % msg)
- errors.append(e)
-
- try:
- p = util.subp(['service', cfg.get('ssh_svcname', 'ssh'),
- 'restart'])
- log.debug("restarted sshd")
- except:
- log.warn("restart of ssh failed")
-
- if len(errors):
- raise(errors[0])
-
- return
-
-
-def rand_str(strlen=32, select_from=letters + digits):
- return("".join([random.choice(select_from) for _x in range(0, strlen)]))
-
-
-def rand_user_password(pwlen=9):
- selfrom = (letters.translate(None, 'loLOI') +
- digits.translate(None, '01'))
- return(rand_str(pwlen, select_from=selfrom))
diff --git a/cloudinit/handlers/cc_ssh.py b/cloudinit/handlers/cc_ssh.py
deleted file mode 100644
index 48eb58bc..00000000
--- a/cloudinit/handlers/cc_ssh.py
+++ /dev/null
@@ -1,106 +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 cloudinit.util as util
-import cloudinit.SshUtil as sshutil
-import os
-import glob
-import subprocess
-
-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\""
-
-
-def handle(_name, cfg, cloud, log, _args):
-
- # remove the static keys from the pristine image
- if cfg.get("ssh_deletekeys", True):
- for f in glob.glob("/etc/ssh/ssh_host_*key*"):
- try:
- os.unlink(f)
- except:
- pass
-
- if "ssh_keys" in cfg:
- # if there are keys in cloud-config, use them
- 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),
- }
-
- for key, val in cfg["ssh_keys"].items():
- if key in key2file:
- util.write_file(key2file[key][0], val, key2file[key][1])
-
- priv2pub = {'rsa_private': 'rsa_public', 'dsa_private': 'dsa_public',
- 'ecdsa_private': 'ecdsa_public', }
-
- cmd = 'o=$(ssh-keygen -yf "%s") && echo "$o" root@localhost > "%s"'
- 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])
- subprocess.call(('sh', '-xc', cmd % pair))
- log.debug("generated %s from %s" % pair)
- else:
- # if not, generate them
- for keytype in util.get_cfg_option_list_or_str(cfg, 'ssh_genkeytypes',
- ['rsa', 'dsa', 'ecdsa']):
- keyfile = '/etc/ssh/ssh_host_%s_key' % keytype
- if not os.path.exists(keyfile):
- subprocess.call(['ssh-keygen', '-t', keytype, '-N', '',
- '-f', keyfile])
-
- util.restorecon_if_possible('/etc/ssh', recursive=True)
-
- 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()
-
- if "ssh_authorized_keys" in cfg:
- cfgkeys = cfg["ssh_authorized_keys"]
- keys.extend(cfgkeys)
-
- apply_credentials(keys, user, disable_root, disable_root_opts, log)
- except:
- util.logexc(log)
- log.warn("applying credentials failed!\n")
-
-
-def apply_credentials(keys, user, disable_root,
- disable_root_opts=DISABLE_ROOT_OPTS, log=None):
- keys = set(keys)
- if user:
- sshutil.setup_user_keys(keys, user, '', log)
-
- if disable_root:
- key_prefix = disable_root_opts.replace('$USER', user)
- else:
- key_prefix = ''
-
- sshutil.setup_user_keys(keys, 'root', key_prefix, log)
diff --git a/cloudinit/handlers/cc_ssh_import_id.py b/cloudinit/handlers/cc_ssh_import_id.py
deleted file mode 100644
index bbf5bd83..00000000
--- a/cloudinit/handlers/cc_ssh_import_id.py
+++ /dev/null
@@ -1,50 +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 cloudinit.util as util
-import subprocess
-import traceback
-
-
-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_or_str(cfg, "ssh_import_id", [])
-
- if len(ids) == 0:
- return
-
- cmd = ["sudo", "-Hu", user, "ssh-import-id"] + ids
-
- log.debug("importing ssh ids. cmd = %s" % cmd)
-
- try:
- subprocess.check_call(cmd)
- except subprocess.CalledProcessError as e:
- log.debug(traceback.format_exc(e))
- raise Exception("Cmd returned %s: %s" % (e.returncode, cmd))
- except OSError as e:
- log.debug(traceback.format_exc(e))
- raise Exception("Cmd failed to execute: %s" % (cmd))
diff --git a/cloudinit/handlers/cc_timezone.py b/cloudinit/handlers/cc_timezone.py
deleted file mode 100644
index e5c9901b..00000000
--- a/cloudinit/handlers/cc_timezone.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/>.
-
-from cloudinit.CloudConfig import per_instance
-from cloudinit import util
-import os.path
-import shutil
-
-frequency = per_instance
-tz_base = "/usr/share/zoneinfo"
-
-
-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:
- return
-
- tz_file = "%s/%s" % (tz_base, timezone)
-
- if not os.path.isfile(tz_file):
- log.debug("Invalid timezone %s" % tz_file)
- raise Exception("Invalid timezone %s" % tz_file)
-
- try:
- fp = open("/etc/timezone", "wb")
- fp.write("%s\n" % timezone)
- fp.close()
- except:
- log.debug("failed to write to /etc/timezone")
- raise
- if os.path.exists("/etc/sysconfig/clock"):
- try:
- with open("/etc/sysconfig/clock", "w") as fp:
- fp.write('ZONE="%s"\n' % timezone)
- except:
- log.debug("failed to write to /etc/sysconfig/clock")
- raise
-
- try:
- shutil.copy(tz_file, "/etc/localtime")
- except:
- log.debug("failed to copy %s to /etc/localtime" % tz_file)
- raise
-
- log.debug("set timezone to %s" % timezone)
- return
diff --git a/cloudinit/handlers/cc_update_etc_hosts.py b/cloudinit/handlers/cc_update_etc_hosts.py
deleted file mode 100644
index 6ad2fca8..00000000
--- a/cloudinit/handlers/cc_update_etc_hosts.py
+++ /dev/null
@@ -1,87 +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 cloudinit.util as util
-from cloudinit.CloudConfig import per_always
-import StringIO
-
-frequency = per_always
-
-
-def handle(_name, cfg, cloud, log, _args):
- (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud)
-
- manage_hosts = util.get_cfg_option_str(cfg, "manage_etc_hosts", False)
- if manage_hosts in ("True", "true", True, "template"):
- # render from template file
- try:
- if not hostname:
- log.info("manage_etc_hosts was set, but no hostname found")
- return
-
- util.render_to_file('hosts', '/etc/hosts',
- {'hostname': hostname, 'fqdn': fqdn})
- except Exception:
- log.warn("failed to update /etc/hosts")
- raise
- elif manage_hosts == "localhost":
- log.debug("managing 127.0.1.1 in /etc/hosts")
- update_etc_hosts(hostname, fqdn, log)
- return
- else:
- if manage_hosts not in ("False", False):
- log.warn("Unknown value for manage_etc_hosts. Assuming False")
- else:
- log.debug("not managing /etc/hosts")
-
-
-def update_etc_hosts(hostname, fqdn, _log):
- with open('/etc/hosts', 'r') as etchosts:
- header = "# Added by cloud-init\n"
- hosts_line = "127.0.1.1\t%s %s\n" % (fqdn, hostname)
- need_write = False
- need_change = True
- new_etchosts = StringIO.StringIO()
- for line in etchosts:
- split_line = [s.strip() for s in line.split()]
- if len(split_line) < 2:
- new_etchosts.write(line)
- continue
- if line == header:
- continue
- ip, hosts = split_line[0], split_line[1:]
- if ip == "127.0.1.1":
- if sorted([hostname, fqdn]) == sorted(hosts):
- need_change = False
- if need_change == True:
- line = "%s%s" % (header, hosts_line)
- need_change = False
- need_write = True
- new_etchosts.write(line)
- etchosts.close()
- if need_change == True:
- new_etchosts.write("%s%s" % (header, hosts_line))
- need_write = True
- if need_write == True:
- new_etcfile = open('/etc/hosts', 'wb')
- new_etcfile.write(new_etchosts.getvalue())
- new_etcfile.close()
- new_etchosts.close()
- return
diff --git a/cloudinit/handlers/cc_update_hostname.py b/cloudinit/handlers/cc_update_hostname.py
deleted file mode 100644
index b9d1919a..00000000
--- a/cloudinit/handlers/cc_update_hostname.py
+++ /dev/null
@@ -1,101 +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 cloudinit.util as util
-import subprocess
-import errno
-from cloudinit.CloudConfig 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("preserve_hostname is set. not updating hostname")
- return
-
- (hostname, _fqdn) = util.get_hostname_fqdn(cfg, cloud)
- try:
- prev = "%s/%s" % (cloud.get_cpath('data'), "previous-hostname")
- update_hostname(hostname, prev, log)
- except Exception:
- log.warn("failed to set hostname\n")
- raise
-
-
-# read hostname from a 'hostname' file
-# allow for comments and stripping line endings.
-# if file doesn't exist, or no contents, return default
-def read_hostname(filename, default=None):
- try:
- fp = open(filename, "r")
- lines = fp.readlines()
- fp.close()
- for line in lines:
- hpos = line.find("#")
- if hpos != -1:
- line = line[0:hpos]
- line = line.rstrip()
- if line:
- return line
- except IOError as e:
- if e.errno != errno.ENOENT:
- raise
- return default
-
-
-def update_hostname(hostname, prev_file, log):
- etc_file = "/etc/hostname"
-
- hostname_prev = None
- hostname_in_etc = None
-
- try:
- hostname_prev = read_hostname(prev_file)
- except Exception as e:
- log.warn("Failed to open %s: %s" % (prev_file, e))
-
- try:
- hostname_in_etc = read_hostname(etc_file)
- except:
- log.warn("Failed to open %s" % etc_file)
-
- update_files = []
- if not hostname_prev or hostname_prev != hostname:
- update_files.append(prev_file)
-
- if (not hostname_in_etc or
- (hostname_in_etc == hostname_prev and hostname_in_etc != hostname)):
- update_files.append(etc_file)
-
- try:
- for fname in update_files:
- util.write_file(fname, "%s\n" % hostname, 0644)
- log.debug("wrote %s to %s" % (hostname, fname))
- except:
- log.warn("failed to write hostname to %s" % fname)
-
- if hostname_in_etc and hostname_prev and hostname_in_etc != hostname_prev:
- log.debug("%s differs from %s. assuming user maintained" %
- (prev_file, etc_file))
-
- if etc_file in update_files:
- log.debug("setting hostname to %s" % hostname)
- subprocess.Popen(['hostname', hostname]).communicate()