summaryrefslogtreecommitdiff
path: root/cloudinit
diff options
context:
space:
mode:
authorScott Moser <smoser@ubuntu.com>2015-03-04 17:00:16 -0500
committerScott Moser <smoser@ubuntu.com>2015-03-04 17:00:16 -0500
commit068ee3d324350fd998e2a27e5be2991ea9bab52f (patch)
treef7a1e0f8a2dc15e5555a3b97982c0475ec1e09dd /cloudinit
parentc808b84f1f6cdfe090a18b759a602eb504f36026 (diff)
parente7cce1a06429813b8d2acc87e6609671d39a3254 (diff)
downloadvyos-cloud-init-068ee3d324350fd998e2a27e5be2991ea9bab52f.tar.gz
vyos-cloud-init-068ee3d324350fd998e2a27e5be2991ea9bab52f.zip
pull in 'snappy' support
This allows config to disable some of the config modules that were failing and logging WARN on snapy. Also adds the snappy module and changes the syslog perms to take a list of user:groups rather than just a single. LP: #1428139
Diffstat (limited to 'cloudinit')
-rw-r--r--cloudinit/config/cc_apt_configure.py4
-rw-r--r--cloudinit/config/cc_emit_upstart.py28
-rw-r--r--cloudinit/config/cc_grub_dpkg.py21
-rw-r--r--cloudinit/config/cc_locale.py6
-rw-r--r--cloudinit/config/cc_snappy.py133
-rw-r--r--cloudinit/settings.py2
-rw-r--r--cloudinit/stages.py21
7 files changed, 194 insertions, 21 deletions
diff --git a/cloudinit/config/cc_apt_configure.py b/cloudinit/config/cc_apt_configure.py
index de72903f..2c51d116 100644
--- a/cloudinit/config/cc_apt_configure.py
+++ b/cloudinit/config/cc_apt_configure.py
@@ -51,6 +51,10 @@ EXPORT_GPG_KEYID = """
def handle(name, cfg, cloud, log, _args):
+ if util.is_false(cfg.get('apt_configure_enabled', True)):
+ log.debug("Skipping module named %s, disabled by config.", name)
+ return
+
release = get_release()
mirrors = find_apt_mirror_info(cloud, cfg)
if not mirrors or "primary" not in mirrors:
diff --git a/cloudinit/config/cc_emit_upstart.py b/cloudinit/config/cc_emit_upstart.py
index 6d376184..e1b9a4c2 100644
--- a/cloudinit/config/cc_emit_upstart.py
+++ b/cloudinit/config/cc_emit_upstart.py
@@ -21,11 +21,32 @@
import os
from cloudinit.settings import PER_ALWAYS
+from cloudinit import log as logging
from cloudinit import util
frequency = PER_ALWAYS
distros = ['ubuntu', 'debian']
+LOG = logging.getLogger(__name__)
+
+
+def is_upstart_system():
+ if not os.path.isfile("/sbin/initctl"):
+ LOG.debug(("Skipping module named %s,"
+ " no /sbin/initctl located"), name)
+ return False
+
+ myenv = os.environ.copy()
+ if 'UPSTART_SESSION' in myenv:
+ del myenv['UPSTART_SESSION']
+ check_cmd = ['initctl', 'version']
+ try:
+ (out, err) = util.subp(check_cmd, env=myenv)
+ return 'upstart' in out
+ except util.ProcessExecutionError as e:
+ LOG.debug("'%s' returned '%s', not using upstart",
+ ' '.join(check_cmd), e.exit_code)
+ return False
def handle(name, _cfg, cloud, log, args):
@@ -34,10 +55,11 @@ def handle(name, _cfg, cloud, log, args):
# Default to the 'cloud-config'
# event for backwards compat.
event_names = ['cloud-config']
- if not os.path.isfile("/sbin/initctl"):
- log.debug(("Skipping module named %s,"
- " no /sbin/initctl located"), name)
+
+ if not is_upstart_system():
+ log.debug("not upstart system, '%s' disabled")
return
+
cfgpath = cloud.paths.get_ipath_cur("cloud_config")
for n in event_names:
cmd = ['initctl', 'emit', str(n), 'CLOUD_CFG=%s' % cfgpath]
diff --git a/cloudinit/config/cc_grub_dpkg.py b/cloudinit/config/cc_grub_dpkg.py
index e3219e81..456597af 100644
--- a/cloudinit/config/cc_grub_dpkg.py
+++ b/cloudinit/config/cc_grub_dpkg.py
@@ -25,15 +25,20 @@ from cloudinit import util
distros = ['ubuntu', 'debian']
-def handle(_name, cfg, _cloud, log, _args):
- idevs = None
- idevs_empty = None
+def handle(name, cfg, _cloud, log, _args):
- 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)
+ mycfg = cfg.get("grub_dpkg", cfg.get("grub-dpkg", {}))
+ if not mycfg:
+ mycfg = {}
+
+ enabled = mycfg.get('enabled', True)
+ if util.is_false(enabled):
+ log.debug("%s disabled by config grub_dpkg/enabled=%s", name, enabled)
+ return
+
+ idevs = util.get_cfg_option_str(mycfg, "grub-pc/install_devices", None)
+ idevs_empty = util.get_cfg_option_str(mycfg,
+ "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")
diff --git a/cloudinit/config/cc_locale.py b/cloudinit/config/cc_locale.py
index 6feaae9d..bbe5fcae 100644
--- a/cloudinit/config/cc_locale.py
+++ b/cloudinit/config/cc_locale.py
@@ -27,9 +27,9 @@ def handle(name, cfg, cloud, log, args):
else:
locale = util.get_cfg_option_str(cfg, "locale", cloud.get_locale())
- if not locale:
- log.debug(("Skipping module named %s, "
- "no 'locale' configuration found"), name)
+ if util.is_false(locale):
+ log.debug("Skipping module named %s, disabled by config: %s",
+ name, locale)
return
log.debug("Setting locale to %s", locale)
diff --git a/cloudinit/config/cc_snappy.py b/cloudinit/config/cc_snappy.py
new file mode 100644
index 00000000..1588443f
--- /dev/null
+++ b/cloudinit/config/cc_snappy.py
@@ -0,0 +1,133 @@
+# vi: ts=4 expandtab
+#
+
+from cloudinit import log as logging
+from cloudinit import templater
+from cloudinit import util
+from cloudinit.settings import PER_INSTANCE
+
+import glob
+import os
+
+LOG = logging.getLogger(__name__)
+
+frequency = PER_INSTANCE
+SNAPPY_ENV_PATH = "/writable/system-data/etc/snappy.env"
+
+CI_SNAPPY_CFG = {
+ 'env_file_path': SNAPPY_ENV_PATH,
+ 'packages': [],
+ 'packages_dir': '/writable/user-data/cloud-init/click_packages',
+ 'ssh_enabled': False
+}
+
+"""
+snappy:
+ ssh_enabled: True
+ packages:
+ - etcd
+ - {'name': 'pkg1', 'config': "wark"}
+"""
+
+
+def flatten(data, fill=None, tok="_", prefix='', recurse=True):
+ if fill is None:
+ fill = {}
+ for key, val in data.items():
+ key = key.replace("-", "_")
+ if isinstance(val, dict) and recurse:
+ flatten(val, fill, tok=tok, prefix=prefix + key + tok,
+ recurse=recurse)
+ elif isinstance(key, str):
+ fill[prefix + key] = val
+ return fill
+
+
+def render2env(data, tok="_", prefix=''):
+ flat = flatten(data, tok=tok, prefix=prefix)
+ ret = ["%s='%s'" % (key, val) for key, val in flat.items()]
+ return '\n'.join(ret) + '\n'
+
+
+def install_package(pkg_name, config=None):
+ cmd = ["snappy", "install"]
+ if config:
+ if os.path.isfile(config):
+ cmd.append("--config-file=" + config)
+ else:
+ cmd.append("--config=" + config)
+ cmd.append(pkg_name)
+ util.subp(cmd)
+
+
+def install_packages(package_dir, packages):
+ local_pkgs = glob.glob(os.path.sep.join([package_dir, '*.click']))
+ LOG.debug("installing local packages %s" % local_pkgs)
+ if local_pkgs:
+ for pkg in local_pkgs:
+ cfg = pkg.replace(".click", ".config")
+ if not os.path.isfile(cfg):
+ cfg = None
+ install_package(pkg, config=cfg)
+
+ LOG.debug("installing click packages")
+ if packages:
+ for pkg in packages:
+ if not pkg:
+ continue
+ if isinstance(pkg, str):
+ name = pkg
+ config = None
+ elif pkg:
+ name = pkg.get('name', pkg)
+ config = pkg.get('config')
+ install_package(pkg_name=name, config=config)
+
+
+def disable_enable_ssh(enabled):
+ LOG.debug("setting enablement of ssh to: %s", enabled)
+ # do something here that would enable or disable
+ not_to_be_run = "/etc/ssh/sshd_not_to_be_run"
+ if enabled:
+ util.del_file(not_to_be_run)
+ # this is an indempotent operation
+ util.subp(["systemctl", "start", "ssh"])
+ else:
+ # this is an indempotent operation
+ util.subp(["systemctl", "stop", "ssh"])
+ util.write_file(not_to_be_run, "cloud-init\n")
+
+
+def handle(name, cfg, cloud, log, args):
+ mycfg = cfg.get('snappy', {'ssh_enabled': False})
+
+ if not mycfg:
+ LOG.debug("%s: no top level found", name)
+ return
+
+ # take out of 'cfg' the cfg keys that cloud-init uses, so
+ # mycfg has only content external to cloud-init.
+ ci_cfg = CI_SNAPPY_CFG.copy()
+ for i in ci_cfg:
+ if i in mycfg:
+ ci_cfg[i] = mycfg[i]
+ del mycfg[i]
+
+ # render the flattened environment variable style file to a path
+ # this was useful for systemd config environment files. given:
+ # snappy:
+ # foo:
+ # bar: wark
+ # cfg1:
+ # key1: value
+ # you get the following in env_file_path.
+ # foo_bar=wark
+ # foo_cfg1_key1=value
+ contents = render2env(mycfg)
+ header = '# for internal use only, not a guaranteed interface\n'
+ util.write_file(ci_cfg['env_file_path'], header + render2env(mycfg))
+
+ install_packages(ci_cfg['packages_dir'],
+ ci_cfg['packages'])
+
+ disable_enable_ssh(ci_cfg.get('ssh_enabled', False))
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
index 5efcb0b0..b61e5613 100644
--- a/cloudinit/settings.py
+++ b/cloudinit/settings.py
@@ -47,7 +47,7 @@ CFG_BUILTIN = {
],
'def_log_file': '/var/log/cloud-init.log',
'log_cfgs': [],
- 'syslog_fix_perms': 'syslog:adm',
+ 'syslog_fix_perms': ['syslog:adm', 'root:adm'],
'system_info': {
'paths': {
'cloud_dir': '/var/lib/cloud',
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
index 45d64823..d28e765b 100644
--- a/cloudinit/stages.py
+++ b/cloudinit/stages.py
@@ -148,16 +148,25 @@ class Init(object):
def _initialize_filesystem(self):
util.ensure_dirs(self._initial_subdirs())
log_file = util.get_cfg_option_str(self.cfg, 'def_log_file')
- perms = util.get_cfg_option_str(self.cfg, 'syslog_fix_perms')
if log_file:
util.ensure_file(log_file)
- if perms:
- u, g = util.extract_usergroup(perms)
+ perms = self.cfg.get('syslog_fix_perms')
+ if not perms:
+ perms = {}
+ if not isinstance(perms, list):
+ perms = [perms]
+
+ error = None
+ for perm in perms:
+ u, g = util.extract_usergroup(perm)
try:
util.chownbyname(log_file, u, g)
- except OSError:
- util.logexc(LOG, "Unable to change the ownership of %s to "
- "user %s, group %s", log_file, u, g)
+ return
+ except OSError as e:
+ error = e
+
+ LOG.warn("Failed changing perms on '%s'. tried: %s. %s",
+ log_file, ','.join(perms), error)
def read_cfg(self, extra_fns=None):
# None check so that we don't keep on re-loading if empty