summaryrefslogtreecommitdiff
path: root/cloudinit/config
diff options
context:
space:
mode:
authorScott Moser <smoser@brickies.net>2016-08-23 16:48:41 -0400
committerScott Moser <smoser@brickies.net>2016-08-23 16:48:41 -0400
commit7b925df28f84c824e9e4697723d879903a81e780 (patch)
tree2314e210f13cc5cc7bdc59971b9f4b657f755825 /cloudinit/config
parentd0c794919d9a9bf176eb96e25e72836a65e841f1 (diff)
parenta551cb080388c2016bcf23981f99a4a6aa0fe198 (diff)
downloadvyos-cloud-init-7b925df28f84c824e9e4697723d879903a81e780.tar.gz
vyos-cloud-init-7b925df28f84c824e9e4697723d879903a81e780.zip
merge trunk at 0.7.7~bzr1208
Diffstat (limited to 'cloudinit/config')
-rw-r--r--cloudinit/config/cc_chef.py26
-rw-r--r--cloudinit/config/cc_lxd.py121
-rw-r--r--cloudinit/config/cc_phone_home.py7
-rw-r--r--cloudinit/config/cc_rh_subscription.py14
4 files changed, 138 insertions, 30 deletions
diff --git a/cloudinit/config/cc_chef.py b/cloudinit/config/cc_chef.py
index 28711a59..4c28be6a 100644
--- a/cloudinit/config/cc_chef.py
+++ b/cloudinit/config/cc_chef.py
@@ -38,8 +38,10 @@ It can be configured with the following option structure::
chef:
directories: (defaulting to /etc/chef, /var/log/chef, /var/lib/chef,
/var/cache/chef, /var/backups/chef, /var/run/chef)
- validation_key or validation_cert: (optional string to be written to
- /etc/chef/validation.pem)
+ validation_cert: (optional string to be written to file validation_key)
+ special value 'system' means set use existing file
+ validation_key: (optional the path for validation_cert. default
+ /etc/chef/validation.pem)
firstboot_path: (path to write run_list and initial_attributes keys that
should also be present in this configuration, defaults
to /etc/chef/firstboot.json)
@@ -64,6 +66,7 @@ It can be configured with the following option structure::
server_url:
show_time:
ssl_verify_mode:
+ validation_cert:
validation_key:
validation_name:
"""
@@ -105,6 +108,7 @@ CHEF_RB_TPL_DEFAULTS = {
# These are not symbols...
'log_location': '/var/log/chef/client.log',
'validation_key': CHEF_VALIDATION_PEM_PATH,
+ 'validation_cert': None,
'client_key': "/etc/chef/client.pem",
'json_attribs': CHEF_FB_PATH,
'file_cache_path': "/var/cache/chef",
@@ -201,13 +205,17 @@ def handle(name, cfg, cloud, log, _args):
for d in itertools.chain(chef_dirs, REQUIRED_CHEF_DIRS):
util.ensure_dir(d)
- # Set the validation key based on the presence of either 'validation_key'
- # or 'validation_cert'. In the case where both exist, 'validation_key'
- # takes precedence
- for key in ('validation_key', 'validation_cert'):
- if key in chef_cfg and chef_cfg[key]:
- util.write_file(CHEF_VALIDATION_PEM_PATH, chef_cfg[key])
- break
+ vkey_path = chef_cfg.get('validation_key', CHEF_VALIDATION_PEM_PATH)
+ vcert = chef_cfg.get('validation_cert')
+ # special value 'system' means do not overwrite the file
+ # but still render the template to contain 'validation_key'
+ if vcert:
+ if vcert != "system":
+ util.write_file(vkey_path, vcert)
+ elif not os.path.isfile(vkey_path):
+ log.warn("chef validation_cert provided as 'system', but "
+ "validation_key path '%s' does not exist.",
+ vkey_path)
# Create the chef config from template
template_fn = cloud.get_template_filename('chef_client.rb')
diff --git a/cloudinit/config/cc_lxd.py b/cloudinit/config/cc_lxd.py
index 63b8fb63..bf735648 100644
--- a/cloudinit/config/cc_lxd.py
+++ b/cloudinit/config/cc_lxd.py
@@ -30,6 +30,19 @@ Example config:
storage_create_loop: <size>
storage_pool: <name>
trust_password: <password>
+ bridge:
+ mode: <new, existing or none>
+ name: <name>
+ ipv4_address: <ip addr>
+ ipv4_netmask: <cidr>
+ ipv4_dhcp_first: <ip addr>
+ ipv4_dhcp_last: <ip addr>
+ ipv4_dhcp_leases: <size>
+ ipv4_nat: <bool>
+ ipv6_address: <ip addr>
+ ipv6_netmask: <cidr>
+ ipv6_nat: <bool>
+ domain: <domain>
"""
from cloudinit import util
@@ -46,22 +59,24 @@ def handle(name, cfg, cloud, log, args):
type(lxd_cfg))
return
+ # Grab the configuration
init_cfg = lxd_cfg.get('init')
if not isinstance(init_cfg, dict):
log.warn("lxd/init config must be a dictionary. found a '%s'",
type(init_cfg))
init_cfg = {}
- if not init_cfg:
- log.debug("no lxd/init config. disabled.")
- return
+ bridge_cfg = lxd_cfg.get('bridge')
+ if not isinstance(bridge_cfg, dict):
+ log.warn("lxd/bridge config must be a dictionary. found a '%s'",
+ type(bridge_cfg))
+ bridge_cfg = {}
+ # Install the needed packages
packages = []
- # Ensure lxd is installed
if not util.which("lxd"):
packages.append('lxd')
- # if using zfs, get the utils
if init_cfg.get("storage_backend") == "zfs" and not util.which('zfs'):
packages.append('zfs')
@@ -73,13 +88,89 @@ def handle(name, cfg, cloud, log, args):
return
# Set up lxd if init config is given
- init_keys = (
- 'network_address', 'network_port', 'storage_backend',
- 'storage_create_device', 'storage_create_loop',
- 'storage_pool', 'trust_password')
- cmd = ['lxd', 'init', '--auto']
- for k in init_keys:
- if init_cfg.get(k):
- cmd.extend(["--%s=%s" %
- (k.replace('_', '-'), str(init_cfg[k]))])
- util.subp(cmd)
+ if init_cfg:
+ init_keys = (
+ 'network_address', 'network_port', 'storage_backend',
+ 'storage_create_device', 'storage_create_loop',
+ 'storage_pool', 'trust_password')
+ cmd = ['lxd', 'init', '--auto']
+ for k in init_keys:
+ if init_cfg.get(k):
+ cmd.extend(["--%s=%s" %
+ (k.replace('_', '-'), str(init_cfg[k]))])
+ util.subp(cmd)
+
+ # Set up lxd-bridge if bridge config is given
+ dconf_comm = "debconf-communicate"
+ if bridge_cfg and util.which(dconf_comm):
+ debconf = bridge_to_debconf(bridge_cfg)
+
+ # Update debconf database
+ try:
+ log.debug("Setting lxd debconf via " + dconf_comm)
+ data = "\n".join(["set %s %s" % (k, v)
+ for k, v in debconf.items()]) + "\n"
+ util.subp(['debconf-communicate'], data)
+ except:
+ util.logexc(log, "Failed to run '%s' for lxd with" % dconf_comm)
+
+ # Remove the existing configuration file (forces re-generation)
+ util.del_file("/etc/default/lxd-bridge")
+
+ # Run reconfigure
+ log.debug("Running dpkg-reconfigure for lxd")
+ util.subp(['dpkg-reconfigure', 'lxd',
+ '--frontend=noninteractive'])
+ elif bridge_cfg:
+ raise RuntimeError(
+ "Unable to configure lxd bridge without %s." + dconf_comm)
+
+
+def bridge_to_debconf(bridge_cfg):
+ debconf = {}
+
+ if bridge_cfg.get("mode") == "none":
+ debconf["lxd/setup-bridge"] = "false"
+ debconf["lxd/bridge-name"] = ""
+
+ elif bridge_cfg.get("mode") == "existing":
+ debconf["lxd/setup-bridge"] = "false"
+ debconf["lxd/use-existing-bridge"] = "true"
+ debconf["lxd/bridge-name"] = bridge_cfg.get("name")
+
+ elif bridge_cfg.get("mode") == "new":
+ debconf["lxd/setup-bridge"] = "true"
+ if bridge_cfg.get("name"):
+ debconf["lxd/bridge-name"] = bridge_cfg.get("name")
+
+ if bridge_cfg.get("ipv4_address"):
+ debconf["lxd/bridge-ipv4"] = "true"
+ debconf["lxd/bridge-ipv4-address"] = \
+ bridge_cfg.get("ipv4_address")
+ debconf["lxd/bridge-ipv4-netmask"] = \
+ bridge_cfg.get("ipv4_netmask")
+ debconf["lxd/bridge-ipv4-dhcp-first"] = \
+ bridge_cfg.get("ipv4_dhcp_first")
+ debconf["lxd/bridge-ipv4-dhcp-last"] = \
+ bridge_cfg.get("ipv4_dhcp_last")
+ debconf["lxd/bridge-ipv4-dhcp-leases"] = \
+ bridge_cfg.get("ipv4_dhcp_leases")
+ debconf["lxd/bridge-ipv4-nat"] = \
+ bridge_cfg.get("ipv4_nat", "true")
+
+ if bridge_cfg.get("ipv6_address"):
+ debconf["lxd/bridge-ipv6"] = "true"
+ debconf["lxd/bridge-ipv6-address"] = \
+ bridge_cfg.get("ipv6_address")
+ debconf["lxd/bridge-ipv6-netmask"] = \
+ bridge_cfg.get("ipv6_netmask")
+ debconf["lxd/bridge-ipv6-nat"] = \
+ bridge_cfg.get("ipv6_nat", "false")
+
+ if bridge_cfg.get("domain"):
+ debconf["lxd/bridge-domain"] = bridge_cfg.get("domain")
+
+ else:
+ raise Exception("invalid bridge mode \"%s\"" % bridge_cfg.get("mode"))
+
+ return debconf
diff --git a/cloudinit/config/cc_phone_home.py b/cloudinit/config/cc_phone_home.py
index 18a7ddad..3dcc9459 100644
--- a/cloudinit/config/cc_phone_home.py
+++ b/cloudinit/config/cc_phone_home.py
@@ -30,7 +30,8 @@ POST_LIST_ALL = [
'pub_key_rsa',
'pub_key_ecdsa',
'instance_id',
- 'hostname'
+ 'hostname',
+ 'fdqn'
]
@@ -41,7 +42,8 @@ POST_LIST_ALL = [
#
# phone_home:
# url: http://my.foo.bar/$INSTANCE_ID/
-# post: [ pub_key_dsa, pub_key_rsa, pub_key_ecdsa, instance_id
+# post: [ pub_key_dsa, pub_key_rsa, pub_key_ecdsa, instance_id, hostname,
+# fqdn ]
#
def handle(name, cfg, cloud, log, args):
if len(args) != 0:
@@ -74,6 +76,7 @@ def handle(name, cfg, cloud, log, args):
all_keys = {}
all_keys['instance_id'] = cloud.get_instance_id()
all_keys['hostname'] = cloud.get_hostname()
+ all_keys['fqdn'] = cloud.get_hostname(fqdn=True)
pubkeys = {
'pub_key_dsa': '/etc/ssh/ssh_host_dsa_key.pub',
diff --git a/cloudinit/config/cc_rh_subscription.py b/cloudinit/config/cc_rh_subscription.py
index 6087c45c..3a113aea 100644
--- a/cloudinit/config/cc_rh_subscription.py
+++ b/cloudinit/config/cc_rh_subscription.py
@@ -19,10 +19,14 @@
from cloudinit import util
-def handle(_name, cfg, _cloud, log, _args):
+def handle(name, cfg, _cloud, log, _args):
sm = SubscriptionManager(cfg)
sm.log = log
- if not sm.is_registered:
+ if not sm.is_configured():
+ log.debug("%s: module not configured.", name)
+ return None
+
+ if not sm.is_registered():
try:
verify, verify_msg = sm._verify_keys()
if verify is not True:
@@ -95,7 +99,6 @@ class SubscriptionManager(object):
self.disable_repo = self.rhel_cfg.get('disable-repo')
self.servicelevel = self.rhel_cfg.get('service-level')
self.subman = ['subscription-manager']
- self.is_registered = self._is_registered()
def log_success(self, msg):
'''Simple wrapper for logging info messages. Useful for unittests'''
@@ -134,7 +137,7 @@ class SubscriptionManager(object):
return False, no_auto
return True, None
- def _is_registered(self):
+ def is_registered(self):
'''
Checks if the system is already registered and returns
True if so, else False
@@ -400,3 +403,6 @@ class SubscriptionManager(object):
self.log.debug("Disabled the following repos: %s" %
(", ".join(disable_list)).replace('--disable=', ''))
return True
+
+ def is_configured(self):
+ return bool((self.userid and self.password) or self.activation_key)