cloud-init-dev team mailing list archive
-
cloud-init-dev team
-
Mailing list archive
-
Message #00835
[Merge] lp:~stgraber/cloud-init/lxd-bridge into lp:cloud-init
Stéphane Graber has proposed merging lp:~stgraber/cloud-init/lxd-bridge into lp:cloud-init.
Requested reviews:
cloud init development team (cloud-init-dev)
For more details, see:
https://code.launchpad.net/~stgraber/cloud-init/lxd-bridge/+merge/291475
This adds basic support for lxd-bridge configuration.
It exposes the most useful debconf keys as cloud-init configuration keys.
I've succesfuly tested all 3 modes with a locally patched-up cloud-init
and everything looks fine here.
--
Your team cloud init development team is requested to review the proposed merge of lp:~stgraber/cloud-init/lxd-bridge into lp:cloud-init.
=== modified file 'cloudinit/config/cc_lxd.py'
--- cloudinit/config/cc_lxd.py 2016-03-03 23:16:13 +0000
+++ cloudinit/config/cc_lxd.py 2016-04-11 04:11:12 +0000
@@ -30,9 +30,23 @@
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
+import os
def handle(name, cfg, cloud, log, args):
@@ -46,22 +60,24 @@
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 +89,78 @@
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
+ if 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"
+ debconf["lxd/bridge-name"] = bridge_cfg.get("name", "lxdbr0")
+ 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")
+
+ else:
+ log.warn("invalid bridge mode \"%s\"" % bridge_cfg.get("mode"))
+ return
+
+ # Update debconf database
+ try:
+ log.debug("Setting lxd debconf-set-selections")
+ for k, v in debconf.items():
+ util.subp(['debconf-communicate'], "set %s %s\n" % (k, v))
+ except:
+ util.logexc(log, "Failed to run debconf-communicate for lxd")
+
+ # Remove the existing configuration file (forces re-generation)
+ if os.path.exists("/etc/default/lxd-bridge"):
+ os.remove("/etc/default/lxd-bridge")
+
+ # Run reconfigure
+ try:
+ log.debug("Running dpkg-reconfigure for lxd")
+ util.subp(['dpkg-reconfigure', 'lxd',
+ '--frontend=noninteractive'])
+ except:
+ util.logexc(log, "Failed to run dpkg-reconfigure for lxd")
=== modified file 'doc/examples/cloud-config-lxd.txt'
--- doc/examples/cloud-config-lxd.txt 2016-03-01 05:19:55 +0000
+++ doc/examples/cloud-config-lxd.txt 2016-04-11 04:11:12 +0000
@@ -12,6 +12,20 @@
# 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
+# bridge: dict of options for the lxd bridge
+# mode: one of "new", "existing" or "none". Defaults to "new"
+# name: the name of the bridge. Defaults to "lxdbr0"
+# ipv4_address: an IPv4 address (e.g. 10.0.8.1)
+# ipv4_netmask: a CIDR mask value (e.g. 24)
+# ipv4_dhcp_first: the first IP of the DHCP range (e.g. 10.0.8.2)
+# ipv4_dhcp_last: the last IP of the DHCP range (e.g. 10.0.8.254)
+# ipv4_dhcp_leases: the size of the DHCP pool (e.g. 250)
+# ipv4_nat: either "true" or "false"
+# ipv6_address: an IPv6 address (e.g. fd98:9e0:3744::1)
+# ipv6_netmask: a CIDR mask value (e.g. 64)
+# ipv6_nat: either "true" or "false"
+# domain: domain name to use for the bridge
+
lxd:
init:
@@ -20,6 +34,19 @@
storage_backend: zfs
storage_pool: datapool
storage_create_loop: 10
+ bridge:
+ mode: new
+ name: lxdbr0
+ ipv4_address: 10.0.8.1
+ ipv4_netmask: 24
+ ipv4_dhcp_first: 10.0.8.2
+ ipv4_dhcp_last: 10.0.8.3
+ ipv4_dhcp_leases: 250
+ ipv4_nat: true
+ ipv6_address: fd98:9e0:3744::1
+ ipv6_netmask: 64
+ ipv6_nat: true
+ domain: lxd
# The simplist working configuration is
Follow ups