diff --git a/0001-Make-tests-work-with-Python-3.8-139.patch b/0001-Make-tests-work-with-Python-3.8-139.patch deleted file mode 100644 index c4d8f7b..0000000 --- a/0001-Make-tests-work-with-Python-3.8-139.patch +++ /dev/null @@ -1,104 +0,0 @@ -From c5a7d7979c036f6dc6823f429c6b6820f7f74241 Mon Sep 17 00:00:00 2001 -From: Conrad Hoffmann <1226676+bitfehler@users.noreply.github.com> -Date: Wed, 8 Jan 2020 15:18:48 +0100 -Subject: [PATCH] Make tests work with Python 3.8 (#139) - -* Make DistroChecker test work with Python 3.8 - -In Python 3.8, `platform.linux_distribution` has been removed. This was -anticipated, and the cloud-init code uses its own -`util.get_linux_distro` instead, which works fine w/o -`platform.linux_distribution`. However, these tests still try to mock -the platform function, which fails if it doesn't exist (Python 3.8). -Instead, mock the new function here, as this is a test for code that -depends on it rather than the function itself. - -* Make GetLinuxDistro tests work with Python 3.8 - -In Python 3.8, `platform.dist` was removed, so allow mock to create the -function by setting `create=True`. - -* Make linter happy in Python 3.8 - -Suppress E1101(no-member) as this function was removed. ---- - cloudinit/analyze/tests/test_boot.py | 8 ++++---- - cloudinit/tests/test_util.py | 6 +++--- - cloudinit/util.py | 4 ++-- - 3 files changed, 9 insertions(+), 9 deletions(-) - -diff --git a/cloudinit/analyze/tests/test_boot.py b/cloudinit/analyze/tests/test_boot.py -index 706e2cc0..f4001c14 100644 ---- a/cloudinit/analyze/tests/test_boot.py -+++ b/cloudinit/analyze/tests/test_boot.py -@@ -12,17 +12,17 @@ class TestDistroChecker(CiTestCase): - @mock.patch('cloudinit.util.system_info', return_value={'dist': ('', '', - ''), - 'system': ''}) -- @mock.patch('platform.linux_distribution', return_value=('', '', '')) -+ @mock.patch('cloudinit.util.get_linux_distro', return_value=('', '', '')) - @mock.patch('cloudinit.util.is_FreeBSD', return_value=False) -- def test_blank_distro(self, m_sys_info, m_linux_distribution, m_free_bsd): -+ def test_blank_distro(self, m_sys_info, m_get_linux_distro, m_free_bsd): - self.assertEqual(err_code, dist_check_timestamp()) - - @mock.patch('cloudinit.util.system_info', return_value={'dist': ('', '', - '')}) -- @mock.patch('platform.linux_distribution', return_value=('', '', '')) -+ @mock.patch('cloudinit.util.get_linux_distro', return_value=('', '', '')) - @mock.patch('cloudinit.util.is_FreeBSD', return_value=True) - def test_freebsd_gentoo_cant_find(self, m_sys_info, -- m_linux_distribution, m_is_FreeBSD): -+ m_get_linux_distro, m_is_FreeBSD): - self.assertEqual(err_code, dist_check_timestamp()) - - @mock.patch('cloudinit.util.subp', return_value=(0, 1)) -diff --git a/cloudinit/tests/test_util.py b/cloudinit/tests/test_util.py -index 64ed82ea..be100646 100644 ---- a/cloudinit/tests/test_util.py -+++ b/cloudinit/tests/test_util.py -@@ -523,7 +523,7 @@ class TestGetLinuxDistro(CiTestCase): - self.assertEqual( - ('opensuse-tumbleweed', '20180920', platform.machine()), dist) - -- @mock.patch('platform.dist') -+ @mock.patch('platform.dist', create=True) - def test_get_linux_distro_no_data(self, m_platform_dist, m_path_exists): - """Verify we get no information if os-release does not exist""" - m_platform_dist.return_value = ('', '', '') -@@ -531,7 +531,7 @@ class TestGetLinuxDistro(CiTestCase): - dist = util.get_linux_distro() - self.assertEqual(('', '', ''), dist) - -- @mock.patch('platform.dist') -+ @mock.patch('platform.dist', create=True) - def test_get_linux_distro_no_impl(self, m_platform_dist, m_path_exists): - """Verify we get an empty tuple when no information exists and - Exceptions are not propagated""" -@@ -540,7 +540,7 @@ class TestGetLinuxDistro(CiTestCase): - dist = util.get_linux_distro() - self.assertEqual(('', '', ''), dist) - -- @mock.patch('platform.dist') -+ @mock.patch('platform.dist', create=True) - def test_get_linux_distro_plat_data(self, m_platform_dist, m_path_exists): - """Verify we get the correct platform information""" - m_platform_dist.return_value = ('foo', '1.1', 'aarch64') -diff --git a/cloudinit/util.py b/cloudinit/util.py -index 9d9d5c72..830c8e54 100644 ---- a/cloudinit/util.py -+++ b/cloudinit/util.py -@@ -635,8 +635,8 @@ def get_linux_distro(): - else: - dist = ('', '', '') - try: -- # Will be removed in 3.7 -- dist = platform.dist() # pylint: disable=W1505 -+ # Was removed in 3.8 -+ dist = platform.dist() # pylint: disable=W1505,E1101 - except Exception: - pass - finally: --- -2.24.1 - diff --git a/cloud-init-19.4.tar.gz b/cloud-init-19.4.tar.gz deleted file mode 100644 index b560ef2..0000000 --- a/cloud-init-19.4.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a2c1f318cbfb28c13b41bbb0de5ab9b21d7cf4b7118551366cd508380124f262 -size 1091893 diff --git a/cloud-init-20.2.tar.gz b/cloud-init-20.2.tar.gz new file mode 100644 index 0000000..21da909 --- /dev/null +++ b/cloud-init-20.2.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6729e9093f8252bff44a94ddc814256da6143456929b6731e9b74642cd57e971 +size 1117084 diff --git a/cloud-init-after-kvp.diff b/cloud-init-after-kvp.diff new file mode 100644 index 0000000..00dce8e --- /dev/null +++ b/cloud-init-after-kvp.diff @@ -0,0 +1,12 @@ +diff --git a/systemd/cloud-init-local.service.tmpl b/systemd/cloud-init-local.service.tmpl +index ff9c644d..7166f640 100644 +--- a/systemd/cloud-init-local.service.tmpl ++++ b/systemd/cloud-init-local.service.tmpl +@@ -5,6 +5,7 @@ Description=Initial cloud-init job (pre-networking) + DefaultDependencies=no + {% endif %} + Wants=network-pre.target ++After=hv_kvp_daemon.service + After=systemd-remount-fs.service + Before=NetworkManager.service + Before=network-pre.target diff --git a/cloud-init-long-pass.patch b/cloud-init-long-pass.patch deleted file mode 100644 index 08fa87c..0000000 --- a/cloud-init-long-pass.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- cloudinit/config/cc_set_passwords.py.orig -+++ cloudinit/config/cc_set_passwords.py -@@ -236,7 +236,7 @@ def handle(_name, cfg, cloud, log, args) - raise errors[-1] - - --def rand_user_password(pwlen=9): -+def rand_user_password(pwlen=20): - return util.rand_str(pwlen, select_from=PW_SET) - - diff --git a/cloud-init-mix-static-dhcp.patch b/cloud-init-mix-static-dhcp.patch deleted file mode 100644 index 48f0a6f..0000000 --- a/cloud-init-mix-static-dhcp.patch +++ /dev/null @@ -1,1660 +0,0 @@ -From 263d8be627431001b8fd27d520340f280ed2d5f9 Mon Sep 17 00:00:00 2001 -From: Robert Schweikert -Date: Thu, 9 Jan 2020 14:47:46 -0500 -Subject: [PATCH] - Handle different values for the common BOOTPROTO - configuration option + Introduce the "flavor" configuration option for the - sysconfig renderer this is necessary to account for differences in the - handling of the BOOTPROTO setting between distributions (lp#1858808) + - Thanks to Petr Pavlu for the idea - Network config clean up for sysconfig - renderer + The introduction of the "flavor" renderer configuration allows - us to only write values that are pertinent for the given distro - Set the - DHCPv6 client mode on SUSE (lp#1800854) - ---- - cloudinit/distros/opensuse.py | 1 + - cloudinit/net/sysconfig.py | 295 ++++++++++++------ - tests/unittests/test_distros/test_netconfig.py | 39 +-- - tests/unittests/test_net.py | 405 +++++++++++++++---------- - 4 files changed, 450 insertions(+), 290 deletions(-) - ---- cloudinit/distros/opensuse.py.orig -+++ cloudinit/distros/opensuse.py -@@ -38,6 +38,7 @@ class Distro(distros.Distro): - renderer_configs = { - 'sysconfig': { - 'control': 'etc/sysconfig/network/config', -+ 'flavor': 'suse', - 'iface_templates': '%(base)s/network/ifcfg-%(name)s', - 'netrules_path': ( - 'etc/udev/rules.d/85-persistent-net-cloud-init.rules'), ---- cloudinit/net/sysconfig.py.orig -+++ cloudinit/net/sysconfig.py -@@ -86,6 +86,9 @@ class ConfigMap(object): - def __getitem__(self, key): - return self._conf[key] - -+ def get(self, key): -+ return self._conf.get(key, None) -+ - def __contains__(self, key): - return key in self._conf - -@@ -269,11 +272,15 @@ class Renderer(renderer.Renderer): - # s1-networkscripts-interfaces.html (or other docs for - # details about this) - -- iface_defaults = tuple([ -+ iface_defaults_rh = tuple([ - ('ONBOOT', True), - ('USERCTL', False), - ('NM_CONTROLLED', False), - ('BOOTPROTO', 'none'), -+ ]) -+ -+ iface_defaults_suse = tuple([ -+ ('BOOTPROTO', 'static'), - ('STARTMODE', 'auto'), - ]) - -@@ -297,12 +304,18 @@ class Renderer(renderer.Renderer): - ('bond_primary_reselect', "primary_reselect=%s"), - ]) - -- bridge_opts_keys = tuple([ -+ bridge_opts_keys_rh = tuple([ - ('bridge_stp', 'STP'), - ('bridge_ageing', 'AGEING'), - ('bridge_bridgeprio', 'PRIO'), - ]) - -+ bridge_opts_keys_suse = tuple([ -+ ('bridge_stp', 'BRIDGE_STP'), -+ ('bridge_ageing', 'BRIDGE_AGEINGTIME'), -+ ('bridge_bridgeprio', 'BRIDGE_PRIORITY'), -+ ]) -+ - templates = {} - - def __init__(self, config=None): -@@ -320,13 +333,21 @@ class Renderer(renderer.Renderer): - 'iface_templates': config.get('iface_templates'), - 'route_templates': config.get('route_templates'), - } -+ self.flavor = config.get('flavor', 'rh') - - @classmethod -- def _render_iface_shared(cls, iface, iface_cfg): -- for k, v in cls.iface_defaults: -+ def _render_iface_shared(cls, iface, iface_cfg, flavor): -+ if flavor == 'suse': -+ iface_defaults = cls.iface_defaults_suse -+ mac_map = ('mac_address', 'LLADDR') -+ else: -+ iface_defaults = cls.iface_defaults_rh -+ mac_map = ('mac_address', 'HWADDR') -+ -+ for k, v in iface_defaults: - iface_cfg[k] = v - -- for (old_key, new_key) in [('mac_address', 'HWADDR'), ('mtu', 'MTU')]: -+ for (old_key, new_key) in [mac_map, ('mtu', 'MTU')]: - old_value = iface.get(old_key) - if old_value is not None: - # only set HWADDR on physical interfaces -@@ -335,50 +356,86 @@ class Renderer(renderer.Renderer): - continue - iface_cfg[new_key] = old_value - -- if iface['accept-ra'] is not None: -+ if iface['accept-ra'] is not None and flavor != 'suse': - iface_cfg['IPV6_FORCE_ACCEPT_RA'] = iface['accept-ra'] - - @classmethod -- def _render_subnets(cls, iface_cfg, subnets, has_default_route): -+ def _render_subnets(cls, iface_cfg, subnets, has_default_route, flavor): - # setting base values -- iface_cfg['BOOTPROTO'] = 'none' -+ if flavor == 'suse': -+ iface_cfg['BOOTPROTO'] = 'static' -+ if 'BRIDGE' in iface_cfg: -+ iface_cfg['BOOTPROTO'] = 'dhcp' -+ iface_cfg.drop('BRIDGE') -+ else: -+ iface_cfg['BOOTPROTO'] = 'none' - - # modifying base values according to subnets - for i, subnet in enumerate(subnets, start=len(iface_cfg.children)): - mtu_key = 'MTU' - subnet_type = subnet.get('type') - if subnet_type == 'dhcp6' or subnet_type == 'ipv6_dhcpv6-stateful': -- # TODO need to set BOOTPROTO to dhcp6 on SUSE -- iface_cfg['IPV6INIT'] = True -- # Configure network settings using DHCPv6 -- iface_cfg['DHCPV6C'] = True -+ if flavor == 'suse': -+ # User wants dhcp for both protocols -+ if iface_cfg['BOOTPROTO'] == 'dhcp4': -+ iface_cfg['BOOTPROTO'] = 'dhcp' -+ else: -+ # Only IPv6 is DHCP, IPv4 may be static -+ iface_cfg['BOOTPROTO'] = 'dhcp6' -+ iface_cfg['DHCLIENT6_MODE'] = 'managed' -+ else: -+ iface_cfg['IPV6INIT'] = True -+ # Configure network settings using DHCPv6 -+ iface_cfg['DHCPV6C'] = True - elif subnet_type == 'ipv6_dhcpv6-stateless': -- iface_cfg['IPV6INIT'] = True -- # Configure network settings using SLAAC from RAs and optional -- # info from dhcp server using DHCPv6 -- iface_cfg['IPV6_AUTOCONF'] = True -- iface_cfg['DHCPV6C'] = True -- # Use Information-request to get only stateless configuration -- # parameters (i.e., without address). -- iface_cfg['DHCPV6C_OPTIONS'] = '-S' -+ if flavor == 'suse': -+ # User wants dhcp for both protocols -+ if iface_cfg['BOOTPROTO'] == 'dhcp4': -+ iface_cfg['BOOTPROTO'] = 'dhcp' -+ else: -+ # Only IPv6 is DHCP, IPv4 may be static -+ iface_cfg['BOOTPROTO'] = 'dhcp6' -+ iface_cfg['DHCLIENT6_MODE'] = 'info' -+ else: -+ iface_cfg['IPV6INIT'] = True -+ # Configure network settings using SLAAC from RAs and -+ # optional info from dhcp server using DHCPv6 -+ iface_cfg['IPV6_AUTOCONF'] = True -+ iface_cfg['DHCPV6C'] = True -+ # Use Information-request to get only stateless -+ # configuration parameters (i.e., without address). -+ iface_cfg['DHCPV6C_OPTIONS'] = '-S' - elif subnet_type == 'ipv6_slaac': -- iface_cfg['IPV6INIT'] = True -- # Configure network settings using SLAAC from RAs -- iface_cfg['IPV6_AUTOCONF'] = True -+ if flavor == 'suse': -+ # User wants dhcp for both protocols -+ if iface_cfg['BOOTPROTO'] == 'dhcp4': -+ iface_cfg['BOOTPROTO'] = 'dhcp' -+ else: -+ # Only IPv6 is DHCP, IPv4 may be static -+ iface_cfg['BOOTPROTO'] = 'dhcp6' -+ iface_cfg['DHCLIENT6_MODE'] = 'info' -+ else: -+ iface_cfg['IPV6INIT'] = True -+ # Configure network settings using SLAAC from RAs -+ iface_cfg['IPV6_AUTOCONF'] = True - elif subnet_type in ['dhcp4', 'dhcp']: -+ bootproto_in = iface_cfg['BOOTPROTO'] - iface_cfg['BOOTPROTO'] = 'dhcp' -+ if flavor == 'suse' and subnet_type == 'dhcp4': -+ # If dhcp6 is already specified the user wants dhcp -+ # for both protocols -+ if bootproto_in != 'dhcp6': -+ # Only IPv4 is DHCP, IPv6 may be static -+ iface_cfg['BOOTPROTO'] = 'dhcp4' - elif subnet_type == 'static': -+ # RH info - # grep BOOTPROTO sysconfig.txt -A2 | head -3 - # BOOTPROTO=none|bootp|dhcp - # 'bootp' or 'dhcp' cause a DHCP client - # to run on the device. Any other - # value causes any static configuration - # in the file to be applied. -- # ==> the following should not be set to 'static' -- # but should remain 'none' -- # if iface_cfg['BOOTPROTO'] == 'none': -- # iface_cfg['BOOTPROTO'] = 'static' -- if subnet_is_ipv6(subnet): -+ if subnet_is_ipv6(subnet) and flavor != 'suse': - mtu_key = 'IPV6_MTU' - iface_cfg['IPV6INIT'] = True - if 'mtu' in subnet: -@@ -389,18 +446,31 @@ class Renderer(renderer.Renderer): - 'Network config: ignoring %s device-level mtu:%s' - ' because ipv4 subnet-level mtu:%s provided.', - iface_cfg.name, iface_cfg[mtu_key], subnet['mtu']) -- iface_cfg[mtu_key] = subnet['mtu'] -+ if subnet_is_ipv6(subnet): -+ if flavor == 'suse': -+ # TODO(rjschwei) write mtu setting to -+ # /etc/sysctl.d/ -+ pass -+ else: -+ iface_cfg[mtu_key] = subnet['mtu'] -+ else: -+ iface_cfg[mtu_key] = subnet['mtu'] - elif subnet_type == 'manual': -- # If the subnet has an MTU setting, then ONBOOT=True -- # to apply the setting -- iface_cfg['ONBOOT'] = mtu_key in iface_cfg -+ if flavor == 'suse': -+ LOG.debug('Unknown subnet type setting "%s"', subnet_type) -+ else: -+ # If the subnet has an MTU setting, then ONBOOT=True -+ # to apply the setting -+ iface_cfg['ONBOOT'] = mtu_key in iface_cfg - else: - raise ValueError("Unknown subnet type '%s' found" - " for interface '%s'" % (subnet_type, - iface_cfg.name)) - if subnet.get('control') == 'manual': -- iface_cfg['ONBOOT'] = False -- iface_cfg['STARTMODE'] = 'manual' -+ if flavor == 'suse': -+ iface_cfg['STARTMODE'] = 'manual' -+ else: -+ iface_cfg['ONBOOT'] = False - - # set IPv4 and IPv6 static addresses - ipv4_index = -1 -@@ -409,13 +479,14 @@ class Renderer(renderer.Renderer): - subnet_type = subnet.get('type') - # metric may apply to both dhcp and static config - if 'metric' in subnet: -- iface_cfg['METRIC'] = subnet['metric'] -- # TODO(hjensas): Including dhcp6 here is likely incorrect. DHCPv6 -- # does not ever provide a default gateway, the default gateway -- # come from RA's. (https://github.com/openSUSE/wicked/issues/570) -- if subnet_type in ['dhcp', 'dhcp4', 'dhcp6']: -- if has_default_route and iface_cfg['BOOTPROTO'] != 'none': -- iface_cfg['DHCLIENT_SET_DEFAULT_ROUTE'] = False -+ if flavor != 'suse': -+ iface_cfg['METRIC'] = subnet['metric'] -+ if subnet_type in ['dhcp', 'dhcp4']: -+ # On SUSE distros 'DHCLIENT_SET_DEFAULT_ROUTE' is a global -+ # setting in /etc/sysconfig/network/dhcp -+ if flavor != 'suse': -+ if has_default_route and iface_cfg['BOOTPROTO'] != 'none': -+ iface_cfg['DHCLIENT_SET_DEFAULT_ROUTE'] = False - continue - elif subnet_type in IPV6_DYNAMIC_TYPES: - continue -@@ -424,14 +495,21 @@ class Renderer(renderer.Renderer): - ipv6_index = ipv6_index + 1 - ipv6_cidr = "%s/%s" % (subnet['address'], subnet['prefix']) - if ipv6_index == 0: -- iface_cfg['IPV6ADDR'] = ipv6_cidr -- iface_cfg['IPADDR6'] = ipv6_cidr -+ if flavor == 'suse': -+ iface_cfg['IPADDR6'] = ipv6_cidr -+ else: -+ iface_cfg['IPV6ADDR'] = ipv6_cidr - elif ipv6_index == 1: -- iface_cfg['IPV6ADDR_SECONDARIES'] = ipv6_cidr -- iface_cfg['IPADDR6_0'] = ipv6_cidr -+ if flavor == 'suse': -+ iface_cfg['IPADDR6_1'] = ipv6_cidr -+ else: -+ iface_cfg['IPV6ADDR_SECONDARIES'] = ipv6_cidr - else: -- iface_cfg['IPV6ADDR_SECONDARIES'] += " " + ipv6_cidr -- iface_cfg['IPADDR6_%d' % ipv6_index] = ipv6_cidr -+ if flavor == 'suse': -+ iface_cfg['IPADDR6_%d' % ipv6_index] = ipv6_cidr -+ else: -+ iface_cfg['IPV6ADDR_SECONDARIES'] += \ -+ " " + ipv6_cidr - else: - ipv4_index = ipv4_index + 1 - suff = "" if ipv4_index == 0 else str(ipv4_index) -@@ -439,17 +517,17 @@ class Renderer(renderer.Renderer): - iface_cfg['NETMASK' + suff] = \ - net_prefix_to_ipv4_mask(subnet['prefix']) - -- if 'gateway' in subnet: -+ if 'gateway' in subnet and flavor != 'suse': - iface_cfg['DEFROUTE'] = True - if is_ipv6_addr(subnet['gateway']): - iface_cfg['IPV6_DEFAULTGW'] = subnet['gateway'] - else: - iface_cfg['GATEWAY'] = subnet['gateway'] - -- if 'dns_search' in subnet: -+ if 'dns_search' in subnet and flavor != 'suse': - iface_cfg['DOMAIN'] = ' '.join(subnet['dns_search']) - -- if 'dns_nameservers' in subnet: -+ if 'dns_nameservers' in subnet and flavor != 'suse': - if len(subnet['dns_nameservers']) > 3: - # per resolv.conf(5) MAXNS sets this to 3. - LOG.debug("%s has %d entries in dns_nameservers. " -@@ -459,7 +537,12 @@ class Renderer(renderer.Renderer): - iface_cfg['DNS' + str(i)] = k - - @classmethod -- def _render_subnet_routes(cls, iface_cfg, route_cfg, subnets): -+ def _render_subnet_routes(cls, iface_cfg, route_cfg, subnets, flavor): -+ # TODO(rjschwei): route configuration on SUSE distro happens via -+ # ifroute-* files, see lp#1812117. SUSE currently carries a local -+ # patch in their package. -+ if flavor == 'suse': -+ return - for _, subnet in enumerate(subnets, start=len(iface_cfg.children)): - subnet_type = subnet.get('type') - for route in subnet.get('routes', []): -@@ -487,14 +570,7 @@ class Renderer(renderer.Renderer): - # TODO(harlowja): add validation that no other iface has - # also provided the default route? - iface_cfg['DEFROUTE'] = True -- # TODO(hjensas): Including dhcp6 here is likely incorrect. -- # DHCPv6 does not ever provide a default gateway, the -- # default gateway come from RA's. -- # (https://github.com/openSUSE/wicked/issues/570) -- if iface_cfg['BOOTPROTO'] in ('dhcp', 'dhcp4', 'dhcp6'): -- # NOTE(hjensas): DHCLIENT_SET_DEFAULT_ROUTE is SuSE -- # only. RHEL, CentOS, Fedora does not implement this -- # option. -+ if iface_cfg['BOOTPROTO'] in ('dhcp', 'dhcp4'): - iface_cfg['DHCLIENT_SET_DEFAULT_ROUTE'] = True - if 'gateway' in route: - if is_ipv6: -@@ -538,7 +614,9 @@ class Renderer(renderer.Renderer): - iface_cfg['BONDING_OPTS'] = " ".join(bond_opts) - - @classmethod -- def _render_physical_interfaces(cls, network_state, iface_contents): -+ def _render_physical_interfaces( -+ cls, network_state, iface_contents, flavor -+ ): - physical_filter = renderer.filter_by_physical - for iface in network_state.iter_interfaces(physical_filter): - iface_name = iface['name'] -@@ -547,12 +625,15 @@ class Renderer(renderer.Renderer): - route_cfg = iface_cfg.routes - - cls._render_subnets( -- iface_cfg, iface_subnets, network_state.has_default_route -+ iface_cfg, iface_subnets, network_state.has_default_route, -+ flavor -+ ) -+ cls._render_subnet_routes( -+ iface_cfg, route_cfg, iface_subnets, flavor - ) -- cls._render_subnet_routes(iface_cfg, route_cfg, iface_subnets) - - @classmethod -- def _render_bond_interfaces(cls, network_state, iface_contents): -+ def _render_bond_interfaces(cls, network_state, iface_contents, flavor): - bond_filter = renderer.filter_by_type('bond') - slave_filter = renderer.filter_by_attr('bond-master') - for iface in network_state.iter_interfaces(bond_filter): -@@ -566,17 +647,24 @@ class Renderer(renderer.Renderer): - master_cfgs.extend(iface_cfg.children) - for master_cfg in master_cfgs: - master_cfg['BONDING_MASTER'] = True -- master_cfg.kind = 'bond' -+ if flavor != 'suse': -+ master_cfg.kind = 'bond' - - if iface.get('mac_address'): -- iface_cfg['MACADDR'] = iface.get('mac_address') -+ if flavor == 'suse': -+ iface_cfg['LLADDR'] = iface.get('mac_address') -+ else: -+ iface_cfg['MACADDR'] = iface.get('mac_address') - - iface_subnets = iface.get("subnets", []) - route_cfg = iface_cfg.routes - cls._render_subnets( -- iface_cfg, iface_subnets, network_state.has_default_route -+ iface_cfg, iface_subnets, network_state.has_default_route, -+ flavor -+ ) -+ cls._render_subnet_routes( -+ iface_cfg, route_cfg, iface_subnets, flavor - ) -- cls._render_subnet_routes(iface_cfg, route_cfg, iface_subnets) - - # iter_interfaces on network-state is not sorted to produce - # consistent numbers we need to sort. -@@ -586,28 +674,44 @@ class Renderer(renderer.Renderer): - if slave_iface['bond-master'] == iface_name]) - - for index, bond_slave in enumerate(bond_slaves): -- slavestr = 'BONDING_SLAVE%s' % index -+ if flavor == 'suse': -+ slavestr = 'BONDING_SLAVE_%s' % index -+ else: -+ slavestr = 'BONDING_SLAVE%s' % index - iface_cfg[slavestr] = bond_slave - - slave_cfg = iface_contents[bond_slave] -- slave_cfg['MASTER'] = iface_name -- slave_cfg['SLAVE'] = True -+ if flavor == 'suse': -+ slave_cfg['BOOTPROTO'] = 'none' -+ slave_cfg['STARTMODE'] = 'hotplug' -+ else: -+ slave_cfg['MASTER'] = iface_name -+ slave_cfg['SLAVE'] = True - - @classmethod -- def _render_vlan_interfaces(cls, network_state, iface_contents): -+ def _render_vlan_interfaces(cls, network_state, iface_contents, flavor): - vlan_filter = renderer.filter_by_type('vlan') - for iface in network_state.iter_interfaces(vlan_filter): - iface_name = iface['name'] - iface_cfg = iface_contents[iface_name] -- iface_cfg['VLAN'] = True -- iface_cfg['PHYSDEV'] = iface_name[:iface_name.rfind('.')] -+ if flavor == 'suse': -+ vlan_id = iface.get('vlan_id') -+ if vlan_id: -+ iface_cfg['VLAN_ID'] = vlan_id -+ iface_cfg['ETHERDEVICE'] = iface_name[:iface_name.rfind('.')] -+ else: -+ iface_cfg['VLAN'] = True -+ iface_cfg['PHYSDEV'] = iface_name[:iface_name.rfind('.')] - - iface_subnets = iface.get("subnets", []) - route_cfg = iface_cfg.routes - cls._render_subnets( -- iface_cfg, iface_subnets, network_state.has_default_route -+ iface_cfg, iface_subnets, network_state.has_default_route, -+ flavor -+ ) -+ cls._render_subnet_routes( -+ iface_cfg, route_cfg, iface_subnets, flavor - ) -- cls._render_subnet_routes(iface_cfg, route_cfg, iface_subnets) - - @staticmethod - def _render_dns(network_state, existing_dns_path=None): -@@ -644,19 +748,39 @@ class Renderer(renderer.Renderer): - return out - - @classmethod -- def _render_bridge_interfaces(cls, network_state, iface_contents): -+ def _render_bridge_interfaces(cls, network_state, iface_contents, flavor): -+ if flavor == 'suse': -+ bridge_opts_keys = cls.bridge_opts_keys_suse -+ else: -+ bridge_opts_keys = cls.bridge_opts_keys_rh - bridge_filter = renderer.filter_by_type('bridge') - for iface in network_state.iter_interfaces(bridge_filter): - iface_name = iface['name'] - iface_cfg = iface_contents[iface_name] -- iface_cfg.kind = 'bridge' -- for old_key, new_key in cls.bridge_opts_keys: -+ if flavor != 'suse': -+ iface_cfg.kind = 'bridge' -+ for old_key, new_key in bridge_opts_keys: - if old_key in iface: - iface_cfg[new_key] = iface[old_key] - -- if iface.get('mac_address'): -- iface_cfg['MACADDR'] = iface.get('mac_address') -+ if flavor == 'suse': -+ if 'BRIDGE_STP' in iface_cfg: -+ if iface_cfg.get('BRIDGE_STP'): -+ iface_cfg['BRIDGE_STP'] = 'on' -+ else: -+ iface_cfg['BRIDGE_STP'] = 'off' - -+ if iface.get('mac_address'): -+ key = 'MACADDR' -+ if flavor == 'suse': -+ key = 'LLADDRESS' -+ iface_cfg[key] = iface.get('mac_address') -+ -+ if flavor == 'suse': -+ if iface.get('bridge_ports', []): -+ iface_cfg['BRIDGE_PORTS'] = '%s' % " ".join( -+ iface.get('bridge_ports') -+ ) - # Is this the right key to get all the connected interfaces? - for bridged_iface_name in iface.get('bridge_ports', []): - # Ensure all bridged interfaces are correctly tagged -@@ -665,17 +789,23 @@ class Renderer(renderer.Renderer): - bridged_cfgs = [bridged_cfg] - bridged_cfgs.extend(bridged_cfg.children) - for bridge_cfg in bridged_cfgs: -- bridge_cfg['BRIDGE'] = iface_name -+ bridge_value = iface_name -+ if flavor == 'suse': -+ bridge_value = 'yes' -+ bridge_cfg['BRIDGE'] = bridge_value - - iface_subnets = iface.get("subnets", []) - route_cfg = iface_cfg.routes - cls._render_subnets( -- iface_cfg, iface_subnets, network_state.has_default_route -+ iface_cfg, iface_subnets, network_state.has_default_route, -+ flavor -+ ) -+ cls._render_subnet_routes( -+ iface_cfg, route_cfg, iface_subnets, flavor - ) -- cls._render_subnet_routes(iface_cfg, route_cfg, iface_subnets) - - @classmethod -- def _render_ib_interfaces(cls, network_state, iface_contents): -+ def _render_ib_interfaces(cls, network_state, iface_contents, flavor): - ib_filter = renderer.filter_by_type('infiniband') - for iface in network_state.iter_interfaces(ib_filter): - iface_name = iface['name'] -@@ -684,12 +814,15 @@ class Renderer(renderer.Renderer): - iface_subnets = iface.get("subnets", []) - route_cfg = iface_cfg.routes - cls._render_subnets( -- iface_cfg, iface_subnets, network_state.has_default_route -+ iface_cfg, iface_subnets, network_state.has_default_route, -+ flavor -+ ) -+ cls._render_subnet_routes( -+ iface_cfg, route_cfg, iface_subnets, flavor - ) -- cls._render_subnet_routes(iface_cfg, route_cfg, iface_subnets) - - @classmethod -- def _render_sysconfig(cls, base_sysconf_dir, network_state, -+ def _render_sysconfig(cls, base_sysconf_dir, network_state, flavor, - templates=None): - '''Given state, return /etc/sysconfig files + contents''' - if not templates: -@@ -700,13 +833,17 @@ class Renderer(renderer.Renderer): - continue - iface_name = iface['name'] - iface_cfg = NetInterface(iface_name, base_sysconf_dir, templates) -- cls._render_iface_shared(iface, iface_cfg) -+ if flavor == 'suse': -+ iface_cfg.drop('DEVICE') -+ # If type detection fails it is considered a bug in SUSE -+ iface_cfg.drop('TYPE') -+ cls._render_iface_shared(iface, iface_cfg, flavor) - iface_contents[iface_name] = iface_cfg -- cls._render_physical_interfaces(network_state, iface_contents) -- cls._render_bond_interfaces(network_state, iface_contents) -- cls._render_vlan_interfaces(network_state, iface_contents) -- cls._render_bridge_interfaces(network_state, iface_contents) -- cls._render_ib_interfaces(network_state, iface_contents) -+ cls._render_physical_interfaces(network_state, iface_contents, flavor) -+ cls._render_bond_interfaces(network_state, iface_contents, flavor) -+ cls._render_vlan_interfaces(network_state, iface_contents, flavor) -+ cls._render_bridge_interfaces(network_state, iface_contents, flavor) -+ cls._render_ib_interfaces(network_state, iface_contents, flavor) - contents = {} - for iface_name, iface_cfg in iface_contents.items(): - if iface_cfg or iface_cfg.children: -@@ -728,7 +865,7 @@ class Renderer(renderer.Renderer): - file_mode = 0o644 - base_sysconf_dir = util.target_path(target, self.sysconf_dir) - for path, data in self._render_sysconfig(base_sysconf_dir, -- network_state, -+ network_state, self.flavor, - templates=templates).items(): - util.write_file(path, data, file_mode) - if self.dns_path: ---- tests/unittests/test_distros/test_netconfig.py.orig -+++ tests/unittests/test_distros/test_netconfig.py -@@ -468,7 +468,6 @@ class TestNetCfgDistroRedhat(TestNetCfgD - NETMASK=255.255.255.0 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -477,7 +476,6 @@ class TestNetCfgDistroRedhat(TestNetCfgD - DEVICE=eth1 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -496,13 +494,11 @@ class TestNetCfgDistroRedhat(TestNetCfgD - BOOTPROTO=none - DEFROUTE=yes - DEVICE=eth0 -- IPADDR6=2607:f0d0:1002:0011::2/64 - IPV6ADDR=2607:f0d0:1002:0011::2/64 - IPV6INIT=yes - IPV6_DEFAULTGW=2607:f0d0:1002:0011::1 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -511,7 +507,6 @@ class TestNetCfgDistroRedhat(TestNetCfgD - DEVICE=eth1 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -556,26 +551,14 @@ class TestNetCfgDistroOpensuse(TestNetCf - """Opensuse uses apply_network_config and renders sysconfig""" - expected_cfgs = { - self.ifcfg_path('eth0'): dedent("""\ -- BOOTPROTO=none -- DEFROUTE=yes -- DEVICE=eth0 -- GATEWAY=192.168.1.254 -+ BOOTPROTO=static - IPADDR=192.168.1.5 - NETMASK=255.255.255.0 -- NM_CONTROLLED=no -- ONBOOT=yes - STARTMODE=auto -- TYPE=Ethernet -- USERCTL=no - """), - self.ifcfg_path('eth1'): dedent("""\ -- BOOTPROTO=dhcp -- DEVICE=eth1 -- NM_CONTROLLED=no -- ONBOOT=yes -+ BOOTPROTO=dhcp4 - STARTMODE=auto -- TYPE=Ethernet -- USERCTL=no - """), - } - self._apply_and_verify(self.distro.apply_network_config, -@@ -586,27 +569,13 @@ class TestNetCfgDistroOpensuse(TestNetCf - """Opensuse uses apply_network_config and renders sysconfig w/ipv6""" - expected_cfgs = { - self.ifcfg_path('eth0'): dedent("""\ -- BOOTPROTO=none -- DEFROUTE=yes -- DEVICE=eth0 -+ BOOTPROTO=static - IPADDR6=2607:f0d0:1002:0011::2/64 -- IPV6ADDR=2607:f0d0:1002:0011::2/64 -- IPV6INIT=yes -- IPV6_DEFAULTGW=2607:f0d0:1002:0011::1 -- NM_CONTROLLED=no -- ONBOOT=yes - STARTMODE=auto -- TYPE=Ethernet -- USERCTL=no - """), - self.ifcfg_path('eth1'): dedent("""\ -- BOOTPROTO=dhcp -- DEVICE=eth1 -- NM_CONTROLLED=no -- ONBOOT=yes -+ BOOTPROTO=dhcp4 - STARTMODE=auto -- TYPE=Ethernet -- USERCTL=no - """), - } - self._apply_and_verify(self.distro.apply_network_config, ---- tests/unittests/test_net.py.orig -+++ tests/unittests/test_net.py -@@ -489,18 +489,11 @@ OS_SAMPLES = [ - """ - # Created by cloud-init on instance boot automatically, do not edit. - # --BOOTPROTO=none --DEFROUTE=yes --DEVICE=eth0 --GATEWAY=172.19.3.254 --HWADDR=fa:16:3e:ed:9a:59 -+BOOTPROTO=static - IPADDR=172.19.1.34 -+LLADDR=fa:16:3e:ed:9a:59 - NETMASK=255.255.252.0 --NM_CONTROLLED=no --ONBOOT=yes - STARTMODE=auto --TYPE=Ethernet --USERCTL=no - """.lstrip()), - ('etc/resolv.conf', - """ -@@ -532,7 +525,6 @@ IPADDR=172.19.1.34 - NETMASK=255.255.252.0 - NM_CONTROLLED=no - ONBOOT=yes --STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """.lstrip()), -@@ -591,20 +583,13 @@ dns = none - """ - # Created by cloud-init on instance boot automatically, do not edit. - # --BOOTPROTO=none --DEFROUTE=yes --DEVICE=eth0 --GATEWAY=172.19.3.254 --HWADDR=fa:16:3e:ed:9a:59 -+BOOTPROTO=static - IPADDR=172.19.1.34 - IPADDR1=10.0.0.10 -+LLADDR=fa:16:3e:ed:9a:59 - NETMASK=255.255.252.0 - NETMASK1=255.255.255.0 --NM_CONTROLLED=no --ONBOOT=yes - STARTMODE=auto --TYPE=Ethernet --USERCTL=no - """.lstrip()), - ('etc/resolv.conf', - """ -@@ -638,7 +623,6 @@ NETMASK=255.255.252.0 - NETMASK1=255.255.255.0 - NM_CONTROLLED=no - ONBOOT=yes --STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """.lstrip()), -@@ -717,25 +701,14 @@ dns = none - """ - # Created by cloud-init on instance boot automatically, do not edit. - # --BOOTPROTO=none --DEFROUTE=yes --DEVICE=eth0 --GATEWAY=172.19.3.254 --HWADDR=fa:16:3e:ed:9a:59 -+BOOTPROTO=static - IPADDR=172.19.1.34 - IPADDR6=2001:DB8::10/64 --IPADDR6_0=2001:DB9::10/64 -+IPADDR6_1=2001:DB9::10/64 - IPADDR6_2=2001:DB10::10/64 --IPV6ADDR=2001:DB8::10/64 --IPV6ADDR_SECONDARIES="2001:DB9::10/64 2001:DB10::10/64" --IPV6INIT=yes --IPV6_DEFAULTGW=2001:DB8::1 -+LLADDR=fa:16:3e:ed:9a:59 - NETMASK=255.255.252.0 --NM_CONTROLLED=no --ONBOOT=yes - STARTMODE=auto --TYPE=Ethernet --USERCTL=no - """.lstrip()), - ('etc/resolv.conf', - """ -@@ -764,9 +737,6 @@ DEVICE=eth0 - GATEWAY=172.19.3.254 - HWADDR=fa:16:3e:ed:9a:59 - IPADDR=172.19.1.34 --IPADDR6=2001:DB8::10/64 --IPADDR6_0=2001:DB9::10/64 --IPADDR6_2=2001:DB10::10/64 - IPV6ADDR=2001:DB8::10/64 - IPV6ADDR_SECONDARIES="2001:DB9::10/64 2001:DB10::10/64" - IPV6INIT=yes -@@ -774,7 +744,6 @@ IPV6_DEFAULTGW=2001:DB8::1 - NETMASK=255.255.252.0 - NM_CONTROLLED=no - ONBOOT=yes --STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """.lstrip()), -@@ -884,14 +853,25 @@ NETWORK_CONFIGS = { - via: 65.61.151.37 - set-name: eth99 - """).rstrip(' '), -- 'expected_sysconfig': { -+ 'expected_sysconfig_opensuse': { -+ 'ifcfg-eth1': textwrap.dedent("""\ -+ BOOTPROTO=static -+ LLADDR=cf:d6:af:48:e8:80 -+ STARTMODE=auto"""), -+ 'ifcfg-eth99': textwrap.dedent("""\ -+ BOOTPROTO=dhcp4 -+ LLADDR=c0:d6:9f:2c:e8:80 -+ IPADDR=192.168.21.3 -+ NETMASK=255.255.255.0 -+ STARTMODE=auto"""), -+ }, -+ 'expected_sysconfig_rhel': { - 'ifcfg-eth1': textwrap.dedent("""\ - BOOTPROTO=none - DEVICE=eth1 - HWADDR=cf:d6:af:48:e8:80 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no"""), - 'ifcfg-eth99': textwrap.dedent("""\ -@@ -909,7 +889,6 @@ NETWORK_CONFIGS = { - METRIC=10000 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no"""), - }, -@@ -1013,18 +992,28 @@ NETWORK_CONFIGS = { - address: 2001:1::1/64 - mtu: 1500 - """).rstrip(' '), -- 'expected_sysconfig': { -+ 'expected_sysconfig_opensuse': { -+ # TODO(rjschwei): what should MTU be, RHEL has 2 for IPv6 and -+ # IPv4 but SUSE only has 1, pick the smaller of the values? -+ 'ifcfg-iface0': textwrap.dedent("""\ -+ BOOTPROTO=static -+ IPADDR=192.168.14.2 -+ IPADDR6=2001:1::1/64 -+ NETMASK=255.255.255.0 -+ STARTMODE=auto -+ MTU=1500 -+ """), -+ }, -+ 'expected_sysconfig_rhel': { - 'ifcfg-iface0': textwrap.dedent("""\ - BOOTPROTO=none - DEVICE=iface0 - IPADDR=192.168.14.2 -- IPADDR6=2001:1::1/64 - IPV6ADDR=2001:1::1/64 - IPV6INIT=yes - NETMASK=255.255.255.0 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - MTU=9000 -@@ -1055,7 +1044,14 @@ NETWORK_CONFIGS = { - subnets: - - {'type': 'dhcp6'} - """).rstrip(' '), -- 'expected_sysconfig': { -+ 'expected_sysconfig_opensuse': { -+ 'ifcfg-iface0': textwrap.dedent("""\ -+ BOOTPROTO=dhcp6 -+ DHCLIENT6_MODE=managed -+ STARTMODE=auto -+ """), -+ }, -+ 'expected_sysconfig_rhel': { - 'ifcfg-iface0': textwrap.dedent("""\ - BOOTPROTO=none - DEVICE=iface0 -@@ -1064,7 +1060,6 @@ NETWORK_CONFIGS = { - DEVICE=iface0 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -1103,7 +1098,14 @@ NETWORK_CONFIGS = { - dhcp6: true - accept-ra: true - """).rstrip(' '), -- 'expected_sysconfig': { -+ 'expected_sysconfig_opensuse': { -+ 'ifcfg-iface0': textwrap.dedent("""\ -+ BOOTPROTO=dhcp6 -+ DHCLIENT6_MODE=managed -+ STARTMODE=auto -+ """), -+ }, -+ 'expected_sysconfig_rhel': { - 'ifcfg-iface0': textwrap.dedent("""\ - BOOTPROTO=none - DEVICE=iface0 -@@ -1113,7 +1115,6 @@ NETWORK_CONFIGS = { - DEVICE=iface0 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -1152,7 +1153,14 @@ NETWORK_CONFIGS = { - dhcp6: true - accept-ra: false - """).rstrip(' '), -- 'expected_sysconfig': { -+ 'expected_sysconfig_opensuse': { -+ 'ifcfg-iface0': textwrap.dedent("""\ -+ BOOTPROTO=dhcp6 -+ DHCLIENT6_MODE=managed -+ STARTMODE=auto -+ """), -+ }, -+ 'expected_sysconfig_rhel': { - 'ifcfg-iface0': textwrap.dedent("""\ - BOOTPROTO=none - DEVICE=iface0 -@@ -1162,7 +1170,6 @@ NETWORK_CONFIGS = { - DEVICE=iface0 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -1192,7 +1199,14 @@ NETWORK_CONFIGS = { - subnets: - - {'type': 'ipv6_slaac'} - """).rstrip(' '), -- 'expected_sysconfig': { -+ 'expected_sysconfig_opensuse': { -+ 'ifcfg-iface0': textwrap.dedent("""\ -+ BOOTPROTO=dhcp6 -+ DHCLIENT6_MODE=managed -+ STARTMODE=auto -+ """), -+ }, -+ 'expected_sysconfig_rhel': { - 'ifcfg-iface0': textwrap.dedent("""\ - BOOTPROTO=none - DEVICE=iface0 -@@ -1201,7 +1215,6 @@ NETWORK_CONFIGS = { - DEVICE=iface0 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -1231,7 +1244,14 @@ NETWORK_CONFIGS = { - subnets: - - {'type': 'ipv6_dhcpv6-stateless'} - """).rstrip(' '), -- 'expected_sysconfig': { -+ 'expected_sysconfig_opensuse': { -+ 'ifcfg-iface0': textwrap.dedent("""\ -+ BOOTPROTO=dhcp6 -+ DHCLIENT6_MODE=managed -+ STARTMODE=auto -+ """), -+ }, -+ 'expected_sysconfig_rhel': { - 'ifcfg-iface0': textwrap.dedent("""\ - BOOTPROTO=none - DEVICE=iface0 -@@ -1242,7 +1262,6 @@ NETWORK_CONFIGS = { - DEVICE=iface0 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -1273,7 +1292,14 @@ NETWORK_CONFIGS = { - - {'type': 'ipv6_dhcpv6-stateful'} - accept-ra: true - """).rstrip(' '), -- 'expected_sysconfig': { -+ 'expected_sysconfig_opensuse': { -+ 'ifcfg-iface0': textwrap.dedent("""\ -+ BOOTPROTO=dhcp6 -+ DHCLIENT6_MODE=managed -+ STARTMODE=auto -+ """), -+ }, -+ 'expected_sysconfig_rhel': { - 'ifcfg-iface0': textwrap.dedent("""\ - BOOTPROTO=none - DEVICE=iface0 -@@ -1283,7 +1309,6 @@ NETWORK_CONFIGS = { - DEVICE=iface0 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -1478,7 +1503,80 @@ pre-down route del -net 10.0.0.0/8 gw 11 - - sacchromyces.maas - - brettanomyces.maas - """).rstrip(' '), -- 'expected_sysconfig': { -+ 'expected_sysconfig_opensuse': { -+ 'ifcfg-bond0': textwrap.dedent("""\ -+ BONDING_MASTER=yes -+ BONDING_OPTS="mode=active-backup """ -+ """xmit_hash_policy=layer3+4 """ -+ """miimon=100" -+ BONDING_SLAVE_0=eth1 -+ BONDING_SLAVE_1=eth2 -+ BOOTPROTO=dhcp6 -+ DHCLIENT6_MODE=managed -+ LLADDR=aa:bb:cc:dd:ee:ff -+ STARTMODE=auto"""), -+ 'ifcfg-bond0.200': textwrap.dedent("""\ -+ BOOTPROTO=dhcp4 -+ ETHERDEVICE=bond0 -+ STARTMODE=auto -+ VLAN_ID=200"""), -+ 'ifcfg-br0': textwrap.dedent("""\ -+ BRIDGE_AGEINGTIME=250 -+ BOOTPROTO=static -+ IPADDR=192.168.14.2 -+ IPADDR6=2001:1::1/64 -+ LLADDRESS=bb:bb:bb:bb:bb:aa -+ NETMASK=255.255.255.0 -+ BRIDGE_PRIORITY=22 -+ BRIDGE_PORTS='eth3 eth4' -+ STARTMODE=auto -+ BRIDGE_STP=off"""), -+ 'ifcfg-eth0': textwrap.dedent("""\ -+ BOOTPROTO=static -+ LLADDR=c0:d6:9f:2c:e8:80 -+ STARTMODE=auto"""), -+ 'ifcfg-eth0.101': textwrap.dedent("""\ -+ BOOTPROTO=static -+ IPADDR=192.168.0.2 -+ IPADDR1=192.168.2.10 -+ MTU=1500 -+ NETMASK=255.255.255.0 -+ NETMASK1=255.255.255.0 -+ ETHERDEVICE=eth0 -+ STARTMODE=auto -+ VLAN_ID=101"""), -+ 'ifcfg-eth1': textwrap.dedent("""\ -+ BOOTPROTO=none -+ LLADDR=aa:d6:9f:2c:e8:80 -+ STARTMODE=hotplug"""), -+ 'ifcfg-eth2': textwrap.dedent("""\ -+ BOOTPROTO=none -+ LLADDR=c0:bb:9f:2c:e8:80 -+ STARTMODE=hotplug"""), -+ 'ifcfg-eth3': textwrap.dedent("""\ -+ BOOTPROTO=static -+ BRIDGE=yes -+ LLADDR=66:bb:9f:2c:e8:80 -+ STARTMODE=auto"""), -+ 'ifcfg-eth4': textwrap.dedent("""\ -+ BOOTPROTO=static -+ BRIDGE=yes -+ LLADDR=98:bb:9f:2c:e8:80 -+ STARTMODE=auto"""), -+ 'ifcfg-eth5': textwrap.dedent("""\ -+ BOOTPROTO=dhcp -+ LLADDR=98:bb:9f:2c:e8:8a -+ STARTMODE=manual"""), -+ 'ifcfg-ib0': textwrap.dedent("""\ -+ BOOTPROTO=static -+ LLADDR=a0:00:02:20:fe:80:00:00:00:00:00:00:ec:0d:9a:03:00:15:e2:c1 -+ IPADDR=192.168.200.7 -+ MTU=9000 -+ NETMASK=255.255.255.0 -+ STARTMODE=auto -+ TYPE=InfiniBand"""), -+ }, -+ 'expected_sysconfig_rhel': { - 'ifcfg-bond0': textwrap.dedent("""\ - BONDING_MASTER=yes - BONDING_OPTS="mode=active-backup """ -@@ -1493,7 +1591,6 @@ pre-down route del -net 10.0.0.0/8 gw 11 - MACADDR=aa:bb:cc:dd:ee:ff - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Bond - USERCTL=no"""), - 'ifcfg-bond0.200': textwrap.dedent("""\ -@@ -1503,7 +1600,6 @@ pre-down route del -net 10.0.0.0/8 gw 11 - NM_CONTROLLED=no - ONBOOT=yes - PHYSDEV=bond0 -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - VLAN=yes"""), -@@ -1513,7 +1609,6 @@ pre-down route del -net 10.0.0.0/8 gw 11 - DEFROUTE=yes - DEVICE=br0 - IPADDR=192.168.14.2 -- IPADDR6=2001:1::1/64 - IPV6ADDR=2001:1::1/64 - IPV6INIT=yes - IPV6_DEFAULTGW=2001:4800:78ff:1b::1 -@@ -1522,7 +1617,6 @@ pre-down route del -net 10.0.0.0/8 gw 11 - NM_CONTROLLED=no - ONBOOT=yes - PRIO=22 -- STARTMODE=auto - STP=no - TYPE=Bridge - USERCTL=no"""), -@@ -1532,7 +1626,6 @@ pre-down route del -net 10.0.0.0/8 gw 11 - HWADDR=c0:d6:9f:2c:e8:80 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no"""), - 'ifcfg-eth0.101': textwrap.dedent("""\ -@@ -1551,7 +1644,6 @@ pre-down route del -net 10.0.0.0/8 gw 11 - NM_CONTROLLED=no - ONBOOT=yes - PHYSDEV=eth0 -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - VLAN=yes"""), -@@ -1562,7 +1654,6 @@ pre-down route del -net 10.0.0.0/8 gw 11 - MASTER=bond0 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - SLAVE=yes - TYPE=Ethernet - USERCTL=no"""), -@@ -1573,7 +1664,6 @@ pre-down route del -net 10.0.0.0/8 gw 11 - MASTER=bond0 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - SLAVE=yes - TYPE=Ethernet - USERCTL=no"""), -@@ -1584,7 +1674,6 @@ pre-down route del -net 10.0.0.0/8 gw 11 - HWADDR=66:bb:9f:2c:e8:80 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no"""), - 'ifcfg-eth4': textwrap.dedent("""\ -@@ -1594,7 +1683,6 @@ pre-down route del -net 10.0.0.0/8 gw 11 - HWADDR=98:bb:9f:2c:e8:80 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no"""), - 'ifcfg-eth5': textwrap.dedent("""\ -@@ -1604,7 +1692,6 @@ pre-down route del -net 10.0.0.0/8 gw 11 - HWADDR=98:bb:9f:2c:e8:8a - NM_CONTROLLED=no - ONBOOT=no -- STARTMODE=manual - TYPE=Ethernet - USERCTL=no"""), - 'ifcfg-ib0': textwrap.dedent("""\ -@@ -1616,7 +1703,6 @@ pre-down route del -net 10.0.0.0/8 gw 11 - NETMASK=255.255.255.0 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=InfiniBand - USERCTL=no"""), - }, -@@ -2012,58 +2098,29 @@ iface bond0 inet6 static - """fail_over_mac=active """ - """primary=bond0s0 """ - """primary_reselect=always" -- BONDING_SLAVE0=bond0s0 -- BONDING_SLAVE1=bond0s1 -- BOOTPROTO=none -- DEFROUTE=yes -- DEVICE=bond0 -- GATEWAY=192.168.0.1 -- MACADDR=aa:bb:cc:dd:e8:ff -+ BONDING_SLAVE_0=bond0s0 -+ BONDING_SLAVE_1=bond0s1 -+ BOOTPROTO=static -+ LLADDR=aa:bb:cc:dd:e8:ff - IPADDR=192.168.0.2 - IPADDR1=192.168.1.2 - IPADDR6=2001:1::1/92 -- IPV6ADDR=2001:1::1/92 -- IPV6INIT=yes - MTU=9000 - NETMASK=255.255.255.0 - NETMASK1=255.255.255.0 -- NM_CONTROLLED=no -- ONBOOT=yes - STARTMODE=auto -- TYPE=Bond -- USERCTL=no - """), - 'ifcfg-bond0s0': textwrap.dedent("""\ - BOOTPROTO=none -- DEVICE=bond0s0 -- HWADDR=aa:bb:cc:dd:e8:00 -- MASTER=bond0 -- NM_CONTROLLED=no -- ONBOOT=yes -- SLAVE=yes -- STARTMODE=auto -- TYPE=Ethernet -- USERCTL=no -- """), -- 'ifroute-bond0': textwrap.dedent("""\ -- ADDRESS0=10.1.3.0 -- GATEWAY0=192.168.0.3 -- NETMASK0=255.255.255.0 -+ LLADDR=aa:bb:cc:dd:e8:00 -+ STARTMODE=hotplug - """), - 'ifcfg-bond0s1': textwrap.dedent("""\ - BOOTPROTO=none -- DEVICE=bond0s1 -- HWADDR=aa:bb:cc:dd:e8:01 -- MASTER=bond0 -- NM_CONTROLLED=no -- ONBOOT=yes -- SLAVE=yes -- STARTMODE=auto -- TYPE=Ethernet -- USERCTL=no -+ LLADDR=aa:bb:cc:dd:e8:01 -+ STARTMODE=hotplug - """), - }, -- - 'expected_sysconfig_rhel': { - 'ifcfg-bond0': textwrap.dedent("""\ - BONDING_MASTER=yes -@@ -2082,7 +2139,6 @@ iface bond0 inet6 static - MACADDR=aa:bb:cc:dd:e8:ff - IPADDR=192.168.0.2 - IPADDR1=192.168.1.2 -- IPADDR6=2001:1::1/92 - IPV6ADDR=2001:1::1/92 - IPV6INIT=yes - MTU=9000 -@@ -2090,7 +2146,6 @@ iface bond0 inet6 static - NETMASK1=255.255.255.0 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Bond - USERCTL=no - """), -@@ -2102,7 +2157,6 @@ iface bond0 inet6 static - NM_CONTROLLED=no - ONBOOT=yes - SLAVE=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -2125,7 +2179,6 @@ iface bond0 inet6 static - NM_CONTROLLED=no - ONBOOT=yes - SLAVE=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -2156,14 +2209,32 @@ iface bond0 inet6 static - netmask: '::' - network: '::' - """), -- 'expected_sysconfig': { -+ 'expected_sysconfig_opensuse': { -+ # TODO RJS: unknown proper BOOTPROTO setting ask Marius -+ 'ifcfg-en0': textwrap.dedent("""\ -+ BOOTPROTO=static -+ LLADDR=aa:bb:cc:dd:e8:00 -+ STARTMODE=auto"""), -+ 'ifcfg-en0.99': textwrap.dedent("""\ -+ BOOTPROTO=static -+ IPADDR=192.168.2.2 -+ IPADDR1=192.168.1.2 -+ IPADDR6=2001:1::bbbb/96 -+ MTU=2222 -+ NETMASK=255.255.255.0 -+ NETMASK1=255.255.255.0 -+ STARTMODE=auto -+ ETHERDEVICE=en0 -+ VLAN_ID=99 -+ """), -+ }, -+ 'expected_sysconfig_rhel': { - 'ifcfg-en0': textwrap.dedent("""\ - BOOTPROTO=none - DEVICE=en0 - HWADDR=aa:bb:cc:dd:e8:00 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no"""), - 'ifcfg-en0.99': textwrap.dedent("""\ -@@ -2173,7 +2244,6 @@ iface bond0 inet6 static - GATEWAY=192.168.1.1 - IPADDR=192.168.2.2 - IPADDR1=192.168.1.2 -- IPADDR6=2001:1::bbbb/96 - IPV6ADDR=2001:1::bbbb/96 - IPV6INIT=yes - IPV6_DEFAULTGW=2001:1::1 -@@ -2183,7 +2253,6 @@ iface bond0 inet6 static - NM_CONTROLLED=no - ONBOOT=yes - PHYSDEV=en0 -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - VLAN=yes"""), -@@ -2216,7 +2285,32 @@ iface bond0 inet6 static - subnets: - - type: static - address: 192.168.2.2/24"""), -- 'expected_sysconfig': { -+ 'expected_sysconfig_opensuse': { -+ 'ifcfg-br0': textwrap.dedent("""\ -+ BOOTPROTO=static -+ IPADDR=192.168.2.2 -+ NETMASK=255.255.255.0 -+ STARTMODE=auto -+ BRIDGE_STP=off -+ BRIDGE_PRIORITY=22 -+ BRIDGE_PORTS='eth0 eth1' -+ """), -+ 'ifcfg-eth0': textwrap.dedent("""\ -+ BOOTPROTO=static -+ BRIDGE=yes -+ LLADDR=52:54:00:12:34:00 -+ IPADDR6=2001:1::100/96 -+ STARTMODE=auto -+ """), -+ 'ifcfg-eth1': textwrap.dedent("""\ -+ BOOTPROTO=static -+ BRIDGE=yes -+ LLADDR=52:54:00:12:34:01 -+ IPADDR6=2001:1::101/96 -+ STARTMODE=auto -+ """), -+ }, -+ 'expected_sysconfig_rhel': { - 'ifcfg-br0': textwrap.dedent("""\ - BOOTPROTO=none - DEVICE=br0 -@@ -2225,7 +2319,6 @@ iface bond0 inet6 static - NM_CONTROLLED=no - ONBOOT=yes - PRIO=22 -- STARTMODE=auto - STP=no - TYPE=Bridge - USERCTL=no -@@ -2235,12 +2328,10 @@ iface bond0 inet6 static - BRIDGE=br0 - DEVICE=eth0 - HWADDR=52:54:00:12:34:00 -- IPADDR6=2001:1::100/96 - IPV6ADDR=2001:1::100/96 - IPV6INIT=yes - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -2249,12 +2340,10 @@ iface bond0 inet6 static - BRIDGE=br0 - DEVICE=eth1 - HWADDR=52:54:00:12:34:01 -- IPADDR6=2001:1::101/96 - IPV6ADDR=2001:1::101/96 - IPV6INIT=yes - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -2320,7 +2409,27 @@ iface bond0 inet6 static - macaddress: 52:54:00:12:34:ff - set-name: eth2 - """), -- 'expected_sysconfig': { -+ 'expected_sysconfig_opensuse': { -+ 'ifcfg-eth0': textwrap.dedent("""\ -+ BOOTPROTO=static -+ LLADDR=52:54:00:12:34:00 -+ IPADDR=192.168.1.2 -+ NETMASK=255.255.255.0 -+ STARTMODE=manual -+ """), -+ 'ifcfg-eth1': textwrap.dedent("""\ -+ BOOTPROTO=static -+ LLADDR=52:54:00:12:34:aa -+ MTU=1480 -+ STARTMODE=auto -+ """), -+ 'ifcfg-eth2': textwrap.dedent("""\ -+ BOOTPROTO=static -+ LLADDR=52:54:00:12:34:ff -+ STARTMODE=manual -+ """), -+ }, -+ 'expected_sysconfig_rhel': { - 'ifcfg-eth0': textwrap.dedent("""\ - BOOTPROTO=none - DEVICE=eth0 -@@ -2329,7 +2438,6 @@ iface bond0 inet6 static - NETMASK=255.255.255.0 - NM_CONTROLLED=no - ONBOOT=no -- STARTMODE=manual - TYPE=Ethernet - USERCTL=no - """), -@@ -2340,7 +2448,6 @@ iface bond0 inet6 static - MTU=1480 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -2350,7 +2457,6 @@ iface bond0 inet6 static - HWADDR=52:54:00:12:34:ff - NM_CONTROLLED=no - ONBOOT=no -- STARTMODE=manual - TYPE=Ethernet - USERCTL=no - """), -@@ -2681,7 +2787,7 @@ class TestRhelSysConfigRendering(CiTestC - header = ('# Created by cloud-init on instance boot automatically, ' - 'do not edit.\n#\n') - -- expected_name = 'expected_sysconfig' -+ expected_name = 'expected_sysconfig_rhel' - - def _get_renderer(self): - distro_cls = distros.fetch('rhel') -@@ -2768,7 +2874,6 @@ DEVICE=eth1000 - HWADDR=07-1c-c6-75-a4-be - NM_CONTROLLED=no - ONBOOT=yes --STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """.lstrip() -@@ -2890,7 +2995,6 @@ IPADDR=10.0.2.15 - NETMASK=255.255.255.0 - NM_CONTROLLED=no - ONBOOT=yes --STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """ -@@ -2922,7 +3026,6 @@ MTU=1500 - NETMASK=255.255.240.0 - NM_CONTROLLED=no - ONBOOT=yes --STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """ -@@ -2937,7 +3040,6 @@ HWADDR=fa:16:3e:b1:ca:29 - MTU=9000 - NM_CONTROLLED=no - ONBOOT=yes --STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """ -@@ -2963,7 +3065,6 @@ BOOTPROTO=dhcp - DEVICE=eth0 - NM_CONTROLLED=no - ONBOOT=yes --STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """ -@@ -2972,10 +3073,9 @@ USERCTL=no - self.assertEqual(resolvconf_content, found['/etc/resolv.conf']) - - def test_bond_config(self): -- expected_name = 'expected_sysconfig_rhel' - entry = NETWORK_CONFIGS['bond'] - found = self._render_and_read(network_config=yaml.load(entry['yaml'])) -- self._compare_files_to_expected(entry[expected_name], found) -+ self._compare_files_to_expected(entry[self.expected_name], found) - self._assert_headers(found) - - def test_vlan_config(self): -@@ -3163,14 +3263,12 @@ USERCTL=no - GATEWAY=192.168.42.1 - HWADDR=52:54:00:ab:cd:ef - IPADDR=192.168.42.100 -- IPADDR6=2001:db8::100/32 - IPV6ADDR=2001:db8::100/32 - IPV6INIT=yes - IPV6_DEFAULTGW=2001:db8::1 - NETMASK=255.255.255.0 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -3196,7 +3294,6 @@ USERCTL=no - DEVICE=eno1 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -3209,7 +3306,6 @@ USERCTL=no - NM_CONTROLLED=no - ONBOOT=yes - PHYSDEV=eno1 -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - VLAN=yes -@@ -3240,7 +3336,6 @@ USERCTL=no - NETMASK=255.255.255.192 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Bond - USERCTL=no - """), -@@ -3252,7 +3347,6 @@ USERCTL=no - NM_CONTROLLED=no - ONBOOT=yes - SLAVE=yes -- STARTMODE=auto - TYPE=Bond - USERCTL=no - """), -@@ -3264,7 +3358,6 @@ USERCTL=no - NM_CONTROLLED=no - ONBOOT=yes - SLAVE=yes -- STARTMODE=auto - TYPE=Bond - USERCTL=no - """) -@@ -3288,7 +3381,6 @@ USERCTL=no - METRIC=100 - NM_CONTROLLED=no - ONBOOT=yes -- STARTMODE=auto - TYPE=Ethernet - USERCTL=no - """), -@@ -3311,7 +3403,7 @@ class TestOpenSuseSysConfigRendering(CiT - header = ('# Created by cloud-init on instance boot automatically, ' - 'do not edit.\n#\n') - -- expected_name = 'expected_sysconfig' -+ expected_name = 'expected_sysconfig_opensuse' - - def _get_renderer(self): - distro_cls = distros.fetch('opensuse') -@@ -3383,19 +3475,17 @@ class TestOpenSuseSysConfigRendering(CiT - expected_content = """ - # Created by cloud-init on instance boot automatically, do not edit. - # --BOOTPROTO=dhcp --DEVICE=eth1000 --HWADDR=07-1c-c6-75-a4-be --NM_CONTROLLED=no --ONBOOT=yes -+BOOTPROTO=dhcp4 -+LLADDR=07-1c-c6-75-a4-be - STARTMODE=auto --TYPE=Ethernet --USERCTL=no - """.lstrip() - self.assertEqual(expected_content, content) - - def test_multiple_ipv4_default_gateways(self): - """ValueError is raised when duplicate ipv4 gateways exist.""" -+ # TODO(rjschwei): re-enable test once route writing is implemented -+ # for SUSE distros -+ return - net_json = { - "services": [{"type": "dns", "address": "172.19.0.12"}], - "networks": [{ -@@ -3434,6 +3524,9 @@ USERCTL=no - - def test_multiple_ipv6_default_gateways(self): - """ValueError is raised when duplicate ipv6 gateways exist.""" -+ # TODO(rjschwei): re-enable test once route writing is implemented -+ # for SUSE distros -+ return - net_json = { - "services": [{"type": "dns", "address": "172.19.0.12"}], - "networks": [{ -@@ -3501,18 +3594,11 @@ USERCTL=no - expected = """\ - # Created by cloud-init on instance boot automatically, do not edit. - # --BOOTPROTO=none --DEFROUTE=yes --DEVICE=interface0 --GATEWAY=10.0.2.2 --HWADDR=52:54:00:12:34:00 -+BOOTPROTO=static - IPADDR=10.0.2.15 -+LLADDR=52:54:00:12:34:00 - NETMASK=255.255.255.0 --NM_CONTROLLED=no --ONBOOT=yes - STARTMODE=auto --TYPE=Ethernet --USERCTL=no - """ - self.assertEqual(expected, found[nspath + 'ifcfg-interface0']) - # The configuration has no nameserver information make sure we -@@ -3537,12 +3623,7 @@ USERCTL=no - # Created by cloud-init on instance boot automatically, do not edit. - # - BOOTPROTO=dhcp --DEVICE=eth0 --NM_CONTROLLED=no --ONBOOT=yes - STARTMODE=auto --TYPE=Ethernet --USERCTL=no - """ - self.assertEqual(expected, found[nspath + 'ifcfg-eth0']) - # a dhcp only config should not modify resolv.conf diff --git a/cloud-init-ostack-metadat-dencode.patch b/cloud-init-ostack-metadat-dencode.patch deleted file mode 100644 index bf4aea7..0000000 --- a/cloud-init-ostack-metadat-dencode.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- cloudinit/sources/helpers/openstack.py.orig -+++ cloudinit/sources/helpers/openstack.py -@@ -291,7 +291,10 @@ class BaseReader(object): - if 'random_seed' in metadata: - random_seed = metadata['random_seed'] - try: -- metadata['random_seed'] = base64.b64decode(random_seed) -+ metadata['random_seed'] = u'%s' % base64.b64decode(random_seed) -+ except UnicodeDecodeError: -+ # Did not decode as expected, probably utf-8 already -+ metadata['random_seed'] = random_seed - except (ValueError, TypeError) as e: - raise BrokenMetadata("Badly formatted metadata" - " random_seed entry: %s" % e) diff --git a/cloud-init-python2-sigpipe.patch b/cloud-init-python2-sigpipe.patch deleted file mode 100644 index be376f1..0000000 --- a/cloud-init-python2-sigpipe.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- cloudinit/util.py.orig -+++ cloudinit/util.py -@@ -35,6 +35,7 @@ import time - from errno import ENOENT, ENOEXEC - - from base64 import b64decode, b64encode -+from signal import signal, SIGPIPE, SIG_DFL - from six.moves.urllib import parse as urlparse - - import six -@@ -2031,7 +2032,8 @@ def subp(args, data=None, rcs=None, env= - try: - sp = subprocess.Popen(bytes_args, stdout=stdout, - stderr=stderr, stdin=stdin, -- env=env, shell=shell) -+ env=env, shell=shell, -+ preexec_fn=lambda: signal(SIGPIPE, SIG_DFL)) - (out, err) = sp.communicate(data) - except OSError as e: - if status_cb: diff --git a/cloud-init-recognize-hpc.patch b/cloud-init-recognize-hpc.patch new file mode 100644 index 0000000..fca89ec --- /dev/null +++ b/cloud-init-recognize-hpc.patch @@ -0,0 +1,13 @@ +--- cloudinit/util.py.orig ++++ cloudinit/util.py +@@ -656,7 +656,9 @@ def system_info(): + elif linux_dist == 'redhat': + var = 'rhel' + elif linux_dist in ( +- 'opensuse', 'opensuse-tumbleweed', 'opensuse-leap', 'sles'): ++ 'opensuse', 'opensuse-tumbleweed', 'opensuse-leap', ++ 'sles', 'sle_hpc' ++ ): + var = 'suse' + else: + var = 'linux' diff --git a/cloud-init-template-py2.patch b/cloud-init-template-py2.patch deleted file mode 100644 index 74e73a7..0000000 --- a/cloud-init-template-py2.patch +++ /dev/null @@ -1,8 +0,0 @@ ---- tools/render-cloudcfg.orig -+++ tools/render-cloudcfg -@@ -1,4 +1,4 @@ --#!/usr/bin/env python3 -+#!/usr/bin/env python - - import argparse - import os diff --git a/cloud-init-use-different-random-src.diff b/cloud-init-use-different-random-src.diff deleted file mode 100644 index bdbe684..0000000 --- a/cloud-init-use-different-random-src.diff +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/cloudinit/util.py b/cloudinit/util.py -index d99e82fa5..c02b3d9a5 100644 ---- a/cloudinit/util.py -+++ b/cloudinit/util.py -@@ -397,9 +397,10 @@ def translate_bool(val, addons=None): - - - def rand_str(strlen=32, select_from=None): -+ r = random.SystemRandom() - if not select_from: - select_from = string.ascii_letters + string.digits -- return "".join([random.choice(select_from) for _x in range(0, strlen)]) -+ return "".join([r.choice(select_from) for _x in range(0, strlen)]) - - - def rand_dict_key(dictionary, postfix=None): diff --git a/cloud-init.changes b/cloud-init.changes index 7847849..b4782ee 100644 --- a/cloud-init.changes +++ b/cloud-init.changes @@ -1,3 +1,202 @@ +------------------------------------------------------------------- +Fri Jul 24 19:55:40 UTC 2020 - Robert Schweikert + +- Update to version 20.2 (bsc#1174443, bsc#1174444) + + Remove patches included upstream: + - 0001-Make-tests-work-with-Python-3.8-139.patch + - cloud-init-ostack-metadat-dencode.patch + - cloud-init-use-different-random-src.diff + - cloud-init-long-pass.patch + - cloud-init-mix-static-dhcp.patch + + Remove patches build switched to Python 3 for all distributions + - cloud-init-python2-sigpipe.patch + - cloud-init-template-py2.patch + + Add + - cloud-init-after-kvp.diff + - cloud-init-recognize-hpc.patch + + doc/format: reference make-mime.py instead of an inline script (#334) + + Add docs about creating parent folders (#330) [Adrian Wilkins] + + DataSourceNoCloud/OVF: drop claim to support FTP (#333) (LP: #1875470) + + schema: ignore spurious pylint error (#332) + + schema: add json schema for write_files module (#152) + + BSD: find_devs_with_ refactoring (#298) [Gonéri Le Bouder] + + nocloud: drop work around for Linux 2.6 (#324) [Gonéri Le Bouder] + + cloudinit: drop dependencies on unittest2 and contextlib2 (#322) + + distros: handle a potential mirror filtering error case (#328) + + log: remove unnecessary import fallback logic (#327) + + .travis.yml: don't run integration test on ubuntu/* branches (#321) + + More unit test documentation (#314) + + conftest: introduce disable_subp_usage autouse fixture (#304) + + YAML align indent sizes for docs readability (#323) [Tak Nishigori] + + network_state: add missing space to log message (#325) + + tests: add missing mocks for get_interfaces_by_mac (#326) (LP: #1873910) + + test_mounts: expand happy path test for both happy paths (#319) + + cc_mounts: fix incorrect format specifiers (#316) (LP: #1872836) + + swap file "size" being used before checked if str (#315) [Eduardo Otubo] + + HACKING.rst: add pytest version gotchas section (#311) + + docs: Add steps to re-run cloud-id and cloud-init (#313) [Joshua Powers] + + readme: OpenBSD is now supported (#309) [Gonéri Le Bouder] + + net: ignore 'renderer' key in netplan config (#306) (LP: #1870421) + + Add support for NFS/EFS mounts (#300) [Andrew Beresford] (LP: #1870370) + + openbsd: set_passwd should not unlock user (#289) [Gonéri Le Bouder] + + tools/.github-cla-signers: add beezly as CLA signer (#301) + + util: remove unnecessary lru_cache import fallback (#299) + + HACKING.rst: reorganise/update CLA signature info (#297) + + distros: drop leading/trailing hyphens from mirror URL labels (#296) + + HACKING.rst: add note about variable annotations (#295) + + CiTestCase: stop using and remove sys_exit helper (#283) + + distros: replace invalid characters in mirror URLs with hyphens (#291) + (LP: #1868232) + + rbxcloud: gracefully handle arping errors (#262) [Adam Dobrawy] + + Fix cloud-init ignoring some misdeclared mimetypes in user-data. + [Kurt Garloff] + + net: ubuntu focal prioritize netplan over eni even if both present + (#267) (LP: #1867029) + + cloudinit: refactor util.is_ipv4 to net.is_ipv4_address (#292) + + net/cmdline: replace type comments with annotations (#294) + + HACKING.rst: add Type Annotations design section (#293) + + net: introduce is_ip_address function (#288) + + CiTestCase: remove now-unneeded parse_and_read helper method (#286) + + .travis.yml: allow 30 minutes of inactivity in cloud tests (#287) + + sources/tests/test_init: drop use of deprecated inspect.getargspec (#285) + + setup.py: drop NIH check_output implementation (#282) + + Identify SAP Converged Cloud as OpenStack [Silvio Knizek] + + add Openbsd support (#147) [Gonéri Le Bouder] + + HACKING.rst: add examples of the two test class types (#278) + + VMWware: support to update guest info gc status if enabled (#261) + [xiaofengw-vmware] + + Add lp-to-git mapping for kgarloff (#279) + + set_passwords: avoid chpasswd on BSD (#268) [Gonéri Le Bouder] + + HACKING.rst: add Unit Testing design section (#277) + + util: read_cc_from_cmdline handle urlencoded yaml content (#275) + + distros/tests/test_init: add tests for _get_package_mirror_info (#272) + + HACKING.rst: add links to new Code Review Process doc (#276) + + freebsd: ensure package update works (#273) [Gonéri Le Bouder] + + doc: introduce Code Review Process documentation (#160) + + tools: use python3 (#274) + + cc_disk_setup: fix RuntimeError (#270) (LP: #1868327) + + cc_apt_configure/util: combine search_for_mirror implementations (#271) + + bsd: boottime does not depend on the libc soname (#269) + [Gonéri Le Bouder] + + test_oracle,DataSourceOracle: sort imports (#266) + + DataSourceOracle: update .network_config docstring (#257) + + cloudinit/tests: remove unneeded with_logs configuration (#263) + + .travis.yml: drop stale comment (#255) + + .gitignore: add more common directories (#258) + + ec2: render network on all NICs and add secondary IPs as static (#114) + (LP: #1866930) + + ec2 json validation: fix the reference to the 'merged_cfg' key (#256) + [Paride Legovini] + + releases.yaml: quote the Ubuntu version numbers (#254) [Paride Legovini] + + cloudinit: remove six from packaging/tooling (#253) + + util/netbsd: drop six usage (#252) + + workflows: introduce stale pull request workflow (#125) + + cc_resolv_conf: introduce tests and stabilise output across Python + versions (#251) + + fix minor issue with resolv_conf template (#144) [andreaf74] + + doc: CloudInit also support NetBSD (#250) [Gonéri Le Bouder] + + Add Netbsd support (#62) [Gonéri Le Bouder] + + tox.ini: avoid substition syntax that causes a traceback on xenial (#245) + + Add pub_key_ed25519 to cc_phone_home (#237) [Daniel Hensby] + + Introduce and use of a list of GitHub usernames that have signed CLA + (#244) + + workflows/cla.yml: use correct username for CLA check (#243) + + tox.ini: use xenial version of jsonpatch in CI (#242) + + workflows: CLA validation altered to fail status on pull_request (#164) + + tox.ini: bump pyflakes version to 2.1.1 (#239) + + cloudinit: move to pytest for running tests (#211) + + instance-data: add cloud-init merged_cfg and sys_info keys to json + (#214) (LP: #1865969) + + ec2: Do not fallback to IMDSv1 on EC2 (#216) + + instance-data: write redacted cfg to instance-data.json (#233) + (LP: #1865947) + + net: support network-config:disabled on the kernel commandline (#232) + (LP: #1862702) + + ec2: only redact token request headers in logs, avoid altering request + (#230) (LP: #1865882) + + docs: typo fixed: dta → data [Alexey Vazhnov] + + Fixes typo on Amazon Web Services (#217) [Nick Wales] + + Fix docs for OpenStack DMI Asset Tag (#228) + [Mark T. Voelker] (LP: #1669875) + + Add physical network type: cascading to openstack helpers (#200) + [sab-systems] + + tests: add focal integration tests for ubuntu (#225) + +- From 20.1 (first vesrion after 19.4) + + ec2: Do not log IMDSv2 token values, instead use REDACTED (#219) + (LP: #1863943) + + utils: use SystemRandom when generating random password. (#204) + [Dimitri John Ledkov] + + docs: mount_default_files is a list of 6 items, not 7 (#212) + + azurecloud: fix issues with instances not starting (#205) (LP: #1861921) + + unittest: fix stderr leak in cc_set_password random unittest + output. (#208) + + cc_disk_setup: add swap filesystem force flag (#207) + + import sysvinit patches from freebsd-ports tree (#161) [Igor Galić] + + docs: fix typo (#195) [Edwin Kofler] + + sysconfig: distro-specific config rendering for BOOTPROTO option (#162) + [Robert Schweikert] (LP: #1800854) + + cloudinit: replace "from six import X" imports (except in util.py) (#183) + + run-container: use 'test -n' instead of 'test ! -z' (#202) + [Paride Legovini] + + net/cmdline: correctly handle static ip= config (#201) + [Dimitri John Ledkov] (LP: #1861412) + + Replace mock library with unittest.mock (#186) + + HACKING.rst: update CLA link (#199) + + Scaleway: Fix DatasourceScaleway to avoid backtrace (#128) + [Louis Bouchard] + + cloudinit/cmd/devel/net_convert.py: add missing space (#191) + + tools/run-container: drop support for python2 (#192) [Paride Legovini] + + Print ssh key fingerprints using sha256 hash (#188) (LP: #1860789) + + Make the RPM build use Python 3 (#190) [Paride Legovini] + + cc_set_password: increase random pwlength from 9 to 20 (#189) + (LP: #1860795) + + .travis.yml: use correct Python version for xenial tests (#185) + + cloudinit: remove ImportError handling for mock imports (#182) + + Do not use fallocate in swap file creation on xfs. (#70) + [Eduardo Otubo] (LP: #1781781) + + .readthedocs.yaml: install cloud-init when building docs (#181) + (LP: #1860450) + + Introduce an RTD config file, and pin the Sphinx version to the RTD + default (#180) + + Drop most of the remaining use of six (#179) + + Start removing dependency on six (#178) + + Add Rootbox & HyperOne to list of cloud in README (#176) [Adam Dobrawy] + + docs: add proposed SRU testing procedure (#167) + + util: rename get_architecture to get_dpkg_architecture (#173) + + Ensure util.get_architecture() runs only once (#172) + + Only use gpart if it is the BSD gpart (#131) [Conrad Hoffmann] + + freebsd: remove superflu exception mapping (#166) [Gonéri Le Bouder] + + ssh_auth_key_fingerprints_disable test: fix capitalization (#165) + [Paride Legovini] + + util: move uptime's else branch into its own boottime function (#53) + [Igor Galić] (LP: #1853160) + + workflows: add contributor license agreement checker (#155) + + net: fix rendering of 'static6' in network config (#77) (LP: #1850988) + + Make tests work with Python 3.8 (#139) [Conrad Hoffmann] + + fixed minor bug with mkswap in cc_disk_setup.py (#143) [andreaf74] + + freebsd: fix create_group() cmd (#146) [Gonéri Le Bouder] + + doc: make apt_update example consistent (#154) + + doc: add modules page toc with links (#153) (LP: #1852456) + + Add support for the amazon variant in cloud.cfg.tmpl (#119) + [Frederick Lefebvre] + + ci: remove Python 2.7 from CI runs (#137) + + modules: drop cc_snap_config config module (#134) + + migrate-lp-user-to-github: ensure Launchpad repo exists (#136) + + docs: add initial troubleshooting to FAQ (#104) [Joshua Powers] + + doc: update cc_set_hostname frequency and descrip (#109) + [Joshua Powers] (LP: #1827021) + + freebsd: introduce the freebsd renderer (#61) [Gonéri Le Bouder] + + cc_snappy: remove deprecated module (#127) + + HACKING.rst: clarify that everyone needs to do the LP->GH dance (#130) + + freebsd: cloudinit service requires devd (#132) [Gonéri Le Bouder] + + cloud-init: fix capitalisation of SSH (#126) + + doc: update cc_ssh clarify host and auth keys + [Joshua Powers] (LP: #1827021) + + ci: emit names of tests run in Travis (#120) + + + ------------------------------------------------------------------- Thu Jun 18 12:11:49 UTC 2020 - Robert Schweikert diff --git a/cloud-init.spec b/cloud-init.spec index 4cb41e9..a0acecd 100644 --- a/cloud-init.spec +++ b/cloud-init.spec @@ -18,7 +18,7 @@ %global configver 0.7 Name: cloud-init -Version: 19.4 +Version: 20.2 Release: 0 License: GPL-3.0 Summary: Cloud node initialization tool @@ -26,35 +26,24 @@ Url: http://launchpad.net/cloud-init/ Group: System/Management Source0: %{name}-%{version}.tar.gz Source1: rsyslog-cloud-init.cfg -Patch0: 0001-Make-tests-work-with-Python-3.8-139.patch -# FIXME -# python2 disables SIGPIPE, causing broken pipe errors in shell scripts (bsc#903449) -Patch20: cloud-init-python2-sigpipe.patch -Patch21: cloud-init-template-py2.patch Patch29: datasourceLocalDisk.patch Patch34: cloud-init-tests-set-exec.patch -# FIXME (lp#1801364) -Patch42: cloud-init-ostack-metadat-dencode.patch # FIXME (lp#1812117) Patch43: cloud-init-write-routes.patch # FIXME (lp#1849296) Patch52: cloud-init-break-resolv-symlink.patch -# FIXME (lp#1858808) -Patch55: cloud-init-mix-static-dhcp.patch # FIXME no proposed solution Patch56: cloud-init-sysconf-path.patch # FIXME (lp#1860164) Patch57: cloud-init-no-tempnet-oci.patch -Patch58: cloud-init-use-different-random-src.diff -Patch59: cloud-init-long-pass.patch - +Patch58: cloud-init-after-kvp.diff +Patch59: cloud-init-recognize-hpc.patch BuildRequires: fdupes BuildRequires: filesystem # pkg-config is needed to find correct systemd unit dir BuildRequires: pkg-config # needed for /lib/udev BuildRequires: pkgconfig(udev) -%if 0%{?suse_version} > 1320 BuildRequires: python3-devel BuildRequires: python3-setuptools # Test requirements @@ -66,16 +55,8 @@ BuildRequires: python3-jsonpatch BuildRequires: python3-mock BuildRequires: python3-nose BuildRequires: python3-oauthlib +BuildRequires: python3-pytest BuildRequires: python3-requests -#BuildRequires: python3-testtools -%else -BuildRequires: python-devel -BuildRequires: python-Jinja2 -BuildRequires: python-PyYAML -BuildRequires: python-requests -BuildRequires: python-setuptools -BuildRequires: python-six -%endif %if 0%{?is_opensuse} BuildRequires: openSUSE-release %else @@ -89,7 +70,6 @@ Requires: growpart Requires: e2fsprogs Requires: net-tools Requires: openssh -%if 0%{?suse_version} > 1320 Requires: python3-configobj >= 5.0.2 Requires: python3-Jinja2 Requires: python3-jsonpatch @@ -101,31 +81,15 @@ Requires: python3-requests Requires: python3-setuptools Requires: python3-six Requires: python3-xml -%else -Requires: python-argparse -Requires: python-configobj >= 5.0.2 -Requires: python-Jinja2 -Requires: python-jsonpatch -Requires: python-jsonschema -Requires: python-oauthlib -Requires: python-pyserial -Requires: python-PyYAML -Requires: python-requests -Requires: python-setuptools -Requires: python-six -Requires: python-xml -%endif Requires: sudo Requires: util-linux +Requires: wicked-service Requires: cloud-init-config = %configver BuildRoot: %{_tmppath}/%{name}-%{version}-build %define docdir %{_defaultdocdir}/%{name} %ifarch %ix86 x86_64 Requires: dmidecode %endif -%if 0%{?suse_version} && 0%{?suse_version} <= 1210 -%define initsys sysvinit_suse -%else %define initsys systemd BuildRequires: pkgconfig(systemd) %{?systemd_requires} @@ -134,12 +98,6 @@ BuildRequires: pkgconfig(systemd) %else %define systemd_prefix /usr/lib %endif -%endif -%if 0%{?suse_version} && 0%{?suse_version} >= 1315 -Requires: wicked-service -%else -Requires: sysconfig-network -%endif %description Cloud-init is an init script that initializes a cloud node (VM) @@ -147,9 +105,9 @@ according to the fetched configuration data from the admin node. %package config-suse Summary: Configuration file for Cloud node initialization tool -Provides: cloud-init-config = %configver +Provides: cloud-init-config = %configver Group: System/Management -Conflicts: otherproviders(cloud-init-config) +Conflicts: otherproviders(cloud-init-config) %description config-suse This package contains the product specific configuration file @@ -166,62 +124,27 @@ according to the fetched configuration data from the admin node. Documentation and examples for cloud-init tools -#%package test -#Summary: Cloud node initialization tool - Testsuite -#Group: System/Management -#Requires: cloud-init = %{version} -# -#%description test -#Cloud-init is an init script that initializes a cloud node (VM) -#according to the fetched configuration data from the admin node. -# -#Unit tests for the cloud-init tools - %prep %setup -q -%patch0 -p1 -%if 0%{?suse_version} < 1315 -%patch20 -%patch21 -%endif %patch29 -p0 %patch34 -%patch42 %patch43 %patch52 -%patch55 -p0 %patch56 %patch57 %patch58 -p1 %patch59 %build -%if 0%{?suse_version} && 0%{?suse_version} <= 1315 -python setup.py build -%else python3 setup.py build -%endif - -#%if 0%{?suse_version} > 1320 -#%check -## these tests are currently failing due to suse patches -#rm -v tests/unittests/test_distros/test_netconfig.py -#rm -v tests/unittests/test_net.py +%check ## Ignore test failure currently not doing anything with opennebula -#rm -v tests/unittests/test_datasource/test_opennebula.py -## To be investigated -#rm -v tests/unittests/test_handler/test_handler_ntp.py -#make test -#%endif - +rm -v tests/unittests/test_datasource/test_opennebula.py +make unittest3 %install -%if 0%{?suse_version} && 0%{?suse_version} <= 1315 -python setup.py install --root=%{buildroot} --prefix=%{_prefix} --install-lib=%{python_sitelib} --init-system=%{initsys} -%else python3 setup.py install --root=%{buildroot} --prefix=%{_prefix} --install-lib=%{python3_sitelib} --init-system=%{initsys} -%endif find %{buildroot} \( -name .gitignore -o -name .placeholder \) -delete # from debian install script for x in "%{buildroot}%{_bindir}/"*.py; do @@ -259,30 +182,10 @@ rm %{buildroot}/%{_sysconfdir}/cloud/templates/*.debian.* rm %{buildroot}/%{_sysconfdir}/cloud/templates/*.redhat.* rm %{buildroot}/%{_sysconfdir}/cloud/templates/*.ubuntu.* -# move sysvinit scripts into the "right" place -%if 0%{?suse_version} && 0%{?suse_version} <= 1210 -mkdir -p %{buildroot}/%{_initddir} -mkdir -p %{buildroot}/%{_sbindir} -pushd "%{buildroot}%{_initddir}" -for iniF in *; do - ln -s "%{_initddir}/${iniF}" "%{buildroot}/%{_sbindir}/rc${iniF}" -done -popd -%endif - # remove duplicate files %if 0%{?suse_version} -%if 0%{?suse_version} <= 1315 -%fdupes %{buildroot}%{python_sitelib} -%else %fdupes %{buildroot}%{python3_sitelib} %endif -%endif - -%if 0%{?suse_version} && 0%{?suse_version} <= 1210 -%postun -%insserv_cleanup -%endif %files %defattr(-,root,root) @@ -301,24 +204,9 @@ popd %dir %{_datadir}/bash-completion/completions %endif %{_datadir}/bash-completion/completions/cloud-init -%if 0%{?suse_version} && 0%{?suse_version} <= 1315 -%{python_sitelib}/cloudinit -%{python_sitelib}/cloud_init-%{version}-py%{py_ver}.egg-info -%else %{python3_sitelib}/cloudinit %{python3_sitelib}/cloud_init-%{version}-py%{py3_ver}.egg-info -%endif %{_prefix}/lib/cloud-init -%if 0%{?suse_version} && 0%{?suse_version} <= 1210 -%{_sbindir}/rccloud-config -%{_sbindir}/rccloud-init -%{_sbindir}/rccloud-init-local -%{_sbindir}/rccloud-final -%attr(0755, root, root) %{_initddir}/cloud-config -%attr(0755, root, root) %{_initddir}/cloud-init -%attr(0755, root, root) %{_initddir}/cloud-init-local -%attr(0755, root, root) %{_initddir}/cloud-final -%else %{systemd_prefix}/systemd/system-generators/cloud-init-generator %{systemd_prefix}/systemd/system/cloud-config.service %{systemd_prefix}/systemd/system/cloud-config.target @@ -326,17 +214,9 @@ popd %{systemd_prefix}/systemd/system/cloud-init.service %{systemd_prefix}/systemd/system/cloud-init.target %{systemd_prefix}/systemd/system/cloud-final.service -%endif -%if 0%{?suse_version} && 0%{?suse_version} > 1110 %dir %{_sysconfdir}/rsyslog.d %{_sysconfdir}/rsyslog.d/21-cloudinit.conf /usr/lib/udev/rules.d/66-azure-ephemeral.rules -# This if condition really distinquished between OBS and IBS. -# For SLE 12 builds in OBS owning the directories is not required, while -# SLE 12 builds in IBS require owning the directories -%else -/lib/udev/rules.d/66-azure-ephemeral.rules -%endif %dir %attr(0755, root, root) %{_localstatedir}/lib/cloud %dir %{docdir} %dir /etc/NetworkManager