summaryrefslogtreecommitdiff
path: root/cloudinit/config
diff options
context:
space:
mode:
Diffstat (limited to 'cloudinit/config')
-rw-r--r--cloudinit/config/cc_snappy.py133
1 files changed, 133 insertions, 0 deletions
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))