From 0cb1bb89c1f40aefceef34ea226a4f195793ac56878af76dd4180fadbf71839a Mon Sep 17 00:00:00 2001 From: Robert Schweikert Date: Mon, 14 Oct 2019 18:50:21 +0000 Subject: [PATCH] =?UTF-8?q?-=20Update=20to=20cloud-init=2019.2=20(bsc#1099?= =?UTF-8?q?358)=20=20=20+=20Remove,=20included=20upstream=20=20=20=20=20-?= =?UTF-8?q?=20cloud-init-detect-nova.diff=20=20=20=20=20-=20cloud-init-add?= =?UTF-8?q?-static-routes.diff=20=20=20+=20net:=20add=20rfc3442=20(classle?= =?UTF-8?q?ss=20static=20routes)=20to=20EphemeralDHCP=20=20=20=20=20(LP:?= =?UTF-8?q?=20#1821102)=20=20=20+=20templates/ntp.conf.debian.tmpl:=20fix?= =?UTF-8?q?=20missing=20newline=20for=20pools=20=20=20=20=20(LP:=20#183659?= =?UTF-8?q?8)=20=20=20+=20Support=20netplan=20renderer=20in=20Arch=20Linux?= =?UTF-8?q?=20[Conrad=20Hoffmann]=20=20=20+=20Fix=20typo=20in=20publicly?= =?UTF-8?q?=20viewable=20documentation.=20[David=20Medberry]=20=20=20+=20A?= =?UTF-8?q?dd=20a=20cdrom=20size=20checker=20for=20OVF=20ds=20to=20ds-iden?= =?UTF-8?q?tify=20=20=20=20=20[Pengpeng=20Sun]=20(LP:=20#1806701)=20=20=20?= =?UTF-8?q?+=20VMWare:=20Trigger=20the=20post=20customization=20script=20v?= =?UTF-8?q?ia=20cc=5Fscripts=20module.=20=20=20=20=20[Xiaofeng=20Wang]=20(?= =?UTF-8?q?LP:=20#1833192)=20=20=20+=20Cloud-init=20analyze=20module:=20Ad?= =?UTF-8?q?ded=20ability=20to=20analyze=20boot=20events.=20=20=20=20=20[Sa?= =?UTF-8?q?m=20Gilson]=20=20=20+=20Update=20debian=20eni=20network=20confi?= =?UTF-8?q?guration=20location,=20retain=20Ubuntu=20setting=20=20=20=20=20?= =?UTF-8?q?[Janos=20Lenart]=20=20=20+=20net:=20skip=20bond=20interfaces=20?= =?UTF-8?q?in=20get=5Finterfaces=20=20=20=20=20[Stanislav=20Makar]=20(LP:?= =?UTF-8?q?=20#1812857)=20=20=20+=20Fix=20a=20couple=20of=20issues=20raise?= =?UTF-8?q?d=20by=20a=20coverity=20scan=20=20=20+=20Add=20missing=20dsname?= =?UTF-8?q?=20for=20Hetzner=20Cloud=20datasource=20[Markus=20Schade]=20=20?= =?UTF-8?q?=20+=20doc:=20indicate=20that=20netplan=20is=20default=20in=20U?= =?UTF-8?q?buntu=20now=20=20=20+=20azure:=20add=20region=20and=20AZ=20prop?= =?UTF-8?q?erties=20from=20imds=20compute=20location=20metadata=20=20=20+?= =?UTF-8?q?=20sysconfig:=20support=20more=20bonding=20options=20[Penghui?= =?UTF-8?q?=20Liao]=20=20=20+=20cloud-init-generator:=20use=20libexec=20pa?= =?UTF-8?q?th=20to=20ds-identify=20on=20redhat=20systems=20=20=20=20=20(LP?= =?UTF-8?q?:=20#1833264)=20=20=20+=20tools/build-on-freebsd:=20update=20to?= =?UTF-8?q?=20python3=20[Gon=C3=A9ri=20Le=20Bouder]=20=20=20+=20Allow=20id?= =?UTF-8?q?entification=20of=20OpenStack=20by=20Asset=20Tag=20=20=20=20=20?= =?UTF-8?q?[Mark=20T.=20Voelker]=20(LP:=20#1669875)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OBS-URL: https://build.opensuse.org/package/show/Cloud:Tools/cloud-init?expand=0&rev=149 --- cloud-init-19.1.tar.gz | 3 - cloud-init-19.2.tar.gz | 3 + cloud-init-add-static-routes.diff | 426 ------------------------------ cloud-init-detect-nova.diff | 57 ---- cloud-init.changes | 45 +++- cloud-init.spec | 15 +- 6 files changed, 51 insertions(+), 498 deletions(-) delete mode 100644 cloud-init-19.1.tar.gz create mode 100644 cloud-init-19.2.tar.gz delete mode 100644 cloud-init-add-static-routes.diff delete mode 100644 cloud-init-detect-nova.diff diff --git a/cloud-init-19.1.tar.gz b/cloud-init-19.1.tar.gz deleted file mode 100644 index 0eda873..0000000 --- a/cloud-init-19.1.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:75be8cbff1431883227c05356cb69400f20bbb2666fd05e085f846ecf1d153cb -size 1017682 diff --git a/cloud-init-19.2.tar.gz b/cloud-init-19.2.tar.gz new file mode 100644 index 0000000..c349620 --- /dev/null +++ b/cloud-init-19.2.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5ead1b3c782c159669f8f8779c45d16a986c7405425d75f915ec55301d83a07 +size 1028832 diff --git a/cloud-init-add-static-routes.diff b/cloud-init-add-static-routes.diff deleted file mode 100644 index 7a043cb..0000000 --- a/cloud-init-add-static-routes.diff +++ /dev/null @@ -1,426 +0,0 @@ -From 07b17236be5665bb552c7460102bcd07bf8f2be8 Mon Sep 17 00:00:00 2001 -From: Ryan Harper -Date: Tue, 16 Jul 2019 22:40:15 +0000 -Subject: net: add rfc3442 (classless static routes) to EphemeralDHCP - -The EphemeralDHCP context manager did not parse or handle -rfc3442 classless static routes which prevented reading -datasource metadata in some clouds. This branch adds support -for extracting the field from the leases output, parsing the -format and then adding the required iproute2 ip commands to -apply (and teardown) the static routes. - -LP: #1821102 - -diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py -index e758006..624c9b4 100644 ---- a/cloudinit/net/__init__.py -+++ b/cloudinit/net/__init__.py -@@ -679,7 +679,7 @@ class EphemeralIPv4Network(object): - """ - - def __init__(self, interface, ip, prefix_or_mask, broadcast, router=None, -- connectivity_url=None): -+ connectivity_url=None, static_routes=None): - """Setup context manager and validate call signature. - - @param interface: Name of the network interface to bring up. -@@ -690,6 +690,7 @@ class EphemeralIPv4Network(object): - @param router: Optionally the default gateway IP. - @param connectivity_url: Optionally, a URL to verify if a usable - connection already exists. -+ @param static_routes: Optionally a list of static routes from DHCP - """ - if not all([interface, ip, prefix_or_mask, broadcast]): - raise ValueError( -@@ -706,6 +707,7 @@ class EphemeralIPv4Network(object): - self.ip = ip - self.broadcast = broadcast - self.router = router -+ self.static_routes = static_routes - self.cleanup_cmds = [] # List of commands to run to cleanup state. - - def __enter__(self): -@@ -718,7 +720,21 @@ class EphemeralIPv4Network(object): - return - - self._bringup_device() -- if self.router: -+ -+ # rfc3442 requires us to ignore the router config *if* classless static -+ # routes are provided. -+ # -+ # https://tools.ietf.org/html/rfc3442 -+ # -+ # If the DHCP server returns both a Classless Static Routes option and -+ # a Router option, the DHCP client MUST ignore the Router option. -+ # -+ # Similarly, if the DHCP server returns both a Classless Static Routes -+ # option and a Static Routes option, the DHCP client MUST ignore the -+ # Static Routes option. -+ if self.static_routes: -+ self._bringup_static_routes() -+ elif self.router: - self._bringup_router() - - def __exit__(self, excp_type, excp_value, excp_traceback): -@@ -762,6 +778,20 @@ class EphemeralIPv4Network(object): - ['ip', '-family', 'inet', 'addr', 'del', cidr, 'dev', - self.interface]) - -+ def _bringup_static_routes(self): -+ # static_routes = [("169.254.169.254/32", "130.56.248.255"), -+ # ("0.0.0.0/0", "130.56.240.1")] -+ for net_address, gateway in self.static_routes: -+ via_arg = [] -+ if gateway != "0.0.0.0/0": -+ via_arg = ['via', gateway] -+ util.subp( -+ ['ip', '-4', 'route', 'add', net_address] + via_arg + -+ ['dev', self.interface], capture=True) -+ self.cleanup_cmds.insert( -+ 0, ['ip', '-4', 'route', 'del', net_address] + via_arg + -+ ['dev', self.interface]) -+ - def _bringup_router(self): - """Perform the ip commands to fully setup the router if needed.""" - # Check if a default route exists and exit if it does -diff --git a/cloudinit/net/dhcp.py b/cloudinit/net/dhcp.py -index c98a97c..1737991 100644 ---- a/cloudinit/net/dhcp.py -+++ b/cloudinit/net/dhcp.py -@@ -92,10 +92,14 @@ class EphemeralDHCPv4(object): - nmap = {'interface': 'interface', 'ip': 'fixed-address', - 'prefix_or_mask': 'subnet-mask', - 'broadcast': 'broadcast-address', -+ 'static_routes': 'rfc3442-classless-static-routes', - 'router': 'routers'} - kwargs = dict([(k, self.lease.get(v)) for k, v in nmap.items()]) - if not kwargs['broadcast']: - kwargs['broadcast'] = bcip(kwargs['prefix_or_mask'], kwargs['ip']) -+ if kwargs['static_routes']: -+ kwargs['static_routes'] = ( -+ parse_static_routes(kwargs['static_routes'])) - if self.connectivity_url: - kwargs['connectivity_url'] = self.connectivity_url - ephipv4 = EphemeralIPv4Network(**kwargs) -@@ -272,4 +276,90 @@ def networkd_get_option_from_leases(keyname, leases_d=None): - return data[keyname] - return None - -+ -+def parse_static_routes(rfc3442): -+ """ parse rfc3442 format and return a list containing tuple of strings. -+ -+ The tuple is composed of the network_address (including net length) and -+ gateway for a parsed static route. -+ -+ @param rfc3442: string in rfc3442 format -+ @returns: list of tuple(str, str) for all valid parsed routes until the -+ first parsing error. -+ -+ E.g. -+ sr = parse_state_routes("32,169,254,169,254,130,56,248,255,0,130,56,240,1") -+ sr = [ -+ ("169.254.169.254/32", "130.56.248.255"), ("0.0.0.0/0", "130.56.240.1") -+ ] -+ -+ Python version of isc-dhclient's hooks: -+ /etc/dhcp/dhclient-exit-hooks.d/rfc3442-classless-routes -+ """ -+ # raw strings from dhcp lease may end in semi-colon -+ rfc3442 = rfc3442.rstrip(";") -+ tokens = rfc3442.split(',') -+ static_routes = [] -+ -+ def _trunc_error(cidr, required, remain): -+ msg = ("RFC3442 string malformed. Current route has CIDR of %s " -+ "and requires %s significant octets, but only %s remain. " -+ "Verify DHCP rfc3442-classless-static-routes value: %s" -+ % (cidr, required, remain, rfc3442)) -+ LOG.error(msg) -+ -+ current_idx = 0 -+ for idx, tok in enumerate(tokens): -+ if idx < current_idx: -+ continue -+ net_length = int(tok) -+ if net_length in range(25, 33): -+ req_toks = 9 -+ if len(tokens[idx:]) < req_toks: -+ _trunc_error(net_length, req_toks, len(tokens[idx:])) -+ return static_routes -+ net_address = ".".join(tokens[idx+1:idx+5]) -+ gateway = ".".join(tokens[idx+5:idx+req_toks]) -+ current_idx = idx + req_toks -+ elif net_length in range(17, 25): -+ req_toks = 8 -+ if len(tokens[idx:]) < req_toks: -+ _trunc_error(net_length, req_toks, len(tokens[idx:])) -+ return static_routes -+ net_address = ".".join(tokens[idx+1:idx+4] + ["0"]) -+ gateway = ".".join(tokens[idx+4:idx+req_toks]) -+ current_idx = idx + req_toks -+ elif net_length in range(9, 17): -+ req_toks = 7 -+ if len(tokens[idx:]) < req_toks: -+ _trunc_error(net_length, req_toks, len(tokens[idx:])) -+ return static_routes -+ net_address = ".".join(tokens[idx+1:idx+3] + ["0", "0"]) -+ gateway = ".".join(tokens[idx+3:idx+req_toks]) -+ current_idx = idx + req_toks -+ elif net_length in range(1, 9): -+ req_toks = 6 -+ if len(tokens[idx:]) < req_toks: -+ _trunc_error(net_length, req_toks, len(tokens[idx:])) -+ return static_routes -+ net_address = ".".join(tokens[idx+1:idx+2] + ["0", "0", "0"]) -+ gateway = ".".join(tokens[idx+2:idx+req_toks]) -+ current_idx = idx + req_toks -+ elif net_length == 0: -+ req_toks = 5 -+ if len(tokens[idx:]) < req_toks: -+ _trunc_error(net_length, req_toks, len(tokens[idx:])) -+ return static_routes -+ net_address = "0.0.0.0" -+ gateway = ".".join(tokens[idx+1:idx+req_toks]) -+ current_idx = idx + req_toks -+ else: -+ LOG.error('Parsed invalid net length "%s". Verify DHCP ' -+ 'rfc3442-classless-static-routes value.', net_length) -+ return static_routes -+ -+ static_routes.append(("%s/%s" % (net_address, net_length), gateway)) -+ -+ return static_routes -+ - # vi: ts=4 expandtab -diff --git a/cloudinit/net/tests/test_dhcp.py b/cloudinit/net/tests/test_dhcp.py -index 5139024..91f503c 100644 ---- a/cloudinit/net/tests/test_dhcp.py -+++ b/cloudinit/net/tests/test_dhcp.py -@@ -8,7 +8,8 @@ from textwrap import dedent - import cloudinit.net as net - from cloudinit.net.dhcp import ( - InvalidDHCPLeaseFileError, maybe_perform_dhcp_discovery, -- parse_dhcp_lease_file, dhcp_discovery, networkd_load_leases) -+ parse_dhcp_lease_file, dhcp_discovery, networkd_load_leases, -+ parse_static_routes) - from cloudinit.util import ensure_file, write_file - from cloudinit.tests.helpers import ( - CiTestCase, HttprettyTestCase, mock, populate_dir, wrap_and_call) -@@ -64,6 +65,123 @@ class TestParseDHCPLeasesFile(CiTestCase): - self.assertItemsEqual(expected, parse_dhcp_lease_file(lease_file)) - - -+class TestDHCPRFC3442(CiTestCase): -+ -+ def test_parse_lease_finds_rfc3442_classless_static_routes(self): -+ """parse_dhcp_lease_file returns rfc3442-classless-static-routes.""" -+ lease_file = self.tmp_path('leases') -+ content = dedent(""" -+ lease { -+ interface "wlp3s0"; -+ fixed-address 192.168.2.74; -+ option subnet-mask 255.255.255.0; -+ option routers 192.168.2.1; -+ option rfc3442-classless-static-routes 0,130,56,240,1; -+ renew 4 2017/07/27 18:02:30; -+ expire 5 2017/07/28 07:08:15; -+ } -+ """) -+ expected = [ -+ {'interface': 'wlp3s0', 'fixed-address': '192.168.2.74', -+ 'subnet-mask': '255.255.255.0', 'routers': '192.168.2.1', -+ 'rfc3442-classless-static-routes': '0,130,56,240,1', -+ 'renew': '4 2017/07/27 18:02:30', -+ 'expire': '5 2017/07/28 07:08:15'}] -+ write_file(lease_file, content) -+ self.assertItemsEqual(expected, parse_dhcp_lease_file(lease_file)) -+ -+ @mock.patch('cloudinit.net.dhcp.EphemeralIPv4Network') -+ @mock.patch('cloudinit.net.dhcp.maybe_perform_dhcp_discovery') -+ def test_obtain_lease_parses_static_routes(self, m_maybe, m_ipv4): -+ """EphemeralDHPCv4 parses rfc3442 routes for EphemeralIPv4Network""" -+ lease = [ -+ {'interface': 'wlp3s0', 'fixed-address': '192.168.2.74', -+ 'subnet-mask': '255.255.255.0', 'routers': '192.168.2.1', -+ 'rfc3442-classless-static-routes': '0,130,56,240,1', -+ 'renew': '4 2017/07/27 18:02:30', -+ 'expire': '5 2017/07/28 07:08:15'}] -+ m_maybe.return_value = lease -+ eph = net.dhcp.EphemeralDHCPv4() -+ eph.obtain_lease() -+ expected_kwargs = { -+ 'interface': 'wlp3s0', -+ 'ip': '192.168.2.74', -+ 'prefix_or_mask': '255.255.255.0', -+ 'broadcast': '192.168.2.255', -+ 'static_routes': [('0.0.0.0/0', '130.56.240.1')], -+ 'router': '192.168.2.1'} -+ m_ipv4.assert_called_with(**expected_kwargs) -+ -+ -+class TestDHCPParseStaticRoutes(CiTestCase): -+ -+ with_logs = True -+ -+ def parse_static_routes_empty_string(self): -+ self.assertEqual([], parse_static_routes("")) -+ -+ def test_parse_static_routes_invalid_input_returns_empty_list(self): -+ rfc3442 = "32,169,254,169,254,130,56,248" -+ self.assertEqual([], parse_static_routes(rfc3442)) -+ -+ def test_parse_static_routes_bogus_width_returns_empty_list(self): -+ rfc3442 = "33,169,254,169,254,130,56,248" -+ self.assertEqual([], parse_static_routes(rfc3442)) -+ -+ def test_parse_static_routes_single_ip(self): -+ rfc3442 = "32,169,254,169,254,130,56,248,255" -+ self.assertEqual([('169.254.169.254/32', '130.56.248.255')], -+ parse_static_routes(rfc3442)) -+ -+ def test_parse_static_routes_single_ip_handles_trailing_semicolon(self): -+ rfc3442 = "32,169,254,169,254,130,56,248,255;" -+ self.assertEqual([('169.254.169.254/32', '130.56.248.255')], -+ parse_static_routes(rfc3442)) -+ -+ def test_parse_static_routes_default_route(self): -+ rfc3442 = "0,130,56,240,1" -+ self.assertEqual([('0.0.0.0/0', '130.56.240.1')], -+ parse_static_routes(rfc3442)) -+ -+ def test_parse_static_routes_class_c_b_a(self): -+ class_c = "24,192,168,74,192,168,0,4" -+ class_b = "16,172,16,172,16,0,4" -+ class_a = "8,10,10,0,0,4" -+ rfc3442 = ",".join([class_c, class_b, class_a]) -+ self.assertEqual(sorted([ -+ ("192.168.74.0/24", "192.168.0.4"), -+ ("172.16.0.0/16", "172.16.0.4"), -+ ("10.0.0.0/8", "10.0.0.4") -+ ]), sorted(parse_static_routes(rfc3442))) -+ -+ def test_parse_static_routes_logs_error_truncated(self): -+ bad_rfc3442 = { -+ "class_c": "24,169,254,169,10", -+ "class_b": "16,172,16,10", -+ "class_a": "8,10,10", -+ "gateway": "0,0", -+ "netlen": "33,0", -+ } -+ for rfc3442 in bad_rfc3442.values(): -+ self.assertEqual([], parse_static_routes(rfc3442)) -+ -+ logs = self.logs.getvalue() -+ self.assertEqual(len(bad_rfc3442.keys()), len(logs.splitlines())) -+ -+ def test_parse_static_routes_returns_valid_routes_until_parse_err(self): -+ class_c = "24,192,168,74,192,168,0,4" -+ class_b = "16,172,16,172,16,0,4" -+ class_a_error = "8,10,10,0,0" -+ rfc3442 = ",".join([class_c, class_b, class_a_error]) -+ self.assertEqual(sorted([ -+ ("192.168.74.0/24", "192.168.0.4"), -+ ("172.16.0.0/16", "172.16.0.4"), -+ ]), sorted(parse_static_routes(rfc3442))) -+ -+ logs = self.logs.getvalue() -+ self.assertIn(rfc3442, logs.splitlines()[0]) -+ -+ - class TestDHCPDiscoveryClean(CiTestCase): - with_logs = True - -diff --git a/cloudinit/net/tests/test_init.py b/cloudinit/net/tests/test_init.py -index 6d2affe..d393e6a 100644 ---- a/cloudinit/net/tests/test_init.py -+++ b/cloudinit/net/tests/test_init.py -@@ -549,6 +549,45 @@ class TestEphemeralIPV4Network(CiTestCase): - self.assertEqual(expected_setup_calls, m_subp.call_args_list) - m_subp.assert_has_calls(expected_teardown_calls) - -+ def test_ephemeral_ipv4_network_with_rfc3442_static_routes(self, m_subp): -+ params = { -+ 'interface': 'eth0', 'ip': '192.168.2.2', -+ 'prefix_or_mask': '255.255.255.0', 'broadcast': '192.168.2.255', -+ 'static_routes': [('169.254.169.254/32', '192.168.2.1'), -+ ('0.0.0.0/0', '192.168.2.1')], -+ 'router': '192.168.2.1'} -+ expected_setup_calls = [ -+ mock.call( -+ ['ip', '-family', 'inet', 'addr', 'add', '192.168.2.2/24', -+ 'broadcast', '192.168.2.255', 'dev', 'eth0'], -+ capture=True, update_env={'LANG': 'C'}), -+ mock.call( -+ ['ip', '-family', 'inet', 'link', 'set', 'dev', 'eth0', 'up'], -+ capture=True), -+ mock.call( -+ ['ip', '-4', 'route', 'add', '169.254.169.254/32', -+ 'via', '192.168.2.1', 'dev', 'eth0'], capture=True), -+ mock.call( -+ ['ip', '-4', 'route', 'add', '0.0.0.0/0', -+ 'via', '192.168.2.1', 'dev', 'eth0'], capture=True)] -+ expected_teardown_calls = [ -+ mock.call( -+ ['ip', '-4', 'route', 'del', '0.0.0.0/0', -+ 'via', '192.168.2.1', 'dev', 'eth0'], capture=True), -+ mock.call( -+ ['ip', '-4', 'route', 'del', '169.254.169.254/32', -+ 'via', '192.168.2.1', 'dev', 'eth0'], capture=True), -+ mock.call( -+ ['ip', '-family', 'inet', 'link', 'set', 'dev', -+ 'eth0', 'down'], capture=True), -+ mock.call( -+ ['ip', '-family', 'inet', 'addr', 'del', -+ '192.168.2.2/24', 'dev', 'eth0'], capture=True) -+ ] -+ with net.EphemeralIPv4Network(**params): -+ self.assertEqual(expected_setup_calls, m_subp.call_args_list) -+ m_subp.assert_has_calls(expected_setup_calls + expected_teardown_calls) -+ - - class TestApplyNetworkCfgNames(CiTestCase): - V1_CONFIG = textwrap.dedent("""\ -diff --git a/tests/unittests/test_datasource/test_azure.py b/tests/unittests/test_datasource/test_azure.py -index f27ef21..2de2aea 100644 ---- a/tests/unittests/test_datasource/test_azure.py -+++ b/tests/unittests/test_datasource/test_azure.py -@@ -1807,7 +1807,8 @@ class TestAzureDataSourcePreprovisioning(CiTestCase): - self.assertEqual(m_dhcp.call_count, 2) - m_net.assert_any_call( - broadcast='192.168.2.255', interface='eth9', ip='192.168.2.9', -- prefix_or_mask='255.255.255.0', router='192.168.2.1') -+ prefix_or_mask='255.255.255.0', router='192.168.2.1', -+ static_routes=None) - self.assertEqual(m_net.call_count, 2) - - def test__reprovision_calls__poll_imds(self, fake_resp, -@@ -1845,7 +1846,8 @@ class TestAzureDataSourcePreprovisioning(CiTestCase): - self.assertEqual(m_dhcp.call_count, 2) - m_net.assert_any_call( - broadcast='192.168.2.255', interface='eth9', ip='192.168.2.9', -- prefix_or_mask='255.255.255.0', router='192.168.2.1') -+ prefix_or_mask='255.255.255.0', router='192.168.2.1', -+ static_routes=None) - self.assertEqual(m_net.call_count, 2) - - -diff --git a/tests/unittests/test_datasource/test_ec2.py b/tests/unittests/test_datasource/test_ec2.py -index 20d59bf..1ec8e00 100644 ---- a/tests/unittests/test_datasource/test_ec2.py -+++ b/tests/unittests/test_datasource/test_ec2.py -@@ -538,7 +538,8 @@ class TestEc2(test_helpers.HttprettyTestCase): - 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') -+ prefix_or_mask='255.255.255.0', router='192.168.2.1', -+ static_routes=None) - self.assertIn('Crawl of metadata service took', self.logs.getvalue()) - - --- -cgit v0.10.2 - diff --git a/cloud-init-detect-nova.diff b/cloud-init-detect-nova.diff deleted file mode 100644 index fde6c89..0000000 --- a/cloud-init-detect-nova.diff +++ /dev/null @@ -1,57 +0,0 @@ -diff --git a/tests/unittests/test_ds_identify.py b/tests/unittests/test_ds_identify.py -index 8c18aa1..7575223 100644 ---- a/tests/unittests/test_ds_identify.py -+++ b/tests/unittests/test_ds_identify.py -@@ -435,6 +435,14 @@ class TestDsIdentify(DsIdentifyBase): - """Open Telecom identification.""" - self._test_ds_found('OpenStack-OpenTelekom') - -+ def test_openstack_asset_tag_nova(self): -+ """OpenStack identification via asset tag OpenStack Nova.""" -+ self._test_ds_found('OpenStack-AssetTag-Nova') -+ -+ def test_openstack_asset_tag_copute(self): -+ """OpenStack identification via asset tag OpenStack Compute.""" -+ self._test_ds_found('OpenStack-AssetTag-Compute') -+ - def test_openstack_on_non_intel_is_maybe(self): - """On non-Intel, openstack without dmi info is maybe. - -@@ -759,6 +767,18 @@ VALID_CFG = { - 'files': {P_CHASSIS_ASSET_TAG: 'OpenTelekomCloud\n'}, - 'mocks': [MOCK_VIRT_IS_XEN], - }, -+ 'OpenStack-AssetTag-Nova': { -+ # VMware vSphere can't modify product-name, LP: #1669875 -+ 'ds': 'OpenStack', -+ 'files': {P_CHASSIS_ASSET_TAG: 'OpenStack Nova\n'}, -+ 'mocks': [MOCK_VIRT_IS_XEN], -+ }, -+ 'OpenStack-AssetTag-Compute': { -+ # VMware vSphere can't modify product-name, LP: #1669875 -+ 'ds': 'OpenStack', -+ 'files': {P_CHASSIS_ASSET_TAG: 'OpenStack Compute\n'}, -+ 'mocks': [MOCK_VIRT_IS_XEN], -+ }, - 'OVF-seed': { - 'ds': 'OVF', - 'files': { -diff --git a/tools/ds-identify b/tools/ds-identify -index 6518901..e16708f 100755 ---- a/tools/ds-identify -+++ b/tools/ds-identify -@@ -979,6 +979,14 @@ dscheck_OpenStack() { - return ${DS_FOUND} - fi - -+ # LP: #1669875 : allow identification of OpenStack by asset tag -+ if dmi_chassis_asset_tag_matches "$nova"; then -+ return ${DS_FOUND} -+ fi -+ if dmi_chassis_asset_tag_matches "$compute"; then -+ return ${DS_FOUND} -+ fi -+ - # LP: #1715241 : arch other than intel are not identified properly. - case "$DI_UNAME_MACHINE" in - i?86|x86_64) :;; diff --git a/cloud-init.changes b/cloud-init.changes index 28abbc3..3d61cd6 100644 --- a/cloud-init.changes +++ b/cloud-init.changes @@ -1,3 +1,45 @@ +------------------------------------------------------------------- +Thu Sep 26 12:15:50 UTC 2019 - Robert Schweikert + +- Update to cloud-init 19.2 (bsc#1099358) + + Remove, included upstream + - cloud-init-detect-nova.diff + - cloud-init-add-static-routes.diff + + net: add rfc3442 (classless static routes) to EphemeralDHCP + (LP: #1821102) + + templates/ntp.conf.debian.tmpl: fix missing newline for pools + (LP: #1836598) + + Support netplan renderer in Arch Linux [Conrad Hoffmann] + + Fix typo in publicly viewable documentation. [David Medberry] + + Add a cdrom size checker for OVF ds to ds-identify + [Pengpeng Sun] (LP: #1806701) + + VMWare: Trigger the post customization script via cc_scripts module. + [Xiaofeng Wang] (LP: #1833192) + + Cloud-init analyze module: Added ability to analyze boot events. + [Sam Gilson] + + Update debian eni network configuration location, retain Ubuntu setting + [Janos Lenart] + + net: skip bond interfaces in get_interfaces + [Stanislav Makar] (LP: #1812857) + + Fix a couple of issues raised by a coverity scan + + Add missing dsname for Hetzner Cloud datasource [Markus Schade] + + doc: indicate that netplan is default in Ubuntu now + + azure: add region and AZ properties from imds compute location metadata + + sysconfig: support more bonding options [Penghui Liao] + + cloud-init-generator: use libexec path to ds-identify on redhat systems + (LP: #1833264) + + tools/build-on-freebsd: update to python3 [Gonéri Le Bouder] + + Allow identification of OpenStack by Asset Tag + [Mark T. Voelker] (LP: #1669875) + + Fix spelling error making 'an Ubuntu' consistent. [Brian Murray] + + run-container: centos: comment out the repo mirrorlist [Paride Legovini] + + netplan: update netplan key mappings for gratuitous-arp (LP: #1827238) + + freebsd: fix the name of cloudcfg VARIANT [Gonéri Le Bouder] + + freebsd: ability to grow root file system [Gonéri Le Bouder] + + freebsd: NoCloud data source support [Gonéri Le Bouder] (LP: #1645824) + + Azure: Return static fallback address as if failed to find endpoint + [Jason Zions (MSFT)] + ------------------------------------------------------------------- Tue Sep 24 19:50:33 UTC 2019 - Robert Schweikert @@ -58,7 +100,7 @@ Tue Jun 11 12:37:16 UTC 2019 - Dominique Leuenberger ------------------------------------------------------------------- Fri May 31 12:42:49 UTC 2019 - Robert Schweikert -- Update to version 19.1 (bsc#1136440) +- Update to version 19.1 (bsc#1136440, bsc#1129124) + Remove, included upstream - fix-default-systemd-unit-dir.patch - cloud-init-sysconf-ethsetup.patch @@ -135,6 +177,7 @@ Fri May 31 12:42:49 UTC 2019 - Robert Schweikert + Enable encrypted_data_bag_secret support for Chef [Eric Williams] (LP: #1817082) + azure: Filter list of ssh keys pulled from fabric [Jason Zions (MSFT)] + CVE-2019-0816 + doc: update merging doc with fixes and some additional details/examples + tests: integration test failure summary to use traceback if empty error + This is to fix https://bugs.launchpad.net/cloud-init/+bug/1812676 diff --git a/cloud-init.spec b/cloud-init.spec index f4a1159..99315a1 100644 --- a/cloud-init.spec +++ b/cloud-init.spec @@ -18,7 +18,7 @@ %global configver 0.7 Name: cloud-init -Version: 19.1 +Version: 19.2 Release: 0 License: GPL-3.0 and AGPL-3.0 Summary: Cloud node initialization tool @@ -27,7 +27,6 @@ Group: System/Management Source0: %{name}-%{version}.tar.gz Source1: rsyslog-cloud-init.cfg - # FIXME # python2 disables SIGPIPE, causing broken pipe errors in shell scripts (bsc#903449) Patch20: cloud-init-python2-sigpipe.patch @@ -42,15 +41,11 @@ Patch41: cloud-init-static-net.patch Patch42: cloud-init-ostack-metadat-dencode.patch # FIXME (lp#1812117) Patch43: cloud-init-write-routes.patch -# FIXME (lp#1817368) +# FIXME (lp#1817368) expected in 19.3 Patch47: cloud-init-trigger-udev.patch -# FIXME (lp#1669875) patch by mvoelker@launchpad -Patch48: cloud-init-detect-nova.diff -# FIXME (lp#1821102) -Patch49: cloud-init-add-static-routes.diff -# FIXME (lp#1843634) +# FIXME (lp#1843634) expected in 19.3 Patch50: cloud-init-noresolv-merge-no-dns-data.diff -# FIXME +# FIXME expected in 19.3 Patch51: cloud-init-after-wicked.patch BuildRequires: fdupes @@ -195,8 +190,6 @@ Documentation and examples for cloud-init tools %patch42 %patch43 %patch47 -%patch48 -p1 -%patch49 -p1 %patch50 -p1 %patch51 -p1