Ryan Harper has proposed merging
~raharper/cloud-init:rebased-netconfig-v2-passthrough into cloud-init:master.
Requested reviews:
cloud init development team (cloud-init-dev)
For more details, see:
https://code.launchpad.net/~raharper/cloud-init/+git/cloud-init/+merge/320291
cloudinit.net: add v2 parsing, and v2 rendering
Network configuration version2 format is implemented in a package
called netplan (nplan)[1] which allows consolidated network config
for multiple network controllers.
- Add a new netplan renderer
- Update default policy, placing eni and sysconfig first
This requires explicit policy to enable netplan over eni
on systems which have both (Yakkety, Zesty, UC16)
- Allow v2 configs to be passed directly to netplan
- Allow any network state (parsed from any format cloud-init supports) to
render to v2 if system supports netplan.
- Move eni's _subnet_is_ipv6 to common code for use by other renderers
- Fix to base distro class for looking up path to
system_info/network/renderers
- Make sysconfig renderer always emit /etc/syconfig/network configuration
- Update cloud-init.service systemd unit to also wait on
systemd-networkd-wait-online.service
1. https://lists.ubuntu.com/archives/ubuntu-devel/2016-July/039464.html
--
Your team cloud init development team is requested to review the proposed merge
of ~raharper/cloud-init:rebased-netconfig-v2-passthrough into cloud-init:master.
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
index 803ac74..22ae998 100755
--- a/cloudinit/distros/__init__.py
+++ b/cloudinit/distros/__init__.py
@@ -73,7 +73,7 @@ class Distro(object):
def _supported_write_network_config(self, network_config):
priority = util.get_cfg_by_path(
-self._cfg, ('network', 'renderers'), None)
+self._cfg, ('system_info', 'network', 'renderers'), None)
name, render_cls = renderers.select(priority=priority)
LOG.debug("Selected renderer '%s' from priority list: %s",
diff --git a/cloudinit/distros/debian.py b/cloudinit/distros/debian.py
index 1101f02..26267c3 100644
--- a/cloudinit/distros/debian.py
+++ b/cloudinit/distros/debian.py
@@ -42,11 +42,16 @@ NETWORK_CONF_FN = "/etc/network/interfaces.d/50-cloud-init.cfg"
class Distro(distros.Distro):
hostname_conf_fn = "/etc/hostname"
locale_conf_fn = "/etc/default/locale"
+network_conf_fn = {
+"eni": "/etc/network/interfaces.d/50-cloud-init.cfg",
+"netplan": "/etc/netplan/50-cloud-init.yaml"
+}
renderer_configs = {
-'eni': {
-'eni_path': NETWORK_CONF_FN,
-'eni_header': ENI_HEADER,
-}
+"eni": {"eni_path": network_conf_fn["eni"],
+"eni_header": ENI_HEADER},
+"netplan": {"netplan_path": network_conf_fn["netplan"],
+"netplan_header": ENI_HEADER,
+"postcmds": True}
}
def __init__(self, name, cfg, paths):
@@ -75,7 +80,8 @@ class Distro(distros.Distro):
self.package_command('install', pkgs=pkglist)
def _write_network(self, settings):
-util.write_file(NETWORK_CONF_FN, settings)
+# this is always going to be legacy based
+util.write_file(self.network_conf_fn["eni"], settings)
return ['all']
def _write_network_config(self, netconfig):
diff --git a/cloudinit/net/eni.py b/cloudinit/net/eni.py
index 9d39a2b..6f6cc48 100644
--- a/cloudinit/net/eni.py
+++ b/cloudinit/net/eni.py
@@ -8,6 +8,7 @@ import re
from . import ParserError
from . import renderer
+from .network_state import subnet_is_ipv6
from cloudinit import util
@@ -111,16 +112,6 @@ def _iface_start_entry(iface, index, render_hwaddress=False):
return lines
-def _subnet_is_ipv6(subnet):
-# 'static6' or 'dhcp6'
-if subnet['type'].endswith('6'):
-# This is a request for DHCPv6.
-return True
-elif subnet['type'] == 'static' and ":" in subnet['address']:
-return True
-return False
-
-
def _parse_deb_config_data(ifaces, contents, src_dir, src_path):
"""Parses the file contents, placing result into ifaces.
@@ -370,7 +361,7 @@ class Renderer(renderer.Renderer):
iface['mode'] = subnet['type']
iface['control'] = subnet.get('control', 'auto')
subnet_inet = 'inet'
-if _subnet_is_ipv6(subnet):
+if subnet_is_ipv6(subnet):
subnet_inet += '6'
iface['inet'] = subnet_inet
if subnet['type'].startswith('dhcp'):
@@ -486,7 +477,7 @@ class Renderer(renderer.Renderer):
def network_state_to_eni(network_state, header=None, render_hwaddress=False):
# render the provided network state, return a string of equivalent eni
eni_path = 'etc/network/interfaces'
-renderer = Renderer({
+renderer = Renderer(config={
'eni_path': eni_path,
'eni_header': header,
'links_path_prefix':