[Cloud-init-dev] [Merge] ~raharper/cloud-init:rebased-netconfig-v2-passthrough into cloud-init:master

2017-03-20 Thread Scott Moser
The proposal to merge ~raharper/cloud-init:rebased-netconfig-v2-passthrough 
into cloud-init:master has been updated.

Status: Needs review => Merged

For more details, see:
https://code.launchpad.net/~raharper/cloud-init/+git/cloud-init/+merge/320291
-- 
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.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


Re: [Cloud-init-dev] [Merge] ~raharper/cloud-init:rebased-netconfig-v2-passthrough into cloud-init:master

2017-03-20 Thread Server Team CI bot
Review: Needs Fixing continuous-integration

FAILED: Continuous integration, rev:1c1fc3a8841a85b86b51931c9f8058832ad3b00a
https://jenkins.ubuntu.com/server/job/cloud-init-ci/145/
Executed test runs:
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-amd64/145/console
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-arm64/145/console
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-ppc64el/145/console
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-s390x/145/console
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=vm-i386/145/console

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/145/rebuild

-- 
https://code.launchpad.net/~raharper/cloud-init/+git/cloud-init/+merge/320291
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.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


Re: [Cloud-init-dev] [Merge] ~raharper/cloud-init:rebased-netconfig-v2-passthrough into cloud-init:master

2017-03-20 Thread Server Team CI bot
Review: Needs Fixing continuous-integration

FAILED: Continuous integration, rev:9bcc80e67b77dbce265de68c11f5f90916988ea0
https://jenkins.ubuntu.com/server/job/cloud-init-ci/144/
Executed test runs:
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-amd64/144/console
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-arm64/144/console
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-ppc64el/144/console
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-s390x/144/console
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=vm-i386/144/console

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/144/rebuild

-- 
https://code.launchpad.net/~raharper/cloud-init/+git/cloud-init/+merge/320291
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.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


[Cloud-init-dev] [Merge] ~raharper/cloud-init:rebased-netconfig-v2-passthrough into cloud-init:master

2017-03-20 Thread Ryan Harper
The proposal to merge ~raharper/cloud-init:rebased-netconfig-v2-passthrough 
into cloud-init:master has been updated.

Description changed to:

cloudinit.net: add network config v2 parsing and rendering

Network configuration version 2 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 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
- 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

For more details, see:
https://code.launchpad.net/~raharper/cloud-init/+git/cloud-init/+merge/320291
-- 
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.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


Re: [Cloud-init-dev] [Merge] ~raharper/cloud-init:rebased-netconfig-v2-passthrough into cloud-init:master

2017-03-20 Thread Ryan Harper


Diff comments:

> 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)

I needed this change to fix up the unittests in 
tests/unittests/test_distro/test_netconfig.py

I've not tested outside of unittest;  If you remove that change and run 
unittest on test_netconfig you can see.
It manifests itself as getting policy of None and then attempts to render eni 
for everything (so netplan and sysconfig renders write out udev files etc).

>  
>  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
> @@ -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

ACK

> +util.write_file(self.network_conf_fn["eni"], settings)
>  return ['all']
>  
>  def _write_network_config(self, netconfig):
> diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
> index 90b2835..ba84059 100644
> --- a/cloudinit/net/network_state.py
> +++ b/cloudinit/net/network_state.py
> @@ -103,14 +114,21 @@ class CommandHandlerMeta(type):
>  
>  class NetworkState(object):
>  
> -def __init__(self, network_state, version=NETWORK_STATE_VERSION):
> +def __init__(self, network_state, version=NETWORK_STATE_VERSION,
> + config=None):

Ill revisit;  I'm somewhat frustrated with the NSI vs NS objects; it maybe 
unneeded changes when doing the initial plumbing of getting v2 to pass through 
config to the renderers which only get (NetworkState) objects.

>  self._network_state = copy.deepcopy(network_state)
>  self._version = version
> +self._config = copy.deepcopy(config)
> +self.use_ipv6 = network_state.get('use_ipv6', False)
>  
>  @property
>  def version(self):
>  return self._version
>  
> +@property
> +def config(self):
> +return self._config
> +
>  def iter_routes(self, filter_func=None):
>  for route in self._network_state.get('routes', []):
>  if filter_func is not None:
> @@ -407,6 +471,239 @@ class NetworkStateInterpreter(object):
>  }
>  routes.append(route)
>  
> +# V2 handlers

ACK; it should be a simple change, we basically had 'handle_bond' (v1) and 
'handle_bonds' (v2); v2 being plural;  That's not easy to see.

> +def handle_bonds(self, command):
> +'''
> +v2_command = {
> +  bond0: {
> +'interfaces': ['interface0', 'interface1'],
> +'miimon': 100,
> +'mode': '802.3ad',
> +'xmit_hash_policy': 'layer3+4'},
> +  bond1: {
> +'bond-slaves': ['interface2', 'interface7'],
> +'mode': 1
> +  }
> +}
> +
> +v1_command = {
> +'type': 'bond'
> +'name': 'bond0',
> +'bond_interfaces': [interface0, interface1],
> +'params': {
> +'bond-mode': '802.3ad',
> +'bond_miimon: 100,
> +'bond_xmit_hash_policy': 'layer3+4',
> +}
> +}
> +
> +'''
> +self._handle_bond_bridge(command, cmd_type='bond')
> +
> +def handle_bridges(self, command):
> +
> +'''
> +v2_command = {
> +  br0: {
> +'interfaces': ['interface0', 'interface1'],
> +'fd': 0,
> +'stp': 'off',
> +'maxwait': 0,
> +  }
> +}
> +
> +v1_command = {
> +'type': 'bridge'
> +'name': 'br0',
> +'bridge_interfaces': [interface0, interface1],
> +'params': {
> +'bridge_stp': 'off',
> +'bridge_fd: 0,
> +'bridge_maxwait': 0
> +}
> +}
> +
> +'''
> +self._handle_bond_bridge(command, cmd_type='bridge')
> +
> +def handle_ethernets(self, command):
> +'''
> +ethernets:
> +  eno1:
> +match:
> +  macaddress: 00:11:22:33:44:55
> +wakeonlan: true
> +dhcp4: true
> +dhcp6: false
> +addresses:
> +  - 192.168.14.2/24
> +  - 2001:1::1/64
> +gateway4: 192.168.14.1
> +

Re: [Cloud-init-dev] [Merge] ~raharper/cloud-init:rebased-netconfig-v2-passthrough into cloud-init:master

2017-03-20 Thread Scott Moser
i have some small comments.
don't worry about fixing the 'handle_' comment, but i do worry about the 
confusion.


Diff comments:

> 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)

I'm pretty sure this is wrong.
distro gets as its config the system_info.  it does not get access to the full 
thing. see usage of _cfg via 'get_option' and '_get_arch_package_mirror_info' 
for my reasoning.  I did not test though.

>  
>  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
> @@ -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

# _write_network is legacy, it will always write eni

that sound reasonable?

> +util.write_file(self.network_conf_fn["eni"], settings)
>  return ['all']
>  
>  def _write_network_config(self, netconfig):
> diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
> index 90b2835..ba84059 100644
> --- a/cloudinit/net/network_state.py
> +++ b/cloudinit/net/network_state.py
> @@ -103,14 +114,21 @@ class CommandHandlerMeta(type):
>  
>  class NetworkState(object):
>  
> -def __init__(self, network_state, version=NETWORK_STATE_VERSION):
> +def __init__(self, network_state, version=NETWORK_STATE_VERSION,
> + config=None):

I dont understand why NetworkState is now getting a 'config', as it doesnt look 
like it gets used for anything.

>  self._network_state = copy.deepcopy(network_state)
>  self._version = version
> +self._config = copy.deepcopy(config)
> +self.use_ipv6 = network_state.get('use_ipv6', False)
>  
>  @property
>  def version(self):
>  return self._version
>  
> +@property
> +def config(self):
> +return self._config
> +
>  def iter_routes(self, filter_func=None):
>  for route in self._network_state.get('routes', []):
>  if filter_func is not None:
> @@ -407,6 +471,239 @@ class NetworkStateInterpreter(object):
>  }
>  routes.append(route)
>  
> +# V2 handlers

can we name these handle_v2_bonds, handle_v2_ethernets ?

just looking at this diff, I thought "Why are we adding support now for 'bonds' 
and 'vlans'?"  I'm sure I'll be confused by that again.

i realize that this is a bit involved due to the CommadnHandlerMeta path.. but 
this is going to get confusing.

> +def handle_bonds(self, command):
> +'''
> +v2_command = {
> +  bond0: {
> +'interfaces': ['interface0', 'interface1'],
> +'miimon': 100,
> +'mode': '802.3ad',
> +'xmit_hash_policy': 'layer3+4'},
> +  bond1: {
> +'bond-slaves': ['interface2', 'interface7'],
> +'mode': 1
> +  }
> +}
> +
> +v1_command = {
> +'type': 'bond'
> +'name': 'bond0',
> +'bond_interfaces': [interface0, interface1],
> +'params': {
> +'bond-mode': '802.3ad',
> +'bond_miimon: 100,
> +'bond_xmit_hash_policy': 'layer3+4',
> +}
> +}
> +
> +'''
> +self._handle_bond_bridge(command, cmd_type='bond')
> +
> +def handle_bridges(self, command):
> +
> +'''
> +v2_command = {
> +  br0: {
> +'interfaces': ['interface0', 'interface1'],
> +'fd': 0,
> +'stp': 'off',
> +'maxwait': 0,
> +  }
> +}
> +
> +v1_command = {
> +'type': 'bridge'
> +'name': 'br0',
> +'bridge_interfaces': [interface0, interface1],
> +'params': {
> +'bridge_stp': 'off',
> +'bridge_fd: 0,
> +'bridge_maxwait': 0
> +}
> +}
> +
> +'''
> +self._handle_bond_bridge(command, cmd_type='bridge')
> +
> +def handle_ethernets(self, command):
> +'''
> +ethernets:
> +  eno1:
> +match:
> +  macaddress: 00:11:22:33:44:55
> +wakeonlan: true
> +dhcp4: true
> +dhcp6: false
> +addresses:
> 

Re: [Cloud-init-dev] [Merge] ~raharper/cloud-init:rebased-netconfig-v2-passthrough into cloud-init:master

2017-03-19 Thread Server Team CI bot
Review: Needs Fixing continuous-integration

FAILED: Continuous integration, rev:c43f407e2ac41e3e474dbfd023fc6325919819a9
https://jenkins.ubuntu.com/server/job/cloud-init-ci/139/
Executed test runs:
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-amd64/139/console
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-arm64/139/console
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-ppc64el/139/console
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=metal-s390x/139/console
FAILURE: 
https://jenkins.ubuntu.com/server/job/cloud-init-ci/nodes=vm-i386/139/console

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/139/rebuild

-- 
https://code.launchpad.net/~raharper/cloud-init/+git/cloud-init/+merge/320291
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.

___
Mailing list: https://launchpad.net/~cloud-init-dev
Post to : cloud-init-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~cloud-init-dev
More help   : https://help.launchpad.net/ListHelp


[Cloud-init-dev] [Merge] ~raharper/cloud-init:rebased-netconfig-v2-passthrough into cloud-init:master

2017-03-19 Thread Ryan Harper
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':