diff options
author | Scott Moser <smoser@ubuntu.com> | 2016-02-25 14:37:04 -0500 |
---|---|---|
committer | Scott Moser <smoser@ubuntu.com> | 2016-02-25 14:37:04 -0500 |
commit | 3b773f7919c86a58956e2fc493512bb2c1ce31a8 (patch) | |
tree | 6ab76ff494ceeb75b567b7c247791d1b6dac03a3 | |
parent | df6af3e1433b9e5564bec7cd452cfb3a0fb403e9 (diff) | |
parent | 4d8e7324c7242e1c969c8561462def6c1cda747c (diff) | |
download | vyos-cloud-init-3b773f7919c86a58956e2fc493512bb2c1ce31a8.tar.gz vyos-cloud-init-3b773f7919c86a58956e2fc493512bb2c1ce31a8.zip |
lxd: add support for setting up lxd using 'lxd init'
If lxd key is present in cfg, then run 'lxd init' with values from the
'init' entry in lxd configuration as flags.
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | cloudinit/config/cc_lxd.py | 68 | ||||
-rw-r--r-- | config/cloud.cfg | 1 | ||||
-rw-r--r-- | doc/examples/cloud-config-lxd.txt | 21 | ||||
-rw-r--r-- | tests/unittests/test_handler/test_handler_lxd.py | 58 |
5 files changed, 149 insertions, 0 deletions
@@ -78,6 +78,7 @@ - docs: fix lock_passwd documentation [Robert C Jennings] - Azure: Handle escaped quotes in WALinuxAgentShim.find_endpoint. (LP: #1488891) [Dan Watkins] + - lxd: add support for setting up lxd using 'lxd init' (LP: #1522879) 0.7.6: - open 0.7.6 diff --git a/cloudinit/config/cc_lxd.py b/cloudinit/config/cc_lxd.py new file mode 100644 index 00000000..aaafb643 --- /dev/null +++ b/cloudinit/config/cc_lxd.py @@ -0,0 +1,68 @@ +# vi: ts=4 expandtab +# +# Copyright (C) 2016 Canonical Ltd. +# +# Author: Wesley Wiedenmeier <wesley.wiedenmeier@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/>. + +""" +This module initializes lxd using 'lxd init' + +Example config: + #cloud-config + lxd: + init: + network_address: <ip addr> + network_port: <port> + storage_backend: <zfs/dir> + storage_create_device: <dev> + storage_create_loop: <size> + storage_pool: <name> + trust_password: <password> +""" + +from cloudinit import util + + +def handle(name, cfg, cloud, log, args): + # Get config + lxd_cfg = cfg.get('lxd') + if not lxd_cfg and isinstance(lxd_cfg, dict): + log.debug("Skipping module named %s, not present or disabled by cfg") + return + + # Ensure lxd is installed + if not util.which("lxd"): + try: + cloud.distro.install_packages(("lxd",)) + except util.ProcessExecutionError as e: + log.warn("no lxd executable and could not install lxd:", e) + 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') + init_cfg = lxd_cfg.get('init') + if init_cfg: + if not isinstance(init_cfg, dict): + log.warn("lxd/init config must be a dictionary. found a '%s'", + type(f)) + return + cmd = ['lxd', 'init', '--auto'] + for k in init_keys: + if init_cfg.get(k): + cmd.extend(["--%s" % k.replace('_', '-'), init_cfg[k]]) + util.subp(cmd) diff --git a/config/cloud.cfg b/config/cloud.cfg index 74794ab0..795df19f 100644 --- a/config/cloud.cfg +++ b/config/cloud.cfg @@ -56,6 +56,7 @@ cloud_config_modules: - fan - landscape - timezone + - lxd - puppet - chef - salt-minion diff --git a/doc/examples/cloud-config-lxd.txt b/doc/examples/cloud-config-lxd.txt new file mode 100644 index 00000000..f66da4c3 --- /dev/null +++ b/doc/examples/cloud-config-lxd.txt @@ -0,0 +1,21 @@ +#cloud-config + +# configure lxd +# default: none +# all options default to none if not specified +# lxd: config sections for lxd +# init: dict of options for lxd init, see 'man lxd' +# network_address: address for lxd to listen on +# network_port: port for lxd to listen on +# storage_backend: either 'zfs' or 'dir' +# storage_create_device: device based storage using specified device +# storage_create_loop: set up loop based storage with size in GB +# storage_pool: name of storage pool to use or create +# trust_password: password required to add new clients + +lxd: + init: + network_address: 0.0.0.0 + network_port: 8443 + storage_backend: zfs + storage_pool: datapool diff --git a/tests/unittests/test_handler/test_handler_lxd.py b/tests/unittests/test_handler/test_handler_lxd.py new file mode 100644 index 00000000..4d858b8f --- /dev/null +++ b/tests/unittests/test_handler/test_handler_lxd.py @@ -0,0 +1,58 @@ +from cloudinit.config import cc_lxd +from cloudinit import (distros, helpers, cloud) +from cloudinit.sources import DataSourceNoCloud +from .. import helpers as t_help + +import logging + +try: + from unittest import mock +except ImportError: + import mock + +LOG = logging.getLogger(__name__) + + +class TestLxd(t_help.TestCase): + lxd_cfg = { + 'lxd': { + 'init': { + 'network_address': '0.0.0.0', + 'storage_backend': 'zfs', + 'storage_pool': 'poolname', + } + } + } + + def setUp(self): + super(TestLxd, self).setUp() + + def _get_cloud(self, distro): + cls = distros.fetch(distro) + paths = helpers.Paths({}) + d = cls(distro, {}, paths) + ds = DataSourceNoCloud.DataSourceNoCloud({}, d, paths) + cc = cloud.Cloud(ds, paths, {}, d, None) + return cc + + @mock.patch("cloudinit.config.cc_lxd.util") + def test_lxd_init(self, mock_util): + cc = self._get_cloud('ubuntu') + mock_util.which.return_value = True + cc_lxd.handle('cc_lxd', self.lxd_cfg, cc, LOG, []) + self.assertTrue(mock_util.which.called) + init_call = mock_util.subp.call_args_list[0][0][0] + self.assertEquals(init_call, + ['lxd', 'init', '--auto', '--network-address', + '0.0.0.0', '--storage-backend', 'zfs', + '--storage-pool', 'poolname']) + + @mock.patch("cloudinit.config.cc_lxd.util") + def test_lxd_install(self, mock_util): + cc = self._get_cloud('ubuntu') + cc.distro = mock.MagicMock() + mock_util.which.return_value = None + cc_lxd.handle('cc_lxd', self.lxd_cfg, cc, LOG, []) + self.assertTrue(cc.distro.install_packages.called) + install_pkg = cc.distro.install_packages.call_args_list[0][0][0] + self.assertEquals(install_pkg, ('lxd',)) |