diff --git a/EC2-Fix-bug-using-fallback_nic-and-metadata-when-res.patch b/EC2-Fix-bug-using-fallback_nic-and-metadata-when-res.patch deleted file mode 100644 index ee4d4788421523e79f4bfef8b80e83763a09589b..0000000000000000000000000000000000000000 --- a/EC2-Fix-bug-using-fallback_nic-and-metadata-when-res.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 281a82181716183d526e76f4e0415e0a6f680cbe Mon Sep 17 00:00:00 2001 -From: Scott Moser -Date: Mon, 20 Nov 2017 15:56:40 -0500 -Subject: [PATCH 040/354] EC2: Fix bug using fallback_nic and metadata when - restoring from cache. - -If user upgraded to new cloud-init and attempted to run 'cloud-init init' -without rebooting, cloud-init restores the datasource object from pickle. -The older version pickled datasource object had no value for -_network_config or fallback_nic. This caused the Ec2 datasource to attempt -to reconfigure networking with a None fallback_nic. The pickled object -also cached an older version of ec2 metadata which didn't contain network -information. - -This branch does two things: - - Add a fallback_interface property to DatasourceEC2 to support reading the - old .fallback_nic attribute if it was set. New versions will - call net.find_fallback_nic() if there has not been one found. - - Re-crawl metadata if we are on Ec2 and don't have a 'network' key in - metadata - -LP: #1732917 ---- - cloudinit/net/dhcp.py | 3 +- - cloudinit/sources/DataSourceEc2.py | 44 +++++++++++++++++++++-------- - tests/unittests/test_datasource/test_ec2.py | 33 ++++++++++++++++++++++ - 3 files changed, 67 insertions(+), 13 deletions(-) - -diff --git a/cloudinit/net/dhcp.py b/cloudinit/net/dhcp.py -index f3a412a..d8624d8 100644 ---- a/cloudinit/net/dhcp.py -+++ b/cloudinit/net/dhcp.py -@@ -42,8 +42,7 @@ def maybe_perform_dhcp_discovery(nic=None): - if nic is None: - nic = find_fallback_nic() - if nic is None: -- LOG.debug( -- 'Skip dhcp_discovery: Unable to find fallback nic.') -+ LOG.debug('Skip dhcp_discovery: Unable to find fallback nic.') - return {} - elif nic not in get_devicelist(): - LOG.debug( -diff --git a/cloudinit/sources/DataSourceEc2.py b/cloudinit/sources/DataSourceEc2.py -index 0ef2217..7bbbfb6 100644 ---- a/cloudinit/sources/DataSourceEc2.py -+++ b/cloudinit/sources/DataSourceEc2.py -@@ -65,7 +65,7 @@ class DataSourceEc2(sources.DataSource): - get_network_metadata = False - - # Track the discovered fallback nic for use in configuration generation. -- fallback_nic = None -+ _fallback_interface = None - - def __init__(self, sys_cfg, distro, paths): - sources.DataSource.__init__(self, sys_cfg, distro, paths) -@@ -92,18 +92,17 @@ class DataSourceEc2(sources.DataSource): - elif self.cloud_platform == Platforms.NO_EC2_METADATA: - return False - -- self.fallback_nic = net.find_fallback_nic() - if self.get_network_metadata: # Setup networking in init-local stage. - if util.is_FreeBSD(): - LOG.debug("FreeBSD doesn't support running dhclient with -sf") - return False -- dhcp_leases = dhcp.maybe_perform_dhcp_discovery(self.fallback_nic) -+ dhcp_leases = dhcp.maybe_perform_dhcp_discovery( -+ self.fallback_interface) - if not dhcp_leases: - # DataSourceEc2Local failed in init-local stage. DataSourceEc2 - # will still run in init-network stage. - return False - dhcp_opts = dhcp_leases[-1] -- self.fallback_nic = dhcp_opts.get('interface') - net_params = {'interface': dhcp_opts.get('interface'), - 'ip': dhcp_opts.get('fixed-address'), - 'prefix_or_mask': dhcp_opts.get('subnet-mask'), -@@ -301,21 +300,44 @@ class DataSourceEc2(sources.DataSource): - return None - - result = None -- net_md = self.metadata.get('network') -+ no_network_metadata_on_aws = bool( -+ 'network' not in self.metadata and -+ self.cloud_platform == Platforms.AWS) -+ if no_network_metadata_on_aws: -+ LOG.debug("Metadata 'network' not present:" -+ " Refreshing stale metadata from prior to upgrade.") -+ util.log_time( -+ logfunc=LOG.debug, msg='Re-crawl of metadata service', -+ func=self._crawl_metadata) -+ - # Limit network configuration to only the primary/fallback nic -- macs_to_nics = { -- net.get_interface_mac(self.fallback_nic): self.fallback_nic} -+ iface = self.fallback_interface -+ macs_to_nics = {net.get_interface_mac(iface): iface} -+ net_md = self.metadata.get('network') - if isinstance(net_md, dict): - result = convert_ec2_metadata_network_config( -- net_md, macs_to_nics=macs_to_nics, -- fallback_nic=self.fallback_nic) -+ net_md, macs_to_nics=macs_to_nics, fallback_nic=iface) - else: -- LOG.warning("unexpected metadata 'network' key not valid: %s", -- net_md) -+ LOG.warning("Metadata 'network' key not valid: %s.", net_md) - self._network_config = result - - return self._network_config - -+ @property -+ def fallback_interface(self): -+ if self._fallback_interface is None: -+ # fallback_nic was used at one point, so restored objects may -+ # have an attribute there. respect that if found. -+ _legacy_fbnic = getattr(self, 'fallback_nic', None) -+ if _legacy_fbnic: -+ self._fallback_interface = _legacy_fbnic -+ self.fallback_nic = None -+ else: -+ self._fallback_interface = net.find_fallback_nic() -+ if self._fallback_interface is None: -+ LOG.warning("Did not find a fallback interface on EC2.") -+ return self._fallback_interface -+ - def _crawl_metadata(self): - """Crawl metadata service when available. - -diff --git a/tests/unittests/test_datasource/test_ec2.py b/tests/unittests/test_datasource/test_ec2.py -index 6af699a..ba328ee 100644 ---- a/tests/unittests/test_datasource/test_ec2.py -+++ b/tests/unittests/test_datasource/test_ec2.py -@@ -307,6 +307,39 @@ class TestEc2(test_helpers.HttprettyTestCase): - - @httpretty.activate - @mock.patch('cloudinit.net.dhcp.maybe_perform_dhcp_discovery') -+ def test_network_config_cached_property_refreshed_on_upgrade(self, m_dhcp): -+ """Refresh the network_config Ec2 cache if network key is absent. -+ -+ This catches an upgrade issue where obj.pkl contained stale metadata -+ which lacked newly required network key. -+ """ -+ old_metadata = copy.deepcopy(DEFAULT_METADATA) -+ old_metadata.pop('network') -+ ds = self._setup_ds( -+ platform_data=self.valid_platform_data, -+ sys_cfg={'datasource': {'Ec2': {'strict_id': True}}}, -+ md=old_metadata) -+ self.assertTrue(ds.get_data()) -+ # Provide new revision of metadata that contains network data -+ register_mock_metaserver( -+ 'http://169.254.169.254/2009-04-04/meta-data/', DEFAULT_METADATA) -+ mac1 = '06:17:04:d7:26:09' # Defined in DEFAULT_METADATA -+ get_interface_mac_path = ( -+ 'cloudinit.sources.DataSourceEc2.net.get_interface_mac') -+ ds.fallback_nic = 'eth9' -+ with mock.patch(get_interface_mac_path) as m_get_interface_mac: -+ m_get_interface_mac.return_value = mac1 -+ ds.network_config # Will re-crawl network metadata -+ self.assertIn('Re-crawl of metadata service', self.logs.getvalue()) -+ expected = {'version': 1, 'config': [ -+ {'mac_address': '06:17:04:d7:26:09', -+ 'name': 'eth9', -+ 'subnets': [{'type': 'dhcp4'}, {'type': 'dhcp6'}], -+ 'type': 'physical'}]} -+ self.assertEqual(expected, ds.network_config) -+ -+ @httpretty.activate -+ @mock.patch('cloudinit.net.dhcp.maybe_perform_dhcp_discovery') - def test_valid_platform_with_strict_true(self, m_dhcp): - """Valid platform data should return true with strict_id true.""" - ds = self._setup_ds( --- -1.7.12.4 - diff --git a/EC2-Limit-network-config-to-fallback-nic-fix-local-i.patch b/EC2-Limit-network-config-to-fallback-nic-fix-local-i.patch deleted file mode 100644 index c2f98b985779512f04f95e7cc3247c62e87e20d2..0000000000000000000000000000000000000000 --- a/EC2-Limit-network-config-to-fallback-nic-fix-local-i.patch +++ /dev/null @@ -1,297 +0,0 @@ -From eb292c18c3d83b9f7e5d1fd81b0e8aefaab0cc2d Mon Sep 17 00:00:00 2001 -From: Chad Smith -Date: Tue, 31 Oct 2017 12:42:15 -0600 -Subject: [PATCH] EC2: Limit network config to fallback nic, fix local-ipv4 - only instances. - -VPC instances have the option to specific local only IPv4 addresses. Allow -Ec2Datasource to enable dhcp4 on instances even if local-ipv4s is -configured on an instance. - -Also limit network_configuration to only the primary (fallback) nic. - -LP: #1728152 ---- - cloudinit/sources/DataSourceEc2.py | 24 +++- - tests/unittests/test_datasource/test_ec2.py | 136 +++++++++++++++++++- - 2 files changed, 149 insertions(+), 11 deletions(-) - -diff --git a/cloudinit/sources/DataSourceEc2.py b/cloudinit/sources/DataSourceEc2.py -index 41367a8b..0ef22174 100644 ---- a/cloudinit/sources/DataSourceEc2.py -+++ b/cloudinit/sources/DataSourceEc2.py -@@ -64,6 +64,9 @@ class DataSourceEc2(sources.DataSource): - # Whether we want to get network configuration from the metadata service. - get_network_metadata = False - -+ # Track the discovered fallback nic for use in configuration generation. -+ fallback_nic = None -+ - def __init__(self, sys_cfg, distro, paths): - sources.DataSource.__init__(self, sys_cfg, distro, paths) - self.metadata_address = None -@@ -89,16 +92,18 @@ class DataSourceEc2(sources.DataSource): - elif self.cloud_platform == Platforms.NO_EC2_METADATA: - return False - -+ self.fallback_nic = net.find_fallback_nic() - if self.get_network_metadata: # Setup networking in init-local stage. - if util.is_FreeBSD(): - LOG.debug("FreeBSD doesn't support running dhclient with -sf") - return False -- dhcp_leases = dhcp.maybe_perform_dhcp_discovery() -+ dhcp_leases = dhcp.maybe_perform_dhcp_discovery(self.fallback_nic) - if not dhcp_leases: - # DataSourceEc2Local failed in init-local stage. DataSourceEc2 - # will still run in init-network stage. - return False - dhcp_opts = dhcp_leases[-1] -+ self.fallback_nic = dhcp_opts.get('interface') - net_params = {'interface': dhcp_opts.get('interface'), - 'ip': dhcp_opts.get('fixed-address'), - 'prefix_or_mask': dhcp_opts.get('subnet-mask'), -@@ -297,8 +302,13 @@ class DataSourceEc2(sources.DataSource): - - result = None - net_md = self.metadata.get('network') -+ # Limit network configuration to only the primary/fallback nic -+ macs_to_nics = { -+ net.get_interface_mac(self.fallback_nic): self.fallback_nic} - if isinstance(net_md, dict): -- result = convert_ec2_metadata_network_config(net_md) -+ result = convert_ec2_metadata_network_config( -+ net_md, macs_to_nics=macs_to_nics, -+ fallback_nic=self.fallback_nic) - else: - LOG.warning("unexpected metadata 'network' key not valid: %s", - net_md) -@@ -458,15 +468,18 @@ def _collect_platform_data(): - return data - - --def convert_ec2_metadata_network_config(network_md, macs_to_nics=None): -+def convert_ec2_metadata_network_config(network_md, macs_to_nics=None, -+ fallback_nic=None): - """Convert ec2 metadata to network config version 1 data dict. - - @param: network_md: 'network' portion of EC2 metadata. - generally formed as {"interfaces": {"macs": {}} where - 'macs' is a dictionary with mac address as key and contents like: - {"device-number": "0", "interface-id": "...", "local-ipv4s": ...} -- @param: macs_to_name: Optional dict mac addresses and the nic name. If -+ @param: macs_to_nics: Optional dict of mac addresses and nic names. If - not provided, get_interfaces_by_mac is called to get it from the OS. -+ @param: fallback_nic: Optionally provide the primary nic interface name. -+ This nic will be guaranteed to minimally have a dhcp4 configuration. - - @return A dict of network config version 1 based on the metadata and macs. - """ -@@ -480,7 +493,8 @@ def convert_ec2_metadata_network_config(network_md, macs_to_nics=None): - continue # Not a physical nic represented in metadata - nic_cfg = {'type': 'physical', 'name': nic_name, 'subnets': []} - nic_cfg['mac_address'] = mac -- if nic_metadata.get('public-ipv4s'): -+ if (nic_name == fallback_nic or nic_metadata.get('public-ipv4s') or -+ nic_metadata.get('local-ipv4s')): - nic_cfg['subnets'].append({'type': 'dhcp4'}) - if nic_metadata.get('ipv6s'): - nic_cfg['subnets'].append({'type': 'dhcp6'}) -diff --git a/tests/unittests/test_datasource/test_ec2.py b/tests/unittests/test_datasource/test_ec2.py -index a7301dbf..6af699a6 100644 ---- a/tests/unittests/test_datasource/test_ec2.py -+++ b/tests/unittests/test_datasource/test_ec2.py -@@ -51,6 +51,29 @@ DEFAULT_METADATA = { - "vpc-ipv4-cidr-block": "172.31.0.0/16", - "vpc-ipv4-cidr-blocks": "172.31.0.0/16", - "vpc-ipv6-cidr-blocks": "2600:1f16:aeb:b200::/56" -+ }, -+ "06:17:04:d7:26:0A": { -+ "device-number": "1", # Only IPv4 local config -+ "interface-id": "eni-e44ef49f", -+ "ipv4-associations": {"": "172.3.3.16"}, -+ "ipv6s": "", # No IPv6 config -+ "local-hostname": ("ip-172-3-3-16.us-east-2." -+ "compute.internal"), -+ "local-ipv4s": "172.3.3.16", -+ "mac": "06:17:04:d7:26:0A", -+ "owner-id": "950047163771", -+ "public-hostname": ("ec2-172-3-3-16.us-east-2." -+ "compute.amazonaws.com"), -+ "public-ipv4s": "", # No public ipv4 config -+ "security-group-ids": "sg-5a61d333", -+ "security-groups": "wide-open", -+ "subnet-id": "subnet-20b8565b", -+ "subnet-ipv4-cidr-block": "172.31.16.0/20", -+ "subnet-ipv6-cidr-blocks": "", -+ "vpc-id": "vpc-87e72bee", -+ "vpc-ipv4-cidr-block": "172.31.0.0/16", -+ "vpc-ipv4-cidr-blocks": "172.31.0.0/16", -+ "vpc-ipv6-cidr-blocks": "" - } - } - } -@@ -209,12 +232,20 @@ class TestEc2(test_helpers.HttprettyTestCase): - - @httpretty.activate - def test_network_config_property_returns_version_1_network_data(self): -- """network_config property returns network version 1 for metadata.""" -+ """network_config property returns network version 1 for metadata. -+ -+ Only one device is configured even when multiple exist in metadata. -+ """ - ds = self._setup_ds( - platform_data=self.valid_platform_data, - sys_cfg={'datasource': {'Ec2': {'strict_id': True}}}, - md=DEFAULT_METADATA) -- ds.get_data() -+ find_fallback_path = ( -+ 'cloudinit.sources.DataSourceEc2.net.find_fallback_nic') -+ with mock.patch(find_fallback_path) as m_find_fallback: -+ m_find_fallback.return_value = 'eth9' -+ ds.get_data() -+ - mac1 = '06:17:04:d7:26:09' # Defined in DEFAULT_METADATA - expected = {'version': 1, 'config': [ - {'mac_address': '06:17:04:d7:26:09', 'name': 'eth9', -@@ -222,9 +253,48 @@ class TestEc2(test_helpers.HttprettyTestCase): - 'type': 'physical'}]} - patch_path = ( - 'cloudinit.sources.DataSourceEc2.net.get_interfaces_by_mac') -+ get_interface_mac_path = ( -+ 'cloudinit.sources.DataSourceEc2.net.get_interface_mac') -+ with mock.patch(patch_path) as m_get_interfaces_by_mac: -+ with mock.patch(find_fallback_path) as m_find_fallback: -+ with mock.patch(get_interface_mac_path) as m_get_mac: -+ m_get_interfaces_by_mac.return_value = {mac1: 'eth9'} -+ m_find_fallback.return_value = 'eth9' -+ m_get_mac.return_value = mac1 -+ self.assertEqual(expected, ds.network_config) -+ -+ @httpretty.activate -+ def test_network_config_property_set_dhcp4_on_private_ipv4(self): -+ """network_config property configures dhcp4 on private ipv4 nics. -+ -+ Only one device is configured even when multiple exist in metadata. -+ """ -+ ds = self._setup_ds( -+ platform_data=self.valid_platform_data, -+ sys_cfg={'datasource': {'Ec2': {'strict_id': True}}}, -+ md=DEFAULT_METADATA) -+ find_fallback_path = ( -+ 'cloudinit.sources.DataSourceEc2.net.find_fallback_nic') -+ with mock.patch(find_fallback_path) as m_find_fallback: -+ m_find_fallback.return_value = 'eth9' -+ ds.get_data() -+ -+ mac1 = '06:17:04:d7:26:0A' # IPv4 only in DEFAULT_METADATA -+ expected = {'version': 1, 'config': [ -+ {'mac_address': '06:17:04:d7:26:0A', 'name': 'eth9', -+ 'subnets': [{'type': 'dhcp4'}], -+ 'type': 'physical'}]} -+ patch_path = ( -+ 'cloudinit.sources.DataSourceEc2.net.get_interfaces_by_mac') -+ get_interface_mac_path = ( -+ 'cloudinit.sources.DataSourceEc2.net.get_interface_mac') - with mock.patch(patch_path) as m_get_interfaces_by_mac: -- m_get_interfaces_by_mac.return_value = {mac1: 'eth9'} -- self.assertEqual(expected, ds.network_config) -+ with mock.patch(find_fallback_path) as m_find_fallback: -+ with mock.patch(get_interface_mac_path) as m_get_mac: -+ m_get_interfaces_by_mac.return_value = {mac1: 'eth9'} -+ m_find_fallback.return_value = 'eth9' -+ m_get_mac.return_value = mac1 -+ self.assertEqual(expected, ds.network_config) - - def test_network_config_property_is_cached_in_datasource(self): - """network_config property is cached in DataSourceEc2.""" -@@ -321,9 +391,11 @@ class TestEc2(test_helpers.HttprettyTestCase): - - @httpretty.activate - @mock.patch('cloudinit.net.EphemeralIPv4Network') -+ @mock.patch('cloudinit.net.find_fallback_nic') - @mock.patch('cloudinit.net.dhcp.maybe_perform_dhcp_discovery') - @mock.patch('cloudinit.sources.DataSourceEc2.util.is_FreeBSD') -- def test_ec2_local_performs_dhcp_on_non_bsd(self, m_is_bsd, m_dhcp, m_net): -+ def test_ec2_local_performs_dhcp_on_non_bsd(self, m_is_bsd, m_dhcp, -+ m_fallback_nic, m_net): - """Ec2Local returns True for valid platform data on non-BSD with dhcp. - - DataSourceEc2Local will setup initial IPv4 network via dhcp discovery. -@@ -331,6 +403,7 @@ class TestEc2(test_helpers.HttprettyTestCase): - When the platform data is valid, return True. - """ - -+ m_fallback_nic.return_value = 'eth9' - m_is_bsd.return_value = False - m_dhcp.return_value = [{ - 'interface': 'eth9', 'fixed-address': '192.168.2.9', -@@ -344,7 +417,7 @@ class TestEc2(test_helpers.HttprettyTestCase): - - ret = ds.get_data() - self.assertTrue(ret) -- m_dhcp.assert_called_once_with() -+ m_dhcp.assert_called_once_with('eth9') - m_net.assert_called_once_with( - broadcast='192.168.2.255', interface='eth9', ip='192.168.2.9', - prefix_or_mask='255.255.255.0', router='192.168.2.1') -@@ -389,6 +462,57 @@ class TestConvertEc2MetadataNetworkConfig(test_helpers.CiTestCase): - ec2.convert_ec2_metadata_network_config( - network_metadata_ipv6, macs_to_nics)) - -+ def test_convert_ec2_metadata_network_config_handles_local_dhcp4(self): -+ """Config dhcp4 when there are no public addresses in public-ipv4s.""" -+ macs_to_nics = {self.mac1: 'eth9'} -+ network_metadata_ipv6 = copy.deepcopy(self.network_metadata) -+ nic1_metadata = ( -+ network_metadata_ipv6['interfaces']['macs'][self.mac1]) -+ nic1_metadata['local-ipv4s'] = '172.3.3.15' -+ nic1_metadata.pop('public-ipv4s') -+ expected = {'version': 1, 'config': [ -+ {'mac_address': self.mac1, 'type': 'physical', -+ 'name': 'eth9', 'subnets': [{'type': 'dhcp4'}]}]} -+ self.assertEqual( -+ expected, -+ ec2.convert_ec2_metadata_network_config( -+ network_metadata_ipv6, macs_to_nics)) -+ -+ def test_convert_ec2_metadata_network_config_handles_absent_dhcp4(self): -+ """Config dhcp4 on fallback_nic when there are no ipv4 addresses.""" -+ macs_to_nics = {self.mac1: 'eth9'} -+ network_metadata_ipv6 = copy.deepcopy(self.network_metadata) -+ nic1_metadata = ( -+ network_metadata_ipv6['interfaces']['macs'][self.mac1]) -+ nic1_metadata['public-ipv4s'] = '' -+ -+ # When no ipv4 or ipv6 content but fallback_nic set, set dhcp4 config. -+ expected = {'version': 1, 'config': [ -+ {'mac_address': self.mac1, 'type': 'physical', -+ 'name': 'eth9', 'subnets': [{'type': 'dhcp4'}]}]} -+ self.assertEqual( -+ expected, -+ ec2.convert_ec2_metadata_network_config( -+ network_metadata_ipv6, macs_to_nics, fallback_nic='eth9')) -+ -+ def test_convert_ec2_metadata_network_config_handles_local_v4_and_v6(self): -+ """When dhcp6 is public and dhcp4 is set to local enable both.""" -+ macs_to_nics = {self.mac1: 'eth9'} -+ network_metadata_both = copy.deepcopy(self.network_metadata) -+ nic1_metadata = ( -+ network_metadata_both['interfaces']['macs'][self.mac1]) -+ nic1_metadata['ipv6s'] = '2620:0:1009:fd00:e442:c88d:c04d:dc85/64' -+ nic1_metadata.pop('public-ipv4s') -+ nic1_metadata['local-ipv4s'] = '10.0.0.42' # Local ipv4 only on vpc -+ expected = {'version': 1, 'config': [ -+ {'mac_address': self.mac1, 'type': 'physical', -+ 'name': 'eth9', -+ 'subnets': [{'type': 'dhcp4'}, {'type': 'dhcp6'}]}]} -+ self.assertEqual( -+ expected, -+ ec2.convert_ec2_metadata_network_config( -+ network_metadata_both, macs_to_nics)) -+ - def test_convert_ec2_metadata_network_config_handles_dhcp4_and_dhcp6(self): - """Config both dhcp4 and dhcp6 when both vpc-ipv6 and ipv4 exists.""" - macs_to_nics = {self.mac1: 'eth9'} --- -2.19.1 - diff --git a/Fix-ssh-keys-validation-in-ssh_util.patch b/Fix-ssh-keys-validation-in-ssh_util.patch deleted file mode 100644 index f16c05377f80c7122075f3cca0ba174ef1a44d0a..0000000000000000000000000000000000000000 --- a/Fix-ssh-keys-validation-in-ssh_util.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 45289a00bf8c043c5783c527c4ea720e67e0524b Mon Sep 17 00:00:00 2001 -From: Tatiana Kholkina -Date: Thu, 1 Feb 2018 18:08:15 +0300 -Subject: [PATCH 092/354] Fix ssh keys validation in ssh_util - -This fixes a bug where invalid keys would sneak into authorized_keys. ---- - cloudinit/ssh_util.py | 5 +---- - tests/unittests/test_sshutil.py | 42 +++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 43 insertions(+), 4 deletions(-) - -diff --git a/cloudinit/ssh_util.py b/cloudinit/ssh_util.py -index b95b956..882517f 100644 ---- a/cloudinit/ssh_util.py -+++ b/cloudinit/ssh_util.py -@@ -171,16 +171,13 @@ def parse_authorized_keys(fname): - - - def update_authorized_keys(old_entries, keys): -- to_add = list(keys) -- -+ to_add = list([k for k in keys if k.valid()]) - for i in range(0, len(old_entries)): - ent = old_entries[i] - if not ent.valid(): - continue - # Replace those with the same base64 - for k in keys: -- if not ent.valid(): -- continue - if k.base64 == ent.base64: - # Replace it with our better one - ent = k -diff --git a/tests/unittests/test_sshutil.py b/tests/unittests/test_sshutil.py -index 2a8e6ab..4c62c8b 100644 ---- a/tests/unittests/test_sshutil.py -+++ b/tests/unittests/test_sshutil.py -@@ -126,6 +126,48 @@ class TestAuthKeyLineParser(test_helpers.TestCase): - self.assertFalse(key.valid()) - - -+class TestUpdateAuthorizedKeys(test_helpers.TestCase): -+ -+ def test_new_keys_replace(self): -+ """new entries with the same base64 should replace old.""" -+ orig_entries = [ -+ ' '.join(('rsa', VALID_CONTENT['rsa'], 'orig_comment1')), -+ ' '.join(('dsa', VALID_CONTENT['dsa'], 'orig_comment2'))] -+ -+ new_entries = [ -+ ' '.join(('rsa', VALID_CONTENT['rsa'], 'new_comment1')), ] -+ -+ expected = '\n'.join([new_entries[0], orig_entries[1]]) + '\n' -+ -+ parser = ssh_util.AuthKeyLineParser() -+ found = ssh_util.update_authorized_keys( -+ [parser.parse(p) for p in orig_entries], -+ [parser.parse(p) for p in new_entries]) -+ -+ self.assertEqual(expected, found) -+ -+ def test_new_invalid_keys_are_ignored(self): -+ """new entries that are invalid should be skipped.""" -+ orig_entries = [ -+ ' '.join(('rsa', VALID_CONTENT['rsa'], 'orig_comment1')), -+ ' '.join(('dsa', VALID_CONTENT['dsa'], 'orig_comment2'))] -+ -+ new_entries = [ -+ ' '.join(('rsa', VALID_CONTENT['rsa'], 'new_comment1')), -+ 'xxx-invalid-thing1', -+ 'xxx-invalid-blob2' -+ ] -+ -+ expected = '\n'.join([new_entries[0], orig_entries[1]]) + '\n' -+ -+ parser = ssh_util.AuthKeyLineParser() -+ found = ssh_util.update_authorized_keys( -+ [parser.parse(p) for p in orig_entries], -+ [parser.parse(p) for p in new_entries]) -+ -+ self.assertEqual(expected, found) -+ -+ - class TestParseSSHConfig(test_helpers.TestCase): - - def setUp(self): --- -1.7.12.4 - diff --git a/add-variable-to-forbid-tmp-dir.patch b/add-variable-to-forbid-tmp-dir.patch index 5990566e47a078f98da3bf89cc2d7e312bc9e5f1..6a7d5f0d37258dd63643886e6048bb21a9d01d20 100644 --- a/add-variable-to-forbid-tmp-dir.patch +++ b/add-variable-to-forbid-tmp-dir.patch @@ -1,58 +1,59 @@ -From 224da46b2331b582577b86c3eb707f67d57800fb Mon Sep 17 00:00:00 2001 -From: chengquan -Date: Thu, 8 Aug 2019 16:15:31 +0800 -Subject: [PATCH] cloud-init: add variable to forbid tmp dir - -reason: add variable to forbid temporary directory - -Signed-off-by: chengquan ---- - cloud-init-17.1/setup.py | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) - -diff -Nur cloud-init-17.1/setup.py cloud-init-17.1_bak/setup.py ---- cloud-init-17.1/setup.py 2019-04-12 19:00:20.782000000 +0800 -+++ cloud-init-17.1_bak/setup.py 2019-04-12 19:48:04.246000000 +0800 -@@ -86,6 +86,8 @@ - (deps, _e) = tiny_p(cmd) - return str(deps).splitlines() - -+# add variable to forbid tmp dir -+num = 0 - - def render_tmpl(template): - """render template into a tmpdir under same dir as setup.py -@@ -107,7 +109,10 @@ - return template - - topdir = os.path.dirname(sys.argv[0]) -- tmpd = tempfile.mkdtemp(dir=topdir) -+ global num -+ os.mkdir(topdir + str(num)) -+ tmpd = os.path.abspath(topdir + str(num)) -+ num = num + 1 - atexit.register(shutil.rmtree, tmpd) - bname = os.path.basename(template).rstrip(tmpl_ext) - fpath = os.path.join(tmpd, bname) -@@ -115,6 +120,9 @@ - # return path relative to setup.py - return os.path.join(os.path.basename(tmpd), bname) - -+def sort_files(file_list): -+ file_list.sort() -+ return file_list - - INITSYS_FILES = { - 'sysvinit': [f for f in glob('sysvinit/redhat/*') if is_f(f)], -@@ -123,9 +131,9 @@ - 'sysvinit_openrc': [f for f in glob('sysvinit/gentoo/*') if is_f(f)], - 'sysvinit_suse': [f for f in glob('sysvinit/suse/*') if is_f(f)], - 'systemd': [render_tmpl(f) -- for f in (glob('systemd/*.tmpl') + -+ for f in sort_files((glob('systemd/*.tmpl') + - glob('systemd/*.service') + -- glob('systemd/*.target')) if is_f(f)], -+ glob('systemd/*.target'))) if is_f(f)], - 'systemd.generators': [f for f in glob('systemd/*-generator') if is_f(f)], - 'upstart': [f for f in glob('upstart/*') if is_f(f)], - } +From 224da46b2331b582577b86c3eb707f67d57800fb Mon Sep 17 00:00:00 2001 +From: chengquan +Date: Thu, 8 Aug 2019 16:15:31 +0800 +Subject: [PATCH] cloud-init: add variable to forbid tmp dir + +reason: add variable to forbid temporary directory + +Signed-off-by: chengquan +--- + cloud-init-19.4/setup.py | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff -Nur a/setup.py b/setup.py +--- a/setup.py 2019-04-12 19:00:20.782000000 +0800 ++++ b/setup.py 2019-04-12 19:48:04.246000000 +0800 +@@ -91,6 +91,8 @@ + (deps, _e) = tiny_p(cmd) + return str(deps).splitlines() + ++# add variable to forbid tmp dir ++num = 0 + + def render_tmpl(template, mode=None): + """render template into a tmpdir under same dir as setup.py +@@ -112,7 +114,10 @@ + return template + + topdir = os.path.dirname(sys.argv[0]) +- tmpd = tempfile.mkdtemp(dir=topdir, prefix=RENDERED_TMPD_PREFIX) ++ global num ++ os.mkdir(topdir + str(num)) ++ tmpd = os.path.abspath(topdir + str(num)) ++ num = num + 1 + atexit.register(shutil.rmtree, tmpd) + bname = os.path.basename(template).rstrip(tmpl_ext) + fpath = os.path.join(tmpd, bname) +@@ -126,6 +131,10 @@ + # return path relative to setup.py + return os.path.join(os.path.basename(tmpd), bname) + ++def sort_files(file_list): ++ file_list.sort() ++ return file_list ++ + # User can set the variant for template rendering + if '--distro' in sys.argv: + idx = sys.argv.index('--distro') +@@ -140,9 +149,9 @@ + 'sysvinit_openrc': [f for f in glob('sysvinit/gentoo/*') if is_f(f)], + 'sysvinit_suse': [f for f in glob('sysvinit/suse/*') if is_f(f)], + 'systemd': [render_tmpl(f) +- for f in (glob('systemd/*.tmpl') + ++ for f in sort_files((glob('systemd/*.tmpl') + + glob('systemd/*.service') + +- glob('systemd/*.target')) ++ glob('systemd/*.target'))) + if (is_f(f) and not is_generator(f))], + 'systemd.generators': [ + render_tmpl(f, mode=0o755) diff --git a/bugfix-cloud-init-add-openEuler-os.patch b/bugfix-cloud-init-add-openEuler-os.patch index 17811a680465d33270bf50d62d6450e916667324..41a953b6bd9fe6c4d8fcb26572d278a1f645cfe5 100644 --- a/bugfix-cloud-init-add-openEuler-os.patch +++ b/bugfix-cloud-init-add-openEuler-os.patch @@ -1,227 +1,213 @@ -From 098429a75ea00df1d8a5670e45df6babfc37f327 Mon Sep 17 00:00:00 2001 -From: chengquan -Date: Thu, 8 Aug 2019 16:11:58 +0800 -Subject: [PATCH] cloud-init: cloud-init add openEuler os - -reason: add openEuler into distros - -Signed-off-by: chengquan ---- - .../0001-cloud-init-Update-patch-information.patch | 68 ++++++++++++++++++++++ - cloud-init-17.1/cloudinit/config/cc_ntp.py | 2 +- - cloud-init-17.1/cloudinit/config/cc_resolv_conf.py | 2 +- - .../cloudinit/config/cc_rh_subscription.py | 2 +- - cloud-init-17.1/cloudinit/config/cc_spacewalk.py | 2 +- - .../cloudinit/config/cc_yum_add_repo.py | 2 +- - cloud-init-17.1/cloudinit/distros/__init__.py | 2 +- - cloud-init-17.1/cloudinit/distros/openEuler.py | 12 ++++ - cloud-init-17.1/cloudinit/util.py | 2 +- - cloud-init-17.1/config/cloud.cfg.tmpl | 8 +-- - cloud-init-17.1/systemd/cloud-init.service.tmpl | 2 +- - cloud-init-17.1/tests/cloud_tests/util.py | 2 +- - .../unittests/test_handler/test_handler_ntp.py | 2 +- - cloud-init-17.1/tools/render-cloudcfg | 2 +- - 14 files changed, 95 insertions(+), 15 deletions(-) - create mode 100644 cloud-init-17.1/cloudinit/distros/openEuler.py - -diff --git a/cloudinit/config/cc_ntp.py b/cloudinit/config/cc_ntp.py -index d43d060..4f14c10 100644 ---- a/cloudinit/config/cc_ntp.py -+++ b/cloudinit/config/cc_ntp.py -@@ -23,7 +23,7 @@ frequency = PER_INSTANCE - NTP_CONF = '/etc/ntp.conf' - TIMESYNCD_CONF = '/etc/systemd/timesyncd.conf.d/cloud-init.conf' - NR_POOL_SERVERS = 4 --distros = ['centos', 'debian', 'fedora', 'opensuse', 'ubuntu'] -+distros = ['centos', 'debian', 'fedora', 'opensuse', 'ubuntu', 'openEuler'] - - - # The schema definition for each cloud-config module is a strict contract for -diff --git a/cloudinit/config/cc_resolv_conf.py b/cloudinit/config/cc_resolv_conf.py -index 9812562..973fe2e 100644 ---- a/cloudinit/config/cc_resolv_conf.py -+++ b/cloudinit/config/cc_resolv_conf.py -@@ -55,7 +55,7 @@ LOG = logging.getLogger(__name__) - - frequency = PER_INSTANCE - --distros = ['fedora', 'opensuse', 'rhel', 'sles'] -+distros = ['fedora', 'opensuse', 'rhel', 'sles', 'openEuler'] - - - def generate_resolv_conf(template_fn, params, target_fname="/etc/resolv.conf"): -diff --git a/cloudinit/config/cc_rh_subscription.py b/cloudinit/config/cc_rh_subscription.py -index 7f36cf8..23f3a5a 100644 ---- a/cloudinit/config/cc_rh_subscription.py -+++ b/cloudinit/config/cc_rh_subscription.py -@@ -40,7 +40,7 @@ Subscription`` example config. - - from cloudinit import util - --distros = ['fedora', 'rhel'] -+distros = ['fedora', 'rhel', 'openEuler'] - - - def handle(name, cfg, _cloud, log, _args): -diff --git a/cloudinit/config/cc_spacewalk.py b/cloudinit/config/cc_spacewalk.py -index 1020e94..63e9d3b 100644 ---- a/cloudinit/config/cc_spacewalk.py -+++ b/cloudinit/config/cc_spacewalk.py -@@ -30,7 +30,7 @@ For more information about spacewalk see: https://fedorahosted.org/spacewalk/ - from cloudinit import util - - --distros = ['redhat', 'fedora'] -+distros = ['redhat', 'fedora', 'openEuler'] - required_packages = ['rhn-setup'] - def_ca_cert_path = "/usr/share/rhn/RHN-ORG-TRUSTED-SSL-CERT" - -diff --git a/cloudinit/config/cc_yum_add_repo.py b/cloudinit/config/cc_yum_add_repo.py -index 6a42f49..9b2d1bd 100644 ---- a/cloudinit/config/cc_yum_add_repo.py -+++ b/cloudinit/config/cc_yum_add_repo.py -@@ -40,7 +40,7 @@ import six - - from cloudinit import util - --distros = ['fedora', 'rhel'] -+distros = ['fedora', 'rhel', 'openEuler'] - - - def _canonicalize_id(repo_id): -diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py -index d5becd1..f6eb899 100755 ---- a/cloudinit/distros/__init__.py -+++ b/cloudinit/distros/__init__.py -@@ -36,7 +36,7 @@ ALL_DISTROS = 'all' - - OSFAMILIES = { - 'debian': ['debian', 'ubuntu'], -- 'redhat': ['centos', 'fedora', 'rhel'], -+ 'redhat': ['centos', 'fedora', 'rhel', 'openEuler'], - 'gentoo': ['gentoo'], - 'freebsd': ['freebsd'], - 'suse': ['opensuse', 'sles'], -diff --git a/cloudinit/util.py b/cloudinit/util.py -index e1290aa..d85daf0 100644 ---- a/cloudinit/util.py -+++ b/cloudinit/util.py -@@ -592,7 +592,7 @@ def system_info(): - var = 'unknown' - if system == "linux": - linux_dist = info['dist'][0].lower() -- if linux_dist in ('centos', 'fedora', 'debian'): -+ if linux_dist in ('centos', 'fedora', 'debian', 'openEuler'): - var = linux_dist - elif linux_dist in ('ubuntu', 'linuxmint', 'mint'): - var = 'ubuntu' -diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl -index 50e3bd8..e3816f2 100644 ---- a/config/cloud.cfg.tmpl -+++ b/config/cloud.cfg.tmpl -@@ -19,7 +19,7 @@ disable_root: false - disable_root: true - {% endif %} - --{% if variant in ["centos", "fedora", "rhel"] %} -+{% if variant in ["centos", "fedora", "rhel", "openEuler"] %} - mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2'] - resize_rootfs_tmp: /dev - ssh_deletekeys: 0 -@@ -75,7 +75,7 @@ cloud_config_modules: - - ssh-import-id - - locale - - set-passwords --{% if variant in ["rhel", "fedora"] %} -+{% if variant in ["rhel", "fedora", "openEuler"] %} - - spacewalk - - yum-add-repo - {% endif %} -@@ -127,7 +127,7 @@ cloud_final_modules: - # (not accessible to handlers/transforms) - system_info: - # This will affect which distro class gets used --{% if variant in ["centos", "debian", "fedora", "rhel", "suse", "ubuntu", "freebsd"] %} -+{% if variant in ["centos", "debian", "fedora", "rhel", "suse", "ubuntu", "freebsd", "openEuler"] %} - distro: {{ variant }} - {% else %} - # Unknown/fallback distro. -@@ -163,7 +163,7 @@ system_info: - primary: http://ports.ubuntu.com/ubuntu-ports - security: http://ports.ubuntu.com/ubuntu-ports - ssh_svcname: ssh --{% elif variant in ["centos", "rhel", "fedora", "suse"] %} -+{% elif variant in ["centos", "rhel", "fedora", "suse", "openEuler"] %} - # Default user name + that default users groups (if added/used) - default_user: - name: {{ variant }} -diff --git a/systemd/cloud-init.service.tmpl b/systemd/cloud-init.service.tmpl -index b92e8ab..f59d4fd 100644 ---- a/systemd/cloud-init.service.tmpl -+++ b/systemd/cloud-init.service.tmpl -@@ -10,7 +10,7 @@ After=systemd-networkd-wait-online.service - {% if variant in ["ubuntu", "unknown", "debian"] %} - After=networking.service - {% endif %} --{% if variant in ["centos", "fedora", "redhat"] %} -+{% if variant in ["centos", "fedora", "redhat", "openEuler"] %} - After=network.service - {% endif %} - {% if variant in ["suse"] %} -diff --git a/tests/cloud_tests/util.py b/tests/cloud_tests/util.py -index 4357fbb..7d3034d 100644 ---- a/tests/cloud_tests/util.py -+++ b/tests/cloud_tests/util.py -@@ -18,7 +18,7 @@ from tests.cloud_tests import LOG - - OS_FAMILY_MAPPING = { - 'debian': ['debian', 'ubuntu'], -- 'redhat': ['centos', 'rhel', 'fedora'], -+ 'redhat': ['centos', 'rhel', 'fedora', 'openEuler'], - 'gentoo': ['gentoo'], - 'freebsd': ['freebsd'], - 'suse': ['sles'], -diff --git a/tests/unittests/test_handler/test_handler_ntp.py b/tests/unittests/test_handler/test_handler_ntp.py -index 3abe578..78548cc 100644 ---- a/tests/unittests/test_handler/test_handler_ntp.py -+++ b/tests/unittests/test_handler/test_handler_ntp.py -@@ -258,7 +258,7 @@ class TestNtp(FilesystemMockingTestCase): - } - } - ntp_conf = self.tmp_path('ntp.conf', self.new_root) # Doesn't exist -- for distro in ('debian', 'ubuntu', 'fedora', 'rhel', 'sles'): -+ for distro in ('debian', 'ubuntu', 'fedora', 'rhel', 'sles', 'openEuler'): - mycloud = self._get_cloud(distro) - root_dir = dirname(dirname(os.path.realpath(util.__file__))) - tmpl_file = os.path.join( -diff --git a/tools/render-cloudcfg b/tools/render-cloudcfg -index 91d074b..7a8a2c4 100755 ---- a/tools/render-cloudcfg -+++ b/tools/render-cloudcfg -@@ -4,7 +4,7 @@ import argparse - import os - import sys - --VARIANTS = ["bsd", "centos", "fedora", "rhel", "suse", "ubuntu", "unknown"] -+VARIANTS = ["bsd", "centos", "fedora", "rhel", "suse", "ubuntu", "unknown", "openEuler"] - - if "avoid-pep8-E402-import-not-top-of-file": - _tdir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) -diff --git a/cloudinit/distros/openEuler.py b/cloudinit/distros/openEuler.py -new file mode 100644 -index 0000000..5ac4700 ---- /dev/null -+++ b/cloudinit/distros/openEuler.py -@@ -0,0 +1,12 @@ -+# Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. -+# This file is part of cloud-init. See LICENSE file for license information. -+ -+from cloudinit.distros import rhel -+from cloudinit import log as logging -+ -+LOG = logging.getLogger(__name__) -+ -+class Distro(rhel.Distro): -+ pass -+ -+# vi: ts=4 expandtab +From 098429a75ea00df1d8a5670e45df6babfc37f327 Mon Sep 17 00:00:00 2001 +From: chengquan +Date: Thu, 8 Aug 2019 16:11:58 +0800 +Subject: [PATCH] cloud-init: cloud-init add openEuler os + +reason: add openEuler into distros + +Signed-off-by: chengquan +--- + .../0001-cloud-init-Update-patch-information.patch | 68 ++++++++++++++++++++++ + cloud-init-19.4/cloudinit/config/cc_ntp.py | 2 +- + cloud-init-19.4/cloudinit/config/cc_resolv_conf.py | 2 +- + cloud-init-19.4/cloudinit/config/cc_rh_subscription.py | 2 +- + cloud-init-19.4/cloudinit/config/cc_spacewalk.py | 2 +- + .../cloudinit/config/cc_yum_add_repo.py | 2 +- + cloud-init-19.4/cloudinit/distros/__init__.py | 2 +- + cloud-init-19.4/cloudinit/distros/openEuler.py | 12 ++++ + cloud-init-19.4/cloudinit/util.py | 2 +- + cloud-init-19.4/config/cloud.cfg.tmpl | 8 +-- + cloud-init-19.4/systemd/cloud-init.service.tmpl | 2 +- + cloud-init-19.4/tests/cloud_tests/util.py | 2 +- + cloud-init-19.4/tools/render-cloudcfg | 2 +- + 14 files changed, 95 insertions(+), 15 deletions(-) + create mode 100644 cloud-init-19.4/cloudinit/distros/openEuler.py + +diff --git a/cloudinit/config/cc_ntp.py b/cloudinit/config/cc_ntp.py +index d43d060..4f14c10 100644 +--- a/cloudinit/config/cc_ntp.py ++++ b/cloudinit/config/cc_ntp.py +@@ -23,7 +23,7 @@ LOG = logging.getLogger(_name_) + frequency = PER_INSTANCE + NTP_CONF = '/etc/ntp.conf' + NR_POOL_SERVERS = 4 +-distros = ['centos', 'debian', 'fedora', 'opensuse', 'rhel', 'sles', 'ubuntu'] ++distros = ['centos', 'debian', 'fedora', 'opensuse', 'rhel', 'sles', 'ubuntu', 'openEuler'] + + NTP_CLIENT_CONFIG = { + 'chrony': { +diff --git a/cloudinit/config/cc_resolv_conf.py b/cloudinit/config/cc_resolv_conf.py +index 9812562..973fe2e 100644 +--- a/cloudinit/config/cc_resolv_conf.py ++++ b/cloudinit/config/cc_resolv_conf.py +@@ -55,7 +55,7 @@ LOG = logging.getLogger(__name__) + + frequency = PER_INSTANCE + +-distros = ['fedora', 'opensuse', 'rhel', 'sles'] ++distros = ['fedora', 'opensuse', 'rhel', 'sles', 'openEuler'] + + + def generate_resolv_conf(template_fn, params, target_fname="/etc/resolv.conf"): +diff --git a/cloudinit/config/cc_rh_subscription.py b/cloudinit/config/cc_rh_subscription.py +index 7f36cf8..23f3a5a 100644 +--- a/cloudinit/config/cc_rh_subscription.py ++++ b/cloudinit/config/cc_rh_subscription.py +@@ -43,7 +43,7 @@ from cloudinit import util + + LOG = logging.getLogger(__name__) + +-distros = ['fedora', 'rhel'] ++distros = ['fedora', 'rhel', 'openEuler'] + + + def handle(name, cfg, _cloud, log, _args): +diff --git a/cloudinit/config/cc_spacewalk.py b/cloudinit/config/cc_spacewalk.py +index 1020e94..63e9d3b 100644 +--- a/cloudinit/config/cc_spacewalk.py ++++ b/cloudinit/config/cc_spacewalk.py +@@ -30,7 +30,7 @@ For more information about spacewalk see: https://fedorahosted.org/spacewalk/ + from cloudinit import util + + +-distros = ['redhat', 'fedora'] ++distros = ['redhat', 'fedora', 'openEuler'] + required_packages = ['rhn-setup'] + def_ca_cert_path = "/usr/share/rhn/RHN-ORG-TRUSTED-SSL-CERT" + +diff --git a/cloudinit/config/cc_yum_add_repo.py b/cloudinit/config/cc_yum_add_repo.py +index 6a42f49..9b2d1bd 100644 +--- a/cloudinit/config/cc_yum_add_repo.py ++++ b/cloudinit/config/cc_yum_add_repo.py +@@ -40,7 +40,7 @@ import six + + from cloudinit import util + +-distros = ['fedora', 'rhel'] ++distros = ['fedora', 'rhel', 'openEuler'] + + + def _canonicalize_id(repo_id): +diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py +index d5becd1..f6eb899 100755 +--- a/cloudinit/distros/__init__.py ++++ b/cloudinit/distros/__init__.py +@@ -36,7 +36,7 @@ ALL_DISTROS = 'all' + + OSFAMILIES = { + 'debian': ['debian', 'ubuntu'], +- 'redhat': ['amazon', 'centos', 'fedora', 'rhel'], ++ 'redhat': ['amazon', 'centos', 'fedora', 'rhel', 'openEuler'], + 'gentoo': ['gentoo'], + 'freebsd': ['freebsd'], + 'suse': ['opensuse', 'sles'], +diff --git a/cloudinit/util.py b/cloudinit/util.py +index e1290aa..d85daf0 100644 +--- a/cloudinit/util.py ++++ b/cloudinit/util.py +@@ -593,7 +593,7 @@ def system_info(): + if system == "linux": + linux_dist = info['dist'][0].lower() + if linux_dist in ( +- 'arch', 'centos', 'debian', 'fedora', 'rhel', 'suse'): ++ 'arch', 'centos', 'debian', 'fedora', 'rhel', 'suse', 'openEuler'): + var = linux_dist + elif linux_dist in ('ubuntu', 'linuxmint', 'mint'): + var = 'ubuntu' +diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl +index 50e3bd8..e3816f2 100644 +--- a/config/cloud.cfg.tmpl ++++ b/config/cloud.cfg.tmpl +@@ -21,7 +21,7 @@ + disable_root: true + {% endif %} + +-{% if variant in ["centos", "fedora", "rhel"] %} ++{% if variant in ["centos", "fedora", "rhel", "openEuler"] %} + mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2'] + resize_rootfs_tmp: /dev + ssh_pwauth: 0 +@@ -76,7 +76,7 @@ + - ssh-import-id + - locale + - set-passwords +-{% if variant in ["rhel", "fedora"] %} ++{% if variant in ["rhel", "fedora", "openEuler"] %} + - spacewalk + - yum-add-repo + {% endif %} +@@ -137,7 +137,7 @@ + # (not accessible to handlers/transforms) + system_info: + # This will affect which distro class gets used +-{% if variant in ["arch", "centos", "debian", "fedora", "freebsd", "rhel", "suse", "ubuntu"] %} ++{% if variant in ["arch", "centos", "debian", "fedora", "freebsd", "rhel", "suse", "ubuntu", "openEuler"] %} + distro: {{ variant }} + {% else %} + # Unknown/fallback distro. +@@ -185,7 +185,7 @@ + primary: http://ports.ubuntu.com/ubuntu-ports + security: http://ports.ubuntu.com/ubuntu-ports + ssh_svcname: ssh +-{% elif variant in ["arch", "centos", "fedora", "rhel", "suse"] %} ++{% elif variant in ["arch", "centos", "fedora", "rhel", "suse", "openEuler"] %} + # Default user name + that default users groups (if added/used) + default_user: + name: {{ variant }} +diff --git a/systemd/cloud-init.service.tmpl b/systemd/cloud-init.service.tmpl +index b92e8ab..f59d4fd 100644 +--- a/systemd/cloud-init.service.tmpl ++++ b/systemd/cloud-init.service.tmpl +@@ -10,7 +10,7 @@ After=systemd-networkd-wait-online.service + {% if variant in ["ubuntu", "unknown", "debian"] %} + After=networking.service + {% endif %} +-{% if variant in ["centos", "fedora", "redhat"] %} ++{% if variant in ["centos", "fedora", "redhat", "openEuler"] %} + After=network.service + After=NetworkManager.service + {% endif %} +diff --git a/tests/cloud_tests/util.py b/tests/cloud_tests/util.py +index 4357fbb..7d3034d 100644 +--- a/tests/cloud_tests/util.py ++++ b/tests/cloud_tests/util.py +@@ -18,7 +18,7 @@ from tests.cloud_tests import LOG + + OS_FAMILY_MAPPING = { + 'debian': ['debian', 'ubuntu'], +- 'redhat': ['centos', 'rhel', 'fedora'], ++ 'redhat': ['centos', 'rhel', 'fedora', 'openEuler'], + 'gentoo': ['gentoo'], + 'freebsd': ['freebsd'], + 'suse': ['sles'], +diff --git a/tools/render-cloudcfg b/tools/render-cloudcfg +index 91d074b..7a8a2c4 100755 +--- a/tools/render-cloudcfg ++++ b/tools/render-cloudcfg +@@ -5,7 +5,7 @@ import argparse + import sys + + VARIANTS = ["arch", "centos", "debian", "fedora", "freebsd", "rhel", "suse", +- "ubuntu", "unknown"] ++ "ubuntu", "unknown", "openEuler"] + + if "avoid-pep8-E402-import-not-top-of-file": + _tdir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +diff --git a/cloudinit/distros/openEuler.py b/cloudinit/distros/openEuler.py +new file mode 100644 +index 0000000..5ac4700 +--- /dev/null ++++ b/cloudinit/distros/openEuler.py +@@ -0,0 +1,12 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. ++# This file is part of cloud-init. See LICENSE file for license information. ++ ++from cloudinit.distros import rhel ++from cloudinit import log as logging ++ ++LOG = logging.getLogger(__name__) ++ ++class Distro(rhel.Distro): ++ pass ++ ++# vi: ts=4 expandtab diff --git a/bugfix-sort-requirements.patch b/bugfix-sort-requirements.patch index a0a46b2ba77cd02b9ac9c1129c82267cb24027b0..8873cdf882734b0a99ec7000e82379a92bccf4fb 100644 --- a/bugfix-sort-requirements.patch +++ b/bugfix-sort-requirements.patch @@ -1,24 +1,23 @@ -From ef3f0c73fd940accf732f94cace4d53fc1604142 Mon Sep 17 00:00:00 2001 -From: chengquan -Date: Thu, 8 Aug 2019 16:14:06 +0800 -Subject: [PATCH] sort requirements - -reason: sort requirements in setup - -Signed-off-by: chengquan ---- - cloud-init-17.1/setup.py | 1 + - 1 file changed, 1 insertion(+) - -diff -Nur cloud-init-17.1_bak/setup.py cloud-init-17.1/setup.py ---- cloud-init-17.1_bak/setup.py 2019-04-11 20:27:41.526622810 +0800 -+++ cloud-init-17.1/setup.py 2019-04-11 20:28:21.734622815 +0800 -@@ -232,6 +232,7 @@ - } - - requirements = read_requires() -+requirements.sort() - - setuptools.setup( - name='cloud-init', - +From ef3f0c73fd940accf732f94cace4d53fc1604142 Mon Sep 17 00:00:00 2001 +From: chengquan +Date: Thu, 8 Aug 2019 16:14:06 +0800 +Subject: [PATCH] sort requirements + +reason: sort requirements in setup + +Signed-off-by: chengquan +--- + cloud-init-19.4/setup.py | 1 + + 1 file changed, 1 insertion(+) + +diff -Nur a/setup.py b/setup.py +--- a/setup.py 2019-04-11 20:27:41.526622810 +0800 ++++ b/setup.py 2019-04-11 20:28:21.734622815 +0800 +@@ -289,6 +289,7 @@ + } + + requirements = read_requires() ++requirements.sort() + + setuptools.setup( + name='cloud-init', diff --git a/cloud-init-17.1-disable-lxd-tests.patch b/cloud-init-17.1-disable-lxd-tests.patch deleted file mode 100644 index 956265ad125d9b98ed7da1f7d8c852ac6ef460c3..0000000000000000000000000000000000000000 --- a/cloud-init-17.1-disable-lxd-tests.patch +++ /dev/null @@ -1,17 +0,0 @@ -Index: cloud-init-17.1/tests/cloud_tests/platforms/__init__.py -=================================================================== ---- cloud-init-17.1.orig/tests/cloud_tests/platforms/__init__.py -+++ cloud-init-17.1/tests/cloud_tests/platforms/__init__.py -@@ -2,12 +2,10 @@ - - """Main init.""" - --from tests.cloud_tests.platforms import lxd - from tests.cloud_tests.platforms import nocloudkvm - - PLATFORMS = { - 'nocloud-kvm': nocloudkvm.NoCloudKVMPlatform, -- 'lxd': lxd.LXDPlatform, - } - - diff --git a/cloud-init-17.1-no-override-default-network.patch b/cloud-init-17.1-no-override-default-network.patch deleted file mode 100644 index 7c21c83f5badceb5970591c8265cec58b654dd82..0000000000000000000000000000000000000000 --- a/cloud-init-17.1-no-override-default-network.patch +++ /dev/null @@ -1,200 +0,0 @@ -diff -rup cloud-init-17.1.orig/cloudinit/net/sysconfig.py cloud-init-17.1/cloudinit/net/sysconfig.py ---- cloud-init-17.1.orig/cloudinit/net/sysconfig.py 2018-03-26 19:22:35.693111559 +0200 -+++ cloud-init-17.1/cloudinit/net/sysconfig.py 2018-03-26 23:47:41.424803588 +0200 -@@ -586,7 +586,17 @@ class Renderer(renderer.Renderer): - - # always write /etc/sysconfig/network configuration - sysconfig_path = util.target_path(target, "etc/sysconfig/network") -- netcfg = [_make_header(), 'NETWORKING=yes'] -+ # Make sure that existing lines, other than overriding ones, remain -+ netcfg = [] -+ for line in util.load_file(sysconfig_path, quiet=True).split('\n'): -+ if 'cloud-init' in line: -+ break -+ if not line.startswith(('NETWORKING=', -+ 'IPV6_AUTOCONF=', -+ 'NETWORKING_IPV6=')): -+ netcfg.append(line) -+ # Now generate the cloud-init portion of sysconfig/network -+ netcfg.extend([_make_header(), 'NETWORKING=yes']) - if network_state.use_ipv6: - netcfg.append('NETWORKING_IPV6=yes') - netcfg.append('IPV6_AUTOCONF=no') -diff -rup cloud-init-17.1.orig/tests/unittests/test_distros/test_netconfig.py cloud-init-17.1/tests/unittests/test_distros/test_netconfig.py ---- cloud-init-17.1.orig/tests/unittests/test_distros/test_netconfig.py 2018-03-26 19:22:35.717111557 +0200 -+++ cloud-init-17.1/tests/unittests/test_distros/test_netconfig.py 2018-03-26 22:08:25.008717651 +0200 -@@ -384,6 +384,82 @@ hn0: flags=8843 +Date: Fri, 21 Feb 2020 10:52:26 +0100 +Subject: [PATCH] Disable LXD tests + +Signed-off-by: Eduardo Otubo +--- + tests/cloud_tests/platforms/__init__.py | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/tests/cloud_tests/platforms/__init__.py b/tests/cloud_tests/platforms/__init__.py +index 6a410b84..2076d1c7 100644 +--- a/tests/cloud_tests/platforms/__init__.py ++++ b/tests/cloud_tests/platforms/__init__.py +@@ -3,14 +3,12 @@ + """Main init.""" + + from .ec2 import platform as ec2 +-from .lxd import platform as lxd + from .nocloudkvm import platform as nocloudkvm + from .azurecloud import platform as azurecloud + + PLATFORMS = { + 'ec2': ec2.EC2Platform, + 'nocloud-kvm': nocloudkvm.NoCloudKVMPlatform, +- 'lxd': lxd.LXDPlatform, + 'azurecloud': azurecloud.AzureCloudPlatform, + } + +-- +2.17.2 + diff --git a/cloud-init-17.1-nm-controlled.patch b/cloud-init-19.4-nm-controlled.patch similarity index 31% rename from cloud-init-17.1-nm-controlled.patch rename to cloud-init-19.4-nm-controlled.patch index 668d63e69dfd466701a69e2d47cd7dad7b08efc1..1f7b26dbc376d6d6b7cf616085426d9c6294f13f 100644 --- a/cloud-init-17.1-nm-controlled.patch +++ b/cloud-init-19.4-nm-controlled.patch @@ -1,291 +1,540 @@ -Index: cloud-init-17.1/cloudinit/net/sysconfig.py -=================================================================== ---- cloud-init-17.1.orig/cloudinit/net/sysconfig.py -+++ cloud-init-17.1/cloudinit/net/sysconfig.py -@@ -230,7 +230,6 @@ class Renderer(renderer.Renderer): +From 98657d64a1d40769b31fcf375ebb1ea0b373350c Mon Sep 17 00:00:00 2001 +From: Eduardo Otubo +Date: Fri, 21 Feb 2020 11:10:09 +0100 +Subject: [PATCH] Do not write NM_CONTROLLED=no in generated interface config + files + +Signed-off-by: Eduardo Otubo +--- + cloudinit/net/sysconfig.py | 1 - + .../unittests/test_distros/test_netconfig.py | 8 --- + tests/unittests/test_net.py | 55 ------------------- + 3 files changed, 64 deletions(-) + +diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py +index 310cdf01..8bd7e887 100644 +--- a/cloudinit/net/sysconfig.py ++++ b/cloudinit/net/sysconfig.py +@@ -272,7 +272,6 @@ class Renderer(renderer.Renderer): iface_defaults = tuple([ ('ONBOOT', True), ('USERCTL', False), - ('NM_CONTROLLED', False), ('BOOTPROTO', 'none'), + ('STARTMODE', 'auto'), ]) - -Index: cloud-init-17.1/tests/unittests/test_net.py -=================================================================== ---- cloud-init-17.1.orig/tests/unittests/test_net.py -+++ cloud-init-17.1/tests/unittests/test_net.py -@@ -146,7 +146,6 @@ GATEWAY=172.19.3.254 +diff --git a/tests/unittests/test_distros/test_netconfig.py b/tests/unittests/test_distros/test_netconfig.py +index 67209955..1df3bfb5 100644 +--- a/tests/unittests/test_distros/test_netconfig.py ++++ b/tests/unittests/test_distros/test_netconfig.py +@@ -466,7 +466,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): + GATEWAY=192.168.1.254 + IPADDR=192.168.1.5 + NETMASK=255.255.255.0 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -475,7 +474,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): + self.ifcfg_path('eth1'): dedent("""\ + BOOTPROTO=dhcp + DEVICE=eth1 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -500,7 +498,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): + 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 +@@ -509,7 +506,6 @@ class TestNetCfgDistroRedhat(TestNetCfgDistroBase): + self.ifcfg_path('eth1'): dedent("""\ + BOOTPROTO=dhcp + DEVICE=eth1 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -562,7 +558,6 @@ class TestNetCfgDistroOpensuse(TestNetCfgDistroBase): + GATEWAY=192.168.1.254 + IPADDR=192.168.1.5 + NETMASK=255.255.255.0 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -571,7 +566,6 @@ class TestNetCfgDistroOpensuse(TestNetCfgDistroBase): + self.ifcfg_path('eth1'): dedent("""\ + BOOTPROTO=dhcp + DEVICE=eth1 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -593,7 +587,6 @@ class TestNetCfgDistroOpensuse(TestNetCfgDistroBase): + 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 +@@ -602,7 +595,6 @@ class TestNetCfgDistroOpensuse(TestNetCfgDistroBase): + self.ifcfg_path('eth1'): dedent("""\ + BOOTPROTO=dhcp + DEVICE=eth1 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py +index 01119e0a..40427461 100644 +--- a/tests/unittests/test_net.py ++++ b/tests/unittests/test_net.py +@@ -496,7 +496,6 @@ GATEWAY=172.19.3.254 HWADDR=fa:16:3e:ed:9a:59 IPADDR=172.19.1.34 NETMASK=255.255.252.0 -NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no -@@ -214,7 +213,6 @@ IPADDR=172.19.1.34 +@@ -530,7 +529,6 @@ GATEWAY=172.19.3.254 + HWADDR=fa:16:3e:ed:9a:59 + IPADDR=172.19.1.34 + NETMASK=255.255.252.0 +-NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -600,7 +598,6 @@ IPADDR=172.19.1.34 IPADDR1=10.0.0.10 NETMASK=255.255.252.0 NETMASK1=255.255.255.0 -NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -636,7 +633,6 @@ IPADDR=172.19.1.34 + IPADDR1=10.0.0.10 + NETMASK=255.255.252.0 + NETMASK1=255.255.255.0 +-NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -731,7 +727,6 @@ IPV6ADDR_SECONDARIES="2001:DB9::10/64 2001:DB10::10/64" + IPV6INIT=yes + IPV6_DEFAULTGW=2001:DB8::1 + NETMASK=255.255.252.0 +-NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no -@@ -304,7 +302,6 @@ IPV6ADDR_SECONDARIES="2001:DB9::10/64 20 +@@ -772,7 +767,6 @@ IPV6ADDR_SECONDARIES="2001:DB9::10/64 2001:DB10::10/64" IPV6INIT=yes IPV6_DEFAULTGW=2001:DB8::1 NETMASK=255.255.252.0 -NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no -@@ -428,7 +425,6 @@ NETWORK_CONFIGS = { +@@ -889,7 +883,6 @@ NETWORK_CONFIGS = { BOOTPROTO=none DEVICE=eth1 HWADDR=cf:d6:af:48:e8:80 - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no"""), -@@ -440,7 +436,6 @@ NETWORK_CONFIGS = { - HWADDR=c0:d6:9f:2c:e8:80 +@@ -907,7 +900,6 @@ NETWORK_CONFIGS = { IPADDR=192.168.21.3 NETMASK=255.255.255.0 + METRIC=10000 - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no"""), -@@ -552,7 +547,6 @@ NETWORK_CONFIGS = { +@@ -1022,7 +1014,6 @@ NETWORK_CONFIGS = { IPV6ADDR=2001:1::1/64 IPV6INIT=yes NETMASK=255.255.255.0 - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -1062,7 +1053,6 @@ NETWORK_CONFIGS = { + DHCPV6C=yes + IPV6INIT=yes + DEVICE=iface0 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -1111,7 +1101,6 @@ NETWORK_CONFIGS = { + IPV6INIT=yes + IPV6_FORCE_ACCEPT_RA=yes + DEVICE=iface0 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -1160,7 +1149,6 @@ NETWORK_CONFIGS = { + IPV6INIT=yes + IPV6_FORCE_ACCEPT_RA=no + DEVICE=iface0 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -1199,7 +1187,6 @@ NETWORK_CONFIGS = { + IPV6_AUTOCONF=yes + IPV6INIT=yes + DEVICE=iface0 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no -@@ -794,14 +788,12 @@ pre-down route del -net 10.0.0.0 netmask +@@ -1240,7 +1227,6 @@ NETWORK_CONFIGS = { + IPV6_AUTOCONF=yes + IPV6INIT=yes + DEVICE=iface0 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -1281,7 +1267,6 @@ NETWORK_CONFIGS = { + IPV6INIT=yes + IPV6_FORCE_ACCEPT_RA=yes + DEVICE=iface0 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -1491,7 +1476,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true DHCPV6C=yes IPV6INIT=yes MACADDR=aa:bb:cc:dd:ee:ff - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Bond - USERCTL=no"""), - 'ifcfg-bond0.200': textwrap.dedent("""\ +@@ -1500,7 +1484,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true BOOTPROTO=dhcp DEVICE=bond0.200 + DHCLIENT_SET_DEFAULT_ROUTE=no - NM_CONTROLLED=no ONBOOT=yes PHYSDEV=bond0 - TYPE=Ethernet -@@ -817,7 +809,6 @@ pre-down route del -net 10.0.0.0 netmask - IPV6INIT=yes + STARTMODE=auto +@@ -1519,7 +1502,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true IPV6_DEFAULTGW=2001:4800:78ff:1b::1 + MACADDR=bb:bb:bb:bb:bb:aa NETMASK=255.255.255.0 - NM_CONTROLLED=no ONBOOT=yes PRIO=22 - STP=off -@@ -827,7 +818,6 @@ pre-down route del -net 10.0.0.0 netmask + STARTMODE=auto +@@ -1530,7 +1512,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true BOOTPROTO=none DEVICE=eth0 HWADDR=c0:d6:9f:2c:e8:80 - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no"""), -@@ -841,7 +831,6 @@ pre-down route del -net 10.0.0.0 netmask +@@ -1548,7 +1529,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true MTU=1500 NETMASK=255.255.255.0 NETMASK1=255.255.255.0 - NM_CONTROLLED=no ONBOOT=yes PHYSDEV=eth0 - TYPE=Ethernet -@@ -852,7 +841,6 @@ pre-down route del -net 10.0.0.0 netmask + STARTMODE=auto +@@ -1560,7 +1540,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true DEVICE=eth1 HWADDR=aa:d6:9f:2c:e8:80 MASTER=bond0 - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto SLAVE=yes - TYPE=Ethernet -@@ -862,7 +850,6 @@ pre-down route del -net 10.0.0.0 netmask +@@ -1571,7 +1550,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true DEVICE=eth2 HWADDR=c0:bb:9f:2c:e8:80 MASTER=bond0 - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto SLAVE=yes - TYPE=Ethernet -@@ -872,7 +859,6 @@ pre-down route del -net 10.0.0.0 netmask +@@ -1582,7 +1560,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true BRIDGE=br0 DEVICE=eth3 HWADDR=66:bb:9f:2c:e8:80 - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no"""), -@@ -881,7 +867,6 @@ pre-down route del -net 10.0.0.0 netmask +@@ -1592,7 +1569,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true BRIDGE=br0 DEVICE=eth4 HWADDR=98:bb:9f:2c:e8:80 - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no"""), -@@ -889,7 +874,6 @@ pre-down route del -net 10.0.0.0 netmask - BOOTPROTO=dhcp +@@ -1602,7 +1578,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true DEVICE=eth5 + DHCLIENT_SET_DEFAULT_ROUTE=no HWADDR=98:bb:9f:2c:e8:8a - NM_CONTROLLED=no ONBOOT=no + STARTMODE=manual TYPE=Ethernet - USERCTL=no""") -@@ -1171,7 +1155,6 @@ pre-down route del -net 10.0.0.0 netmask - IPV6INIT=yes +@@ -1614,7 +1589,6 @@ pre-down route del -net 10.0.0.0/8 gw 11.0.0.1 metric 3 || true + IPADDR=192.168.200.7 + MTU=9000 + NETMASK=255.255.255.0 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=InfiniBand +@@ -2027,7 +2001,6 @@ iface bond0 inet6 static + MTU=9000 NETMASK=255.255.255.0 NETMASK1=255.255.255.0 - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Bond - USERCTL=no -@@ -1181,7 +1164,6 @@ pre-down route del -net 10.0.0.0 netmask +@@ -2038,7 +2011,6 @@ iface bond0 inet6 static DEVICE=bond0s0 HWADDR=aa:bb:cc:dd:e8:00 MASTER=bond0 - NM_CONTROLLED=no ONBOOT=yes SLAVE=yes - TYPE=Ethernet -@@ -1199,7 +1181,6 @@ pre-down route del -net 10.0.0.0 netmask + STARTMODE=auto +@@ -2055,7 +2027,6 @@ iface bond0 inet6 static DEVICE=bond0s1 HWADDR=aa:bb:cc:dd:e8:01 MASTER=bond0 - NM_CONTROLLED=no ONBOOT=yes SLAVE=yes - TYPE=Ethernet -@@ -1236,7 +1217,6 @@ pre-down route del -net 10.0.0.0 netmask + STARTMODE=auto +@@ -2088,7 +2059,6 @@ iface bond0 inet6 static + MTU=9000 + NETMASK=255.255.255.0 + NETMASK1=255.255.255.0 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Bond +@@ -2099,7 +2069,6 @@ iface bond0 inet6 static + DEVICE=bond0s0 + HWADDR=aa:bb:cc:dd:e8:00 + MASTER=bond0 +- NM_CONTROLLED=no + ONBOOT=yes + SLAVE=yes + STARTMODE=auto +@@ -2122,7 +2091,6 @@ iface bond0 inet6 static + DEVICE=bond0s1 + HWADDR=aa:bb:cc:dd:e8:01 + MASTER=bond0 +- NM_CONTROLLED=no + ONBOOT=yes + SLAVE=yes + STARTMODE=auto +@@ -2161,7 +2129,6 @@ iface bond0 inet6 static BOOTPROTO=none DEVICE=en0 HWADDR=aa:bb:cc:dd:e8:00 - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no"""), -@@ -1252,7 +1232,6 @@ pre-down route del -net 10.0.0.0 netmask - IPV6_DEFAULTGW=2001:1::1 +@@ -2180,7 +2147,6 @@ iface bond0 inet6 static + MTU=2222 NETMASK=255.255.255.0 NETMASK1=255.255.255.0 - NM_CONTROLLED=no ONBOOT=yes PHYSDEV=en0 - TYPE=Ethernet -@@ -1293,7 +1272,6 @@ pre-down route del -net 10.0.0.0 netmask + STARTMODE=auto +@@ -2222,7 +2188,6 @@ iface bond0 inet6 static DEVICE=br0 IPADDR=192.168.2.2 NETMASK=255.255.255.0 - NM_CONTROLLED=no ONBOOT=yes PRIO=22 - STP=off -@@ -1307,7 +1285,6 @@ pre-down route del -net 10.0.0.0 netmask - HWADDR=52:54:00:12:34:00 + STARTMODE=auto +@@ -2238,7 +2203,6 @@ iface bond0 inet6 static + IPADDR6=2001:1::100/96 IPV6ADDR=2001:1::100/96 IPV6INIT=yes - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no -@@ -1319,7 +1296,6 @@ pre-down route del -net 10.0.0.0 netmask - HWADDR=52:54:00:12:34:01 +@@ -2252,7 +2216,6 @@ iface bond0 inet6 static + IPADDR6=2001:1::101/96 IPV6ADDR=2001:1::101/96 IPV6INIT=yes - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no -@@ -1393,7 +1369,6 @@ pre-down route del -net 10.0.0.0 netmask +@@ -2327,7 +2290,6 @@ iface bond0 inet6 static HWADDR=52:54:00:12:34:00 IPADDR=192.168.1.2 NETMASK=255.255.255.0 - NM_CONTROLLED=no ONBOOT=no + STARTMODE=manual TYPE=Ethernet - USERCTL=no -@@ -1403,7 +1378,6 @@ pre-down route del -net 10.0.0.0 netmask +@@ -2338,7 +2300,6 @@ iface bond0 inet6 static DEVICE=eth1 HWADDR=52:54:00:12:34:aa MTU=1480 - NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no -@@ -1412,7 +1386,6 @@ pre-down route del -net 10.0.0.0 netmask +@@ -2348,7 +2309,6 @@ iface bond0 inet6 static BOOTPROTO=none DEVICE=eth2 HWADDR=52:54:00:12:34:ff - NM_CONTROLLED=no ONBOOT=no + STARTMODE=manual TYPE=Ethernet - USERCTL=no -@@ -1685,7 +1658,6 @@ class TestSysConfigRendering(CiTestCase) +@@ -2766,7 +2726,6 @@ class TestRhelSysConfigRendering(CiTestCase): BOOTPROTO=dhcp DEVICE=eth1000 - HWADDR=07-1C-C6-75-A4-BE + HWADDR=07-1c-c6-75-a4-be -NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no -@@ -1805,7 +1777,6 @@ GATEWAY=10.0.2.2 +@@ -2888,7 +2847,6 @@ GATEWAY=10.0.2.2 HWADDR=52:54:00:12:34:00 IPADDR=10.0.2.15 NETMASK=255.255.255.0 -NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no -@@ -1826,7 +1797,6 @@ USERCTL=no - # - BOOTPROTO=dhcp - DEVICE=eth0 +@@ -2920,7 +2878,6 @@ HWADDR=fa:16:3e:25:b4:59 + IPADDR=51.68.89.122 + MTU=1500 + NETMASK=255.255.240.0 -NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no -Index: cloud-init-17.1/tests/unittests/test_distros/test_netconfig.py -=================================================================== ---- cloud-init-17.1.orig/tests/unittests/test_distros/test_netconfig.py -+++ cloud-init-17.1/tests/unittests/test_distros/test_netconfig.py -@@ -481,7 +481,6 @@ DEVICE=eth0 - GATEWAY=192.168.1.254 - IPADDR=192.168.1.5 - NETMASK=255.255.255.0 +@@ -2935,7 +2892,6 @@ DEVICE=eth1 + DHCLIENT_SET_DEFAULT_ROUTE=no + HWADDR=fa:16:3e:b1:ca:29 + MTU=9000 -NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no -@@ -498,7 +497,6 @@ USERCTL=no +@@ -2961,7 +2917,6 @@ USERCTL=no # BOOTPROTO=dhcp - DEVICE=eth1 + DEVICE=eth0 -NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no -@@ -632,7 +630,6 @@ DEVICE=eth0 - IPV6ADDR=2607:f0d0:1002:0011::2/64 - IPV6INIT=yes - IPV6_DEFAULTGW=2607:f0d0:1002:0011::1 +@@ -3168,7 +3123,6 @@ USERCTL=no + IPV6INIT=yes + IPV6_DEFAULTGW=2001:db8::1 + NETMASK=255.255.255.0 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -3194,7 +3148,6 @@ USERCTL=no + 'ifcfg-eno1': textwrap.dedent("""\ + BOOTPROTO=none + DEVICE=eno1 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -3206,7 +3159,6 @@ USERCTL=no + IPADDR=192.6.1.9 + MTU=1495 + NETMASK=255.255.255.0 +- NM_CONTROLLED=no + ONBOOT=yes + PHYSDEV=eno1 + STARTMODE=auto +@@ -3238,7 +3190,6 @@ USERCTL=no + IPADDR=10.101.8.65 + MTU=1334 + NETMASK=255.255.255.192 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Bond +@@ -3249,7 +3200,6 @@ USERCTL=no + BOOTPROTO=none + DEVICE=enp0s0 + MASTER=bond0 +- NM_CONTROLLED=no + ONBOOT=yes + SLAVE=yes + STARTMODE=auto +@@ -3261,7 +3211,6 @@ USERCTL=no + BOOTPROTO=none + DEVICE=enp0s1 + MASTER=bond0 +- NM_CONTROLLED=no + ONBOOT=yes + SLAVE=yes + STARTMODE=auto +@@ -3286,7 +3235,6 @@ USERCTL=no + DEVICE=eno1 + HWADDR=07-1c-c6-75-a4-be + METRIC=100 +- NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -3386,7 +3334,6 @@ class TestOpenSuseSysConfigRendering(CiTestCase): + BOOTPROTO=dhcp + DEVICE=eth1000 + HWADDR=07-1c-c6-75-a4-be +-NM_CONTROLLED=no + ONBOOT=yes + STARTMODE=auto + TYPE=Ethernet +@@ -3508,7 +3455,6 @@ GATEWAY=10.0.2.2 + HWADDR=52:54:00:12:34:00 + IPADDR=10.0.2.15 + NETMASK=255.255.255.0 -NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no -@@ -647,7 +644,6 @@ USERCTL=no +@@ -3538,7 +3484,6 @@ USERCTL=no # BOOTPROTO=dhcp - DEVICE=eth1 + DEVICE=eth0 -NM_CONTROLLED=no ONBOOT=yes + STARTMODE=auto TYPE=Ethernet - USERCTL=no +-- +2.17.2 + diff --git a/cloud-init-19.4-no-override-default-network.patch b/cloud-init-19.4-no-override-default-network.patch new file mode 100644 index 0000000000000000000000000000000000000000..b7934ba700ee6a5202ea81d9ee78ebd991c80412 --- /dev/null +++ b/cloud-init-19.4-no-override-default-network.patch @@ -0,0 +1,36 @@ +From 674873573abf2b6e10b09d533a58437c35d508f8 Mon Sep 17 00:00:00 2001 +From: Eduardo Otubo +Date: Fri, 21 Feb 2020 11:40:34 +0100 +Subject: [PATCH] Don't override default network configuration + +Signed-off-by: Eduardo Otubo +--- + cloudinit/net/sysconfig.py | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py +index 310cdf01..87b8f743 100644 +--- a/cloudinit/net/sysconfig.py ++++ b/cloudinit/net/sysconfig.py +@@ -755,7 +755,17 @@ class Renderer(renderer.Renderer): + # Distros configuring /etc/sysconfig/network as a file e.g. Centos + if sysconfig_path.endswith('network'): + util.ensure_dir(os.path.dirname(sysconfig_path)) +- netcfg = [_make_header(), 'NETWORKING=yes'] ++ # Make sure that existing lines, other than overriding ones, remain ++ netcfg = [] ++ for line in util.load_file(sysconfig_path, quiet=True).split('\n'): ++ if 'cloud-init' in line: ++ break ++ if not line.startswith(('NETWORKING=', ++ 'IPV6_AUTOCONF=', ++ 'NETWORKING_IPV6=')): ++ netcfg.append(line) ++ # Now generate the cloud-init portion of sysconfig/network ++ netcfg.extend([_make_header(), 'NETWORKING=yes']) + if network_state.use_ipv6: + netcfg.append('NETWORKING_IPV6=yes') + netcfg.append('IPV6_AUTOCONF=no') +-- +2.17.2 + diff --git a/cloud-init-19.4.tar.gz b/cloud-init-19.4.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..22d52ad6f2b2c9e93786af36d68ef55d4d5cb28d Binary files /dev/null and b/cloud-init-19.4.tar.gz differ diff --git a/cloud-init.spec b/cloud-init.spec index 712c1b426152280c095d9bea5cb694d60567cbb4..60d38c85e6754661face74a9b776a4910a3f8b25 100644 --- a/cloud-init.spec +++ b/cloud-init.spec @@ -1,29 +1,18 @@ Name: cloud-init -Version: 17.1 -Release: 12 +Version: 19.4 +Release: 1 Summary: the defacto multi-distribution package that handles early initialization of a cloud instance. License: ASL 2.0 or GPLv3 URL: http://launchpad.net/cloud-init Source0: https://launchpad.net/%{name}/trunk/%{version}/+download/%{name}-%{version}.tar.gz - Source1: cloud-init-tmpfiles.conf -Patch0: cloud-init-17.1-disable-lxd-tests.patch -Patch1: cloud-init-17.1-nm-controlled.patch -Patch2: cloud-init-17.1-no-override-default-network.patch - -Patch6000: EC2-Limit-network-config-to-fallback-nic-fix-local-i.patch -Patch6001: ntp-fix-config-module-schema-to-allow-empty-ntp-conf.patch -Patch6002: resizefs-Fix-regression-when-system-booted-with-root.patch -Patch6003: hosts-Fix-openSUSE-and-SLES-setup-for-etc-hosts-and-.patch -Patch6004: EC2-Fix-bug-using-fallback_nic-and-metadata-when-res.patch -Patch6005: Fix-ssh-keys-validation-in-ssh_util.patch -Patch6006: stages-fix-tracebacks-if-a-module-stage-is-undefined.patch -Patch6007: stages-Fix-bug-causing-datasource-to-have-incorrect-.patch - -Patch9000: bugfix-cloud-init-add-openEuler-os.patch -Patch9001: bugfix-sort-requirements.patch -Patch9002: add-variable-to-forbid-tmp-dir.patch +Patch0: cloud-init-19.4-disable-lxd-tests.patch +Patch1: cloud-init-19.4-nm-controlled.patch +Patch2: cloud-init-19.4-no-override-default-network.patch +Patch3: bugfix-cloud-init-add-openEuler-os.patch +Patch4: bugfix-sort-requirements.patch +Patch5: add-variable-to-forbid-tmp-dir.patch BuildRequires: pkgconfig(systemd) python3-devel python3-setuptools systemd BuildRequires: iproute python3-configobj python3-httpretty >= 0.8.14-2 @@ -117,9 +106,11 @@ fi %{_tmpfilesdir}/%{name}.conf %{_libexecdir}/%{name} %{_bindir}/cloud-init* +%{_bindir}/cloud-id %{python3_sitelib}/* %dir /run/%{name} %dir /var/lib/cloud +%{_datadir}/bash-completion/completions/cloud-init %files help %doc doc/* @@ -128,6 +119,9 @@ fi %exclude /usr/share/doc/* %changelog +* Mon Aug 3 2020 chengquan - 19.4-1 +- Update software to v19.4 + * Sat Mar 14 2020 chengquan - 17.1-12 - Type:bugfix - ID:NA diff --git a/cloud-init.yaml b/cloud-init.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e743a94399c06aa0d8b3d366996a91bf506387ff --- /dev/null +++ b/cloud-init.yaml @@ -0,0 +1,4 @@ +version_control: github +src_repo: canonical/cloud-init +tag_prefix: +seperator: "." diff --git a/hosts-Fix-openSUSE-and-SLES-setup-for-etc-hosts-and-.patch b/hosts-Fix-openSUSE-and-SLES-setup-for-etc-hosts-and-.patch deleted file mode 100644 index d9eb27d3df9479c3427e89326c3f87e025c21c7e..0000000000000000000000000000000000000000 --- a/hosts-Fix-openSUSE-and-SLES-setup-for-etc-hosts-and-.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 22a14a6a6d45ae55d2c2307d7b097eef9863bb0c Mon Sep 17 00:00:00 2001 -From: Robert Schweikert -Date: Wed, 8 Nov 2017 15:45:53 -0500 -Subject: [PATCH 035/354] hosts: Fix openSUSE and SLES setup for /etc/hosts - and clarify docs. - -The etc/hosts file is was not properly setup for openSUSE or SLES -when manage_etc_hosts is set in the config file. - -Improve the doc to address the fact that the 'localhost' ip is -distribution dependent (not always 127.0.0.1). - -LP: #1731022 ---- - cloudinit/config/cc_update_etc_hosts.py | 4 +- - templates/hosts.opensuse.tmpl | 26 -------- - templates/hosts.suse.tmpl | 10 +++- - .../test_handler/test_handler_etc_hosts.py | 69 ++++++++++++++++++++++ - 4 files changed, 79 insertions(+), 30 deletions(-) - delete mode 100644 templates/hosts.opensuse.tmpl - create mode 100644 tests/unittests/test_handler/test_handler_etc_hosts.py - -diff --git a/cloudinit/config/cc_update_etc_hosts.py b/cloudinit/config/cc_update_etc_hosts.py -index b394784..c96eede 100644 ---- a/cloudinit/config/cc_update_etc_hosts.py -+++ b/cloudinit/config/cc_update_etc_hosts.py -@@ -23,8 +23,8 @@ using the template located in ``/etc/cloud/templates/hosts.tmpl``. In the - - If ``manage_etc_hosts`` is set to ``localhost``, then cloud-init will not - rewrite ``/etc/hosts`` entirely, but rather will ensure that a entry for the --fqdn with ip ``127.0.1.1`` is present in ``/etc/hosts`` (i.e. --``ping `` will ping ``127.0.1.1``). -+fqdn with a distribution dependent ip is present in ``/etc/hosts`` (i.e. -+``ping `` will ping ``127.0.0.1`` or ``127.0.1.1`` or other ip). - - .. note:: - if ``manage_etc_hosts`` is set ``true`` or ``template``, the contents -diff --git a/templates/hosts.opensuse.tmpl b/templates/hosts.opensuse.tmpl -deleted file mode 100644 -index 655da3f..0000000 ---- a/templates/hosts.opensuse.tmpl -+++ /dev/null -@@ -1,26 +0,0 @@ --* -- This file /etc/cloud/templates/hosts.opensuse.tmpl is only utilized -- if enabled in cloud-config. Specifically, in order to enable it -- you need to add the following to config: -- manage_etc_hosts: True --*# --# Your system has configured 'manage_etc_hosts' as True. --# As a result, if you wish for changes to this file to persist --# then you will need to either --# a.) make changes to the master file in --# /etc/cloud/templates/hosts.opensuse.tmpl --# b.) change or remove the value of 'manage_etc_hosts' in --# /etc/cloud/cloud.cfg or cloud-config from user-data --# --# The following lines are desirable for IPv4 capable hosts --127.0.0.1 localhost -- --# The following lines are desirable for IPv6 capable hosts --::1 localhost ipv6-localhost ipv6-loopback --fe00::0 ipv6-localnet -- --ff00::0 ipv6-mcastprefix --ff02::1 ipv6-allnodes --ff02::2 ipv6-allrouters --ff02::3 ipv6-allhosts -- -diff --git a/templates/hosts.suse.tmpl b/templates/hosts.suse.tmpl -index b608269..8e664db 100644 ---- a/templates/hosts.suse.tmpl -+++ b/templates/hosts.suse.tmpl -@@ -13,12 +13,18 @@ you need to add the following to config: - # /etc/cloud/cloud.cfg or cloud-config from user-data - # - # The following lines are desirable for IPv4 capable hosts --127.0.0.1 localhost -+127.0.0.1 {{fqdn}} {{hostname}} -+127.0.0.1 localhost.localdomain localhost -+127.0.0.1 localhost4.localdomain4 localhost4 - - # The following lines are desirable for IPv6 capable hosts -+::1 {{fqdn}} {{hostname}} -+::1 localhost.localdomain localhost -+::1 localhost6.localdomain6 localhost6 - ::1 localhost ipv6-localhost ipv6-loopback --fe00::0 ipv6-localnet - -+ -+fe00::0 ipv6-localnet - ff00::0 ipv6-mcastprefix - ff02::1 ipv6-allnodes - ff02::2 ipv6-allrouters -diff --git a/tests/unittests/test_handler/test_handler_etc_hosts.py b/tests/unittests/test_handler/test_handler_etc_hosts.py -new file mode 100644 -index 0000000..ced05a8 ---- /dev/null -+++ b/tests/unittests/test_handler/test_handler_etc_hosts.py -@@ -0,0 +1,69 @@ -+# This file is part of cloud-init. See LICENSE file for license information. -+ -+from cloudinit.config import cc_update_etc_hosts -+ -+from cloudinit import cloud -+from cloudinit import distros -+from cloudinit import helpers -+from cloudinit import util -+ -+from cloudinit.tests import helpers as t_help -+ -+import logging -+import os -+import shutil -+ -+LOG = logging.getLogger(__name__) -+ -+ -+class TestHostsFile(t_help.FilesystemMockingTestCase): -+ def setUp(self): -+ super(TestHostsFile, self).setUp() -+ self.tmp = self.tmp_dir() -+ -+ def _fetch_distro(self, kind): -+ cls = distros.fetch(kind) -+ paths = helpers.Paths({}) -+ return cls(kind, {}, paths) -+ -+ def test_write_etc_hosts_suse_localhost(self): -+ cfg = { -+ 'manage_etc_hosts': 'localhost', -+ 'hostname': 'cloud-init.test.us' -+ } -+ os.makedirs('%s/etc/' % self.tmp) -+ hosts_content = '192.168.1.1 blah.blah.us blah\n' -+ fout = open('%s/etc/hosts' % self.tmp, 'w') -+ fout.write(hosts_content) -+ fout.close() -+ distro = self._fetch_distro('sles') -+ distro.hosts_fn = '%s/etc/hosts' % self.tmp -+ paths = helpers.Paths({}) -+ ds = None -+ cc = cloud.Cloud(ds, paths, {}, distro, None) -+ self.patchUtils(self.tmp) -+ cc_update_etc_hosts.handle('test', cfg, cc, LOG, []) -+ contents = util.load_file('%s/etc/hosts' % self.tmp) -+ if '127.0.0.1\tcloud-init.test.us\tcloud-init' not in contents: -+ self.assertIsNone('No entry for 127.0.0.1 in etc/hosts') -+ if '192.168.1.1\tblah.blah.us\tblah' not in contents: -+ self.assertIsNone('Default etc/hosts content modified') -+ -+ def test_write_etc_hosts_suse_template(self): -+ cfg = { -+ 'manage_etc_hosts': 'template', -+ 'hostname': 'cloud-init.test.us' -+ } -+ shutil.copytree('templates', '%s/etc/cloud/templates' % self.tmp) -+ distro = self._fetch_distro('sles') -+ paths = helpers.Paths({}) -+ paths.template_tpl = '%s' % self.tmp + '/etc/cloud/templates/%s.tmpl' -+ ds = None -+ cc = cloud.Cloud(ds, paths, {}, distro, None) -+ self.patchUtils(self.tmp) -+ cc_update_etc_hosts.handle('test', cfg, cc, LOG, []) -+ contents = util.load_file('%s/etc/hosts' % self.tmp) -+ if '127.0.0.1 cloud-init.test.us cloud-init' not in contents: -+ self.assertIsNone('No entry for 127.0.0.1 in etc/hosts') -+ if '::1 cloud-init.test.us cloud-init' not in contents: -+ self.assertIsNone('No entry for 127.0.0.1 in etc/hosts') --- -1.7.12.4 - diff --git a/ntp-fix-config-module-schema-to-allow-empty-ntp-conf.patch b/ntp-fix-config-module-schema-to-allow-empty-ntp-conf.patch deleted file mode 100644 index b2d4aa91c89c173923b2f62e825dcb523e239eda..0000000000000000000000000000000000000000 --- a/ntp-fix-config-module-schema-to-allow-empty-ntp-conf.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 6bc504e41666329631cdfd5b947ed5b0e2529a76 Mon Sep 17 00:00:00 2001 -From: Chad Smith -Date: Fri, 20 Oct 2017 13:24:22 -0600 -Subject: [PATCH 021/354] ntp: fix config module schema to allow empty ntp - config - -Fix three things related to the ntp module: - 1. Fix invalid cloud-config schema in the integration test which - provided empty dicts instead of emptylists for pools and servers - 2. Correct logic in the ntp module to allow support for the minimal - cloud-config 'ntp:' without raising a RuntimeError. Docs and schema - definitions already describe that cloud-config's ntp can be empty. - An ntp configuration with neither pools nor servers will be - configured with a default set of ntp pools. As such, the ntp module - now officially allows the following ntp cloud-configs: - - ntp: - - ntp: {} - - ntp: - servers: [] - pools: [] - 3. Add a simple unit test which validates all cloud-config provided to - our integration tests to ensure it adheres to any defined module - schema so as more jsonschema definitions are added, we validate our - integration test configs. - -LP: #1724951 ---- - cloudinit/config/cc_ntp.py | 4 ++- - tests/cloud_tests/testcases/modules/ntp.yaml | 4 +-- - tests/unittests/test_handler/test_handler_ntp.py | 23 ++++++++------- - tests/unittests/test_handler/test_schema.py | 37 +++++++++++++++++++++++- - 4 files changed, 53 insertions(+), 15 deletions(-) - -diff --git a/cloudinit/config/cc_ntp.py b/cloudinit/config/cc_ntp.py -index 15ae1ec..d43d060 100644 ---- a/cloudinit/config/cc_ntp.py -+++ b/cloudinit/config/cc_ntp.py -@@ -100,7 +100,9 @@ def handle(name, cfg, cloud, log, _args): - LOG.debug( - "Skipping module named %s, not present or disabled by cfg", name) - return -- ntp_cfg = cfg.get('ntp', {}) -+ ntp_cfg = cfg['ntp'] -+ if ntp_cfg is None: -+ ntp_cfg = {} # Allow empty config which will install the package - - # TODO drop this when validate_cloudconfig_schema is strict=True - if not isinstance(ntp_cfg, (dict)): -diff --git a/tests/cloud_tests/configs/modules/ntp.yaml b/tests/cloud_tests/configs/modules/ntp.yaml -index fbef431..2530d72 100644 ---- a/tests/cloud_tests/configs/modules/ntp.yaml -+++ b/tests/cloud_tests/configs/modules/ntp.yaml -@@ -4,8 +4,8 @@ - cloud_config: | - #cloud-config - ntp: -- pools: {} -- servers: {} -+ pools: [] -+ servers: [] - collect_scripts: - ntp_installed: | - #!/bin/bash -diff --git a/tests/unittests/test_handler/test_handler_ntp.py b/tests/unittests/test_handler/test_handler_ntp.py -index 4f29124..3abe578 100644 ---- a/tests/unittests/test_handler/test_handler_ntp.py -+++ b/tests/unittests/test_handler/test_handler_ntp.py -@@ -293,23 +293,24 @@ class TestNtp(FilesystemMockingTestCase): - - def test_ntp_handler_schema_validation_allows_empty_ntp_config(self): - """Ntp schema validation allows for an empty ntp: configuration.""" -- invalid_config = {'ntp': {}} -+ valid_empty_configs = [{'ntp': {}}, {'ntp': None}] - distro = 'ubuntu' - cc = self._get_cloud(distro) - ntp_conf = os.path.join(self.new_root, 'ntp.conf') - with open('{0}.tmpl'.format(ntp_conf), 'wb') as stream: - stream.write(NTP_TEMPLATE) -- with mock.patch('cloudinit.config.cc_ntp.NTP_CONF', ntp_conf): -- cc_ntp.handle('cc_ntp', invalid_config, cc, None, []) -+ for valid_empty_config in valid_empty_configs: -+ with mock.patch('cloudinit.config.cc_ntp.NTP_CONF', ntp_conf): -+ cc_ntp.handle('cc_ntp', valid_empty_config, cc, None, []) -+ with open(ntp_conf) as stream: -+ content = stream.read() -+ default_pools = [ -+ "{0}.{1}.pool.ntp.org".format(x, distro) -+ for x in range(0, cc_ntp.NR_POOL_SERVERS)] -+ self.assertEqual( -+ "servers []\npools {0}\n".format(default_pools), -+ content) - self.assertNotIn('Invalid config:', self.logs.getvalue()) -- with open(ntp_conf) as stream: -- content = stream.read() -- default_pools = [ -- "{0}.{1}.pool.ntp.org".format(x, distro) -- for x in range(0, cc_ntp.NR_POOL_SERVERS)] -- self.assertEqual( -- "servers []\npools {0}\n".format(default_pools), -- content) - - @skipIf(_missing_jsonschema_dep, "No python-jsonschema dependency") - def test_ntp_handler_schema_validation_warns_non_string_item_type(self): -diff --git a/tests/unittests/test_handler/test_schema.py b/tests/unittests/test_handler/test_schema.py -index b8fc893..648573f 100644 ---- a/tests/unittests/test_handler/test_schema.py -+++ b/tests/unittests/test_handler/test_schema.py -@@ -4,11 +4,12 @@ from cloudinit.config.schema import ( - CLOUD_CONFIG_HEADER, SchemaValidationError, annotated_cloudconfig_file, - get_schema_doc, get_schema, validate_cloudconfig_file, - validate_cloudconfig_schema, main) --from cloudinit.util import write_file -+from cloudinit.util import subp, write_file - - from cloudinit.tests.helpers import CiTestCase, mock, skipIf - - from copy import copy -+import os - from six import StringIO - from textwrap import dedent - from yaml import safe_load -@@ -364,4 +365,38 @@ class MainTest(CiTestCase): - self.assertIn( - 'Valid cloud-config file {0}'.format(myyaml), m_stdout.getvalue()) - -+ -+class CloudTestsIntegrationTest(CiTestCase): -+ """Validate all cloud-config yaml schema provided in integration tests. -+ -+ It is less expensive to have unittests validate schema of all cloud-config -+ yaml provided to integration tests, than to run an integration test which -+ raises Warnings or errors on invalid cloud-config schema. -+ """ -+ -+ @skipIf(_missing_jsonschema_dep, "No python-jsonschema dependency") -+ def test_all_integration_test_cloud_config_schema(self): -+ """Validate schema of cloud_tests yaml files looking for warnings.""" -+ schema = get_schema() -+ testsdir = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) -+ integration_testdir = os.path.sep.join( -+ [testsdir, 'cloud_tests', 'testcases']) -+ errors = [] -+ out, _ = subp(['find', integration_testdir, '-name', '*yaml']) -+ for filename in out.splitlines(): -+ test_cfg = safe_load(open(filename)) -+ cloud_config = test_cfg.get('cloud_config') -+ if cloud_config: -+ cloud_config = safe_load( -+ cloud_config.replace("#cloud-config\n", "")) -+ try: -+ validate_cloudconfig_schema( -+ cloud_config, schema, strict=True) -+ except SchemaValidationError as e: -+ errors.append( -+ '{0}: {1}'.format( -+ filename, e)) -+ if errors: -+ raise AssertionError(', '.join(errors)) -+ - # vi: ts=4 expandtab syntax=python --- -1.7.12.4 - diff --git a/resizefs-Fix-regression-when-system-booted-with-root.patch b/resizefs-Fix-regression-when-system-booted-with-root.patch deleted file mode 100644 index e12b2a4f1eae0384b6a53887e9a5d1f4a9ae5e19..0000000000000000000000000000000000000000 --- a/resizefs-Fix-regression-when-system-booted-with-root.patch +++ /dev/null @@ -1,322 +0,0 @@ -From 17a15f9e0ae78e4fc4e24fab0caebdf78f06ef66 Mon Sep 17 00:00:00 2001 -From: Chad Smith -Date: Mon, 23 Oct 2017 14:34:23 -0600 -Subject: [PATCH 025/354] resizefs: Fix regression when system booted with - root=PARTUUID= - -A recent cleanup of the resizefs module broke resizing when a system was -booted with root=PARTUUID= and the device /dev/root does not exist. -This path is exposed with the Ubuntu 16.04 but not with Ubuntu 17.10. A -recreate exists under bug 1684869. - -LP: #1725067 ---- - cloudinit/config/cc_resizefs.py | 43 ++++------ - .../test_handler/test_handler_resizefs.py | 91 ++++++++++++++-------- - 2 files changed, 70 insertions(+), 64 deletions(-) - -diff --git a/cloudinit/config/cc_resizefs.py b/cloudinit/config/cc_resizefs.py -index f774baa..0d282e6 100644 ---- a/cloudinit/config/cc_resizefs.py -+++ b/cloudinit/config/cc_resizefs.py -@@ -145,25 +145,6 @@ RESIZE_FS_PRECHECK_CMDS = { - } - - --def rootdev_from_cmdline(cmdline): -- found = None -- for tok in cmdline.split(): -- if tok.startswith("root="): -- found = tok[5:] -- break -- if found is None: -- return None -- -- if found.startswith("/dev/"): -- return found -- if found.startswith("LABEL="): -- return "/dev/disk/by-label/" + found[len("LABEL="):] -- if found.startswith("UUID="): -- return "/dev/disk/by-uuid/" + found[len("UUID="):] -- -- return "/dev/" + found -- -- - def can_skip_resize(fs_type, resize_what, devpth): - fstype_lc = fs_type.lower() - for i, func in RESIZE_FS_PRECHECK_CMDS.items(): -@@ -172,14 +153,15 @@ def can_skip_resize(fs_type, resize_what, devpth): - return False - - --def is_device_path_writable_block(devpath, info, log): -- """Return True if devpath is a writable block device. -+def maybe_get_writable_device_path(devpath, info, log): -+ """Return updated devpath if the devpath is a writable block device. - -- @param devpath: Path to the root device we want to resize. -+ @param devpath: Requested path to the root device we want to resize. - @param info: String representing information about the requested device. - @param log: Logger to which logs will be added upon error. - -- @returns Boolean True if block device is writable -+ @returns devpath or updated devpath per kernel commandline if the device -+ path is a writable block device, returns None otherwise. - """ - container = util.is_container() - -@@ -189,12 +171,12 @@ def is_device_path_writable_block(devpath, info, log): - devpath = util.rootdev_from_cmdline(util.get_cmdline()) - if devpath is None: - log.warn("Unable to find device '/dev/root'") -- return False -+ return None - log.debug("Converted /dev/root to '%s' per kernel cmdline", devpath) - - if devpath == 'overlayroot': - log.debug("Not attempting to resize devpath '%s': %s", devpath, info) -- return False -+ return None - - try: - statret = os.stat(devpath) -@@ -207,7 +189,7 @@ def is_device_path_writable_block(devpath, info, log): - devpath, info) - else: - raise exc -- return False -+ return None - - if not stat.S_ISBLK(statret.st_mode) and not stat.S_ISCHR(statret.st_mode): - if container: -@@ -216,8 +198,8 @@ def is_device_path_writable_block(devpath, info, log): - else: - log.warn("device '%s' not a block device. cannot resize: %s" % - (devpath, info)) -- return False -- return True -+ return None -+ return devpath # The writable block devpath - - - def handle(name, cfg, _cloud, log, args): -@@ -242,8 +224,9 @@ def handle(name, cfg, _cloud, log, args): - info = "dev=%s mnt_point=%s path=%s" % (devpth, mount_point, resize_what) - log.debug("resize_info: %s" % info) - -- if not is_device_path_writable_block(devpth, info, log): -- return -+ devpth = maybe_get_writable_device_path(devpth, info, log) -+ if not devpth: -+ return # devpath was not a writable block device - - resizer = None - if can_skip_resize(fs_type, resize_what, devpth): -diff --git a/tests/unittests/test_handler/test_handler_resizefs.py b/tests/unittests/test_handler/test_handler_resizefs.py -index 3e5d436..29d5574 100644 ---- a/tests/unittests/test_handler/test_handler_resizefs.py -+++ b/tests/unittests/test_handler/test_handler_resizefs.py -@@ -1,9 +1,9 @@ - # This file is part of cloud-init. See LICENSE file for license information. - - from cloudinit.config.cc_resizefs import ( -- can_skip_resize, handle, is_device_path_writable_block, -- rootdev_from_cmdline) -+ can_skip_resize, handle, maybe_get_writable_device_path) - -+from collections import namedtuple - import logging - import textwrap - -@@ -138,47 +138,48 @@ class TestRootDevFromCmdline(CiTestCase): - invalid_cases = [ - 'BOOT_IMAGE=/adsf asdfa werasef root adf', 'BOOT_IMAGE=/adsf', ''] - for case in invalid_cases: -- self.assertIsNone(rootdev_from_cmdline(case)) -+ self.assertIsNone(util.rootdev_from_cmdline(case)) - - def test_rootdev_from_cmdline_with_root_startswith_dev(self): - """Return the cmdline root when the path starts with /dev.""" - self.assertEqual( -- '/dev/this', rootdev_from_cmdline('asdf root=/dev/this')) -+ '/dev/this', util.rootdev_from_cmdline('asdf root=/dev/this')) - - def test_rootdev_from_cmdline_with_root_without_dev_prefix(self): - """Add /dev prefix to cmdline root when the path lacks the prefix.""" -- self.assertEqual('/dev/this', rootdev_from_cmdline('asdf root=this')) -+ self.assertEqual( -+ '/dev/this', util.rootdev_from_cmdline('asdf root=this')) - - def test_rootdev_from_cmdline_with_root_with_label(self): - """When cmdline root contains a LABEL, our root is disk/by-label.""" - self.assertEqual( - '/dev/disk/by-label/unique', -- rootdev_from_cmdline('asdf root=LABEL=unique')) -+ util.rootdev_from_cmdline('asdf root=LABEL=unique')) - - def test_rootdev_from_cmdline_with_root_with_uuid(self): - """When cmdline root contains a UUID, our root is disk/by-uuid.""" - self.assertEqual( - '/dev/disk/by-uuid/adsfdsaf-adsf', -- rootdev_from_cmdline('asdf root=UUID=adsfdsaf-adsf')) -+ util.rootdev_from_cmdline('asdf root=UUID=adsfdsaf-adsf')) - - --class TestIsDevicePathWritableBlock(CiTestCase): -+class TestMaybeGetDevicePathAsWritableBlock(CiTestCase): - - with_logs = True - -- def test_is_device_path_writable_block_false_on_overlayroot(self): -+ def test_maybe_get_writable_device_path_none_on_overlayroot(self): - """When devpath is overlayroot (on MAAS), is_dev_writable is False.""" - info = 'does not matter' -- is_writable = wrap_and_call( -+ devpath = wrap_and_call( - 'cloudinit.config.cc_resizefs.util', - {'is_container': {'return_value': False}}, -- is_device_path_writable_block, 'overlayroot', info, LOG) -- self.assertFalse(is_writable) -+ maybe_get_writable_device_path, 'overlayroot', info, LOG) -+ self.assertIsNone(devpath) - self.assertIn( - "Not attempting to resize devpath 'overlayroot'", - self.logs.getvalue()) - -- def test_is_device_path_writable_block_warns_missing_cmdline_root(self): -+ def test_maybe_get_writable_device_path_warns_missing_cmdline_root(self): - """When root does not exist isn't in the cmdline, log warning.""" - info = 'does not matter' - -@@ -190,43 +191,43 @@ class TestIsDevicePathWritableBlock(CiTestCase): - exists_mock_path = 'cloudinit.config.cc_resizefs.os.path.exists' - with mock.patch(exists_mock_path) as m_exists: - m_exists.return_value = False -- is_writable = wrap_and_call( -+ devpath = wrap_and_call( - 'cloudinit.config.cc_resizefs.util', - {'is_container': {'return_value': False}, - 'get_mount_info': {'side_effect': fake_mount_info}, - 'get_cmdline': {'return_value': 'BOOT_IMAGE=/vmlinuz.efi'}}, -- is_device_path_writable_block, '/dev/root', info, LOG) -- self.assertFalse(is_writable) -+ maybe_get_writable_device_path, '/dev/root', info, LOG) -+ self.assertIsNone(devpath) - logs = self.logs.getvalue() - self.assertIn("WARNING: Unable to find device '/dev/root'", logs) - -- def test_is_device_path_writable_block_does_not_exist(self): -+ def test_maybe_get_writable_device_path_does_not_exist(self): - """When devpath does not exist, a warning is logged.""" - info = 'dev=/I/dont/exist mnt_point=/ path=/dev/none' -- is_writable = wrap_and_call( -+ devpath = wrap_and_call( - 'cloudinit.config.cc_resizefs.util', - {'is_container': {'return_value': False}}, -- is_device_path_writable_block, '/I/dont/exist', info, LOG) -- self.assertFalse(is_writable) -+ maybe_get_writable_device_path, '/I/dont/exist', info, LOG) -+ self.assertIsNone(devpath) - self.assertIn( - "WARNING: Device '/I/dont/exist' did not exist." - ' cannot resize: %s' % info, - self.logs.getvalue()) - -- def test_is_device_path_writable_block_does_not_exist_in_container(self): -+ def test_maybe_get_writable_device_path_does_not_exist_in_container(self): - """When devpath does not exist in a container, log a debug message.""" - info = 'dev=/I/dont/exist mnt_point=/ path=/dev/none' -- is_writable = wrap_and_call( -+ devpath = wrap_and_call( - 'cloudinit.config.cc_resizefs.util', - {'is_container': {'return_value': True}}, -- is_device_path_writable_block, '/I/dont/exist', info, LOG) -- self.assertFalse(is_writable) -+ maybe_get_writable_device_path, '/I/dont/exist', info, LOG) -+ self.assertIsNone(devpath) - self.assertIn( - "DEBUG: Device '/I/dont/exist' did not exist in container." - ' cannot resize: %s' % info, - self.logs.getvalue()) - -- def test_is_device_path_writable_block_raises_oserror(self): -+ def test_maybe_get_writable_device_path_raises_oserror(self): - """When unexpected OSError is raises by os.stat it is reraised.""" - info = 'dev=/I/dont/exist mnt_point=/ path=/dev/none' - with self.assertRaises(OSError) as context_manager: -@@ -234,41 +235,63 @@ class TestIsDevicePathWritableBlock(CiTestCase): - 'cloudinit.config.cc_resizefs', - {'util.is_container': {'return_value': True}, - 'os.stat': {'side_effect': OSError('Something unexpected')}}, -- is_device_path_writable_block, '/I/dont/exist', info, LOG) -+ maybe_get_writable_device_path, '/I/dont/exist', info, LOG) - self.assertEqual( - 'Something unexpected', str(context_manager.exception)) - -- def test_is_device_path_writable_block_non_block(self): -+ def test_maybe_get_writable_device_path_non_block(self): - """When device is not a block device, emit warning return False.""" - fake_devpath = self.tmp_path('dev/readwrite') - util.write_file(fake_devpath, '', mode=0o600) # read-write - info = 'dev=/dev/root mnt_point=/ path={0}'.format(fake_devpath) - -- is_writable = wrap_and_call( -+ devpath = wrap_and_call( - 'cloudinit.config.cc_resizefs.util', - {'is_container': {'return_value': False}}, -- is_device_path_writable_block, fake_devpath, info, LOG) -- self.assertFalse(is_writable) -+ maybe_get_writable_device_path, fake_devpath, info, LOG) -+ self.assertIsNone(devpath) - self.assertIn( - "WARNING: device '{0}' not a block device. cannot resize".format( - fake_devpath), - self.logs.getvalue()) - -- def test_is_device_path_writable_block_non_block_on_container(self): -+ def test_maybe_get_writable_device_path_non_block_on_container(self): - """When device is non-block device in container, emit debug log.""" - fake_devpath = self.tmp_path('dev/readwrite') - util.write_file(fake_devpath, '', mode=0o600) # read-write - info = 'dev=/dev/root mnt_point=/ path={0}'.format(fake_devpath) - -- is_writable = wrap_and_call( -+ devpath = wrap_and_call( - 'cloudinit.config.cc_resizefs.util', - {'is_container': {'return_value': True}}, -- is_device_path_writable_block, fake_devpath, info, LOG) -- self.assertFalse(is_writable) -+ maybe_get_writable_device_path, fake_devpath, info, LOG) -+ self.assertIsNone(devpath) - self.assertIn( - "DEBUG: device '{0}' not a block device in container." - ' cannot resize'.format(fake_devpath), - self.logs.getvalue()) - -+ def test_maybe_get_writable_device_path_returns_cmdline_root(self): -+ """When root device is UUID in kernel commandline, update devpath.""" -+ # XXX Long-term we want to use FilesystemMocking test to avoid -+ # touching os.stat. -+ FakeStat = namedtuple( -+ 'FakeStat', ['st_mode', 'st_size', 'st_mtime']) # minimal def. -+ info = 'dev=/dev/root mnt_point=/ path=/does/not/matter' -+ devpath = wrap_and_call( -+ 'cloudinit.config.cc_resizefs', -+ {'util.get_cmdline': {'return_value': 'asdf root=UUID=my-uuid'}, -+ 'util.is_container': False, -+ 'os.path.exists': False, # /dev/root doesn't exist -+ 'os.stat': { -+ 'return_value': FakeStat(25008, 0, 1)} # char block device -+ }, -+ maybe_get_writable_device_path, '/dev/root', info, LOG) -+ self.assertEqual('/dev/disk/by-uuid/my-uuid', devpath) -+ self.assertIn( -+ "DEBUG: Converted /dev/root to '/dev/disk/by-uuid/my-uuid'" -+ " per kernel cmdline", -+ self.logs.getvalue()) -+ - - # vi: ts=4 expandtab --- -1.7.12.4 - diff --git a/stages-Fix-bug-causing-datasource-to-have-incorrect-.patch b/stages-Fix-bug-causing-datasource-to-have-incorrect-.patch deleted file mode 100644 index e5b3583e8aebe3c3ee959ea0f6c6d9144bcd1d76..0000000000000000000000000000000000000000 --- a/stages-Fix-bug-causing-datasource-to-have-incorrect-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From f0ff194054da90b7b49620b5658342e52156d68e Mon Sep 17 00:00:00 2001 -From: Scott Moser -Date: Thu, 20 Sep 2018 12:45:00 +0000 -Subject: [PATCH 275/354] stages: Fix bug causing datasource to have incorrect - sys_cfg. - -The Init object had a bug/odd side effect where when retrieving a distro -object it would update the datasources's sys_cfg. That was probably -intended to refresh the possibly stale config stored there. Unfortunately -what it actually did limit the config there to the 'system_info' top level -key where initially it had the whole config. - -LP: #1787459 ---- - cloudinit/stages.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/cloudinit/stages.py b/cloudinit/stages.py -index ef5c699..8a06412 100644 ---- a/cloudinit/stages.py -+++ b/cloudinit/stages.py -@@ -88,7 +88,7 @@ class Init(object): - # from whatever it was to a new set... - if self.datasource is not NULL_DATA_SOURCE: - self.datasource.distro = self._distro -- self.datasource.sys_cfg = system_config -+ self.datasource.sys_cfg = self.cfg - return self._distro - - @property --- -1.7.12.4 - diff --git a/stages-fix-tracebacks-if-a-module-stage-is-undefined.patch b/stages-fix-tracebacks-if-a-module-stage-is-undefined.patch deleted file mode 100644 index b969e3c88195fb1827d31e2d1c432c5857cda77a..0000000000000000000000000000000000000000 --- a/stages-fix-tracebacks-if-a-module-stage-is-undefined.patch +++ /dev/null @@ -1,94 +0,0 @@ -From fef2616b9876d3d354b0de1a8e753361e52e77b0 Mon Sep 17 00:00:00 2001 -From: Robert Schweikert -Date: Fri, 15 Jun 2018 13:41:21 -0600 -Subject: [PATCH 219/354] stages: fix tracebacks if a module stage is - undefined or empty - -In /etc/cloud/cloud.cfg, users and imagees can configure which modules run -during a specific cloud-init stage by modifying one of the following -lists: cloud_init_modules, cloud_init_modules, cloud_init_final_modules. - -If any of the configured module lists are absent or empty, cloud-init will -emit the same message it already does for existing lists that only contain -modules which are not unsupported on that platform: - -No 'config' modules to run under section 'cloud_config_modules' - -LP: #1770462 ---- - cloudinit/stages.py | 4 +++- - tests/unittests/test_runs/test_simple_run.py | 32 ++++++++++++++++++++++++++-- - 2 files changed, 33 insertions(+), 3 deletions(-) - -diff --git a/cloudinit/stages.py b/cloudinit/stages.py -index 3998cf6..286607b 100644 ---- a/cloudinit/stages.py -+++ b/cloudinit/stages.py -@@ -697,7 +697,9 @@ class Modules(object): - module_list = [] - if name not in self.cfg: - return module_list -- cfg_mods = self.cfg[name] -+ cfg_mods = self.cfg.get(name) -+ if not cfg_mods: -+ return module_list - # Create 'module_list', an array of hashes - # Where hash['mod'] = module name - # hash['freq'] = frequency -diff --git a/tests/unittests/test_runs/test_simple_run.py b/tests/unittests/test_runs/test_simple_run.py -index 762974e..d67c422 100644 ---- a/tests/unittests/test_runs/test_simple_run.py -+++ b/tests/unittests/test_runs/test_simple_run.py -@@ -1,5 +1,6 @@ - # This file is part of cloud-init. See LICENSE file for license information. - -+import copy - import os - - from cloudinit.tests import helpers -@@ -127,8 +128,9 @@ class TestSimpleRun(helpers.FilesystemMockingTestCase): - """run_section forced skipped modules by using unverified_modules.""" - - # re-write cloud.cfg with unverified_modules override -- self.cfg['unverified_modules'] = ['spacewalk'] # Would have skipped -- cloud_cfg = util.yaml_dumps(self.cfg) -+ cfg = copy.deepcopy(self.cfg) -+ cfg['unverified_modules'] = ['spacewalk'] # Would have skipped -+ cloud_cfg = util.yaml_dumps(cfg) - util.ensure_dir(os.path.join(self.new_root, 'etc', 'cloud')) - util.write_file(os.path.join(self.new_root, 'etc', - 'cloud', 'cloud.cfg'), cloud_cfg) -@@ -150,4 +152,30 @@ class TestSimpleRun(helpers.FilesystemMockingTestCase): - "running unverified_modules: 'spacewalk'", - self.logs.getvalue()) - -+ def test_none_ds_run_with_no_config_modules(self): -+ """run_section will report no modules run when none are configured.""" -+ -+ # re-write cloud.cfg with unverified_modules override -+ cfg = copy.deepcopy(self.cfg) -+ # Represent empty configuration in /etc/cloud/cloud.cfg -+ cfg['cloud_init_modules'] = None -+ cloud_cfg = util.yaml_dumps(cfg) -+ util.ensure_dir(os.path.join(self.new_root, 'etc', 'cloud')) -+ util.write_file(os.path.join(self.new_root, 'etc', -+ 'cloud', 'cloud.cfg'), cloud_cfg) -+ -+ initer = stages.Init() -+ initer.read_cfg() -+ initer.initialize() -+ initer.fetch() -+ initer.instancify() -+ initer.update() -+ initer.cloudify().run('consume_data', initer.consume_data, -+ args=[PER_INSTANCE], freq=PER_INSTANCE) -+ -+ mods = stages.Modules(initer) -+ (which_ran, failures) = mods.run_section('cloud_init_modules') -+ self.assertTrue(len(failures) == 0) -+ self.assertEqual([], which_ran) -+ - # vi: ts=4 expandtab --- -1.7.12.4 -