From edc5d41c428cdade965b42aee5439f7728f11881 Mon Sep 17 00:00:00 2001 From: James Falcon Date: Fri, 3 Sep 2021 14:36:41 -0500 Subject: 21.3-1-g6803368d-0ubuntu2 (patches unapplied) Imported using git-ubuntu import. --- debian/changelog | 9 +++ ...56d99-Azure-Retry-dhcp-on-timeouts-when-polling | 73 ++++++++++++++++++++++ ...re-to-only-update-metadata-on-BOOT_NEW_INSTANCE | 55 ++++++++++++++++ debian/patches/series | 2 + 4 files changed, 139 insertions(+) create mode 100644 debian/patches/cpick-28e56d99-Azure-Retry-dhcp-on-timeouts-when-polling create mode 100644 debian/patches/cpick-e69a8874-Set-Azure-to-only-update-metadata-on-BOOT_NEW_INSTANCE create mode 100644 debian/patches/series diff --git a/debian/changelog b/debian/changelog index fc76ca49..b2cb8a6c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +cloud-init (21.3-1-g6803368d-0ubuntu2) impish; urgency=medium + + * cherry-pick 28e56d99: Azure: Retry dhcp on timeouts when polling + reprovisiondata + * cherry-pick e69a8874: Set Azure to only update metadata on + BOOT_NEW_INSTANCE + + -- James Falcon Fri, 03 Sep 2021 14:36:41 -0500 + cloud-init (21.3-1-g6803368d-0ubuntu1) impish; urgency=medium * New upstream snapshot. diff --git a/debian/patches/cpick-28e56d99-Azure-Retry-dhcp-on-timeouts-when-polling b/debian/patches/cpick-28e56d99-Azure-Retry-dhcp-on-timeouts-when-polling new file mode 100644 index 00000000..db914b45 --- /dev/null +++ b/debian/patches/cpick-28e56d99-Azure-Retry-dhcp-on-timeouts-when-polling @@ -0,0 +1,73 @@ +From 28e56d993fc40feab139f149dacc10cae51a3fe0 Mon Sep 17 00:00:00 2001 +From: aswinrajamannar <39812128+aswinrajamannar@users.noreply.github.com> +Date: Tue, 24 Aug 2021 13:45:41 -0700 +Subject: [PATCH] Azure: Retry dhcp on timeouts when polling reprovisiondata + (#998) + +In the nic attach path, we skip doing dhcp since we already did it +when bringing the interface up. However when polling for +reprovisiondata, it is possible for the request to timeout due to +platform issues. In those cases we still need to do dhcp and try again +since we tear down the context. We can only skip the first dhcp +attempt. +--- + cloudinit/sources/DataSourceAzure.py | 4 +++ + tests/unittests/test_datasource/test_azure.py | 34 +++++++++++++++++++ + 2 files changed, 38 insertions(+) + +--- a/cloudinit/sources/DataSourceAzure.py ++++ b/cloudinit/sources/DataSourceAzure.py +@@ -1317,6 +1317,10 @@ class DataSourceAzure(sources.DataSource + except UrlError: + # Teardown our EphemeralDHCPv4 context on failure as we retry + self._ephemeral_dhcp_ctx.clean_network() ++ ++ # Also reset this flag which determines if we should do dhcp ++ # during retries. ++ is_ephemeral_ctx_present = False + finally: + if nl_sock: + nl_sock.close() +--- a/tests/unittests/test_datasource/test_azure.py ++++ b/tests/unittests/test_datasource/test_azure.py +@@ -3055,6 +3055,40 @@ class TestPreprovisioningPollIMDS(CiTest + self.assertEqual(0, m_dhcp.call_count) + self.assertEqual(0, m_media_switch.call_count) + ++ @mock.patch('os.path.isfile') ++ @mock.patch(MOCKPATH + 'EphemeralDHCPv4') ++ def test_poll_imds_does_dhcp_on_retries_if_ctx_present( ++ self, m_ephemeral_dhcpv4, m_isfile, report_ready_func, m_request, ++ m_media_switch, m_dhcp, m_net): ++ """The poll_imds function should reuse the dhcp ctx if it is already ++ present. This happens when we wait for nic to be hot-attached before ++ polling for reprovisiondata. Note that if this ctx is set when ++ _poll_imds is called, then it is not expected to be waiting for ++ media_disconnect_connect either.""" ++ ++ tries = 0 ++ ++ def fake_timeout_once(**kwargs): ++ nonlocal tries ++ tries += 1 ++ if tries == 1: ++ raise requests.Timeout('Fake connection timeout') ++ return mock.MagicMock(status_code=200, text="good", content="good") ++ ++ m_request.side_effect = fake_timeout_once ++ report_file = self.tmp_path('report_marker', self.tmp) ++ m_isfile.return_value = True ++ dsa = dsaz.DataSourceAzure({}, distro=None, paths=self.paths) ++ with mock.patch(MOCKPATH + 'REPORTED_READY_MARKER_FILE', report_file),\ ++ mock.patch.object(dsa, '_ephemeral_dhcp_ctx') as m_dhcp_ctx: ++ m_dhcp_ctx.obtain_lease.return_value = "Dummy lease" ++ dsa._ephemeral_dhcp_ctx = m_dhcp_ctx ++ dsa._poll_imds() ++ self.assertEqual(1, m_dhcp_ctx.clean_network.call_count) ++ self.assertEqual(1, m_ephemeral_dhcpv4.call_count) ++ self.assertEqual(0, m_media_switch.call_count) ++ self.assertEqual(2, m_request.call_count) ++ + def test_does_not_poll_imds_report_ready_when_marker_file_exists( + self, m_report_ready, m_request, m_media_switch, m_dhcp, m_net): + """poll_imds should not call report ready when the reported ready diff --git a/debian/patches/cpick-e69a8874-Set-Azure-to-only-update-metadata-on-BOOT_NEW_INSTANCE b/debian/patches/cpick-e69a8874-Set-Azure-to-only-update-metadata-on-BOOT_NEW_INSTANCE new file mode 100644 index 00000000..c6ff7345 --- /dev/null +++ b/debian/patches/cpick-e69a8874-Set-Azure-to-only-update-metadata-on-BOOT_NEW_INSTANCE @@ -0,0 +1,55 @@ +From e69a88745e37061e0ab0a1e67ad11015cca610c1 Mon Sep 17 00:00:00 2001 +From: James Falcon +Date: Fri, 3 Sep 2021 12:57:20 -0500 +Subject: [PATCH] Set Azure to only update metadata on BOOT_NEW_INSTANCE + (#1006) + +In #834, we refactored the handling of events for fetching new metadata. +Previously, in Azure's __init__, the BOOT event was added to the +update_events, so it was assumed that Azure required the standard BOOT +behavior, which is to apply metadata twice every boot: once during +local-init, then again during standard init phase. +https://github.com/canonical/cloud-init/blob/21.2/cloudinit/sources/DataSourceAzure.py#L356 + +However, this line was effectively meaningless. After the metadata was +fetched in local-init, it was then pickled out to disk. Because +"update_events" was a class variable, the EventType.BOOT was not +persisted into the pickle. When the pickle was then unpickled in the +init phase, metadata did not get re-fetched because EventType.BOOT was +not present, so Azure is effectely only BOOT_NEW_INSTANCE. + +Fetching metadata twice during boot causes some issue for +pre-provisioning on Azure because updating metadata during +re-provisioning will cause cloud-init to poll for reprovisiondata again +in DataSourceAzure, which will infinitely return 404(reprovisiondata +is deleted from IMDS after health signal was sent by cloud-init during +init-local). This makes cloud-init stuck in 'init' +--- + cloudinit/sources/DataSourceAzure.py | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +--- a/cloudinit/sources/DataSourceAzure.py ++++ b/cloudinit/sources/DataSourceAzure.py +@@ -22,7 +22,7 @@ import requests + from cloudinit import dmi + from cloudinit import log as logging + from cloudinit import net +-from cloudinit.event import EventScope, EventType ++from cloudinit.event import EventType + from cloudinit.net import device_driver + from cloudinit.net.dhcp import EphemeralDHCPv4 + from cloudinit import sources +@@ -339,13 +339,6 @@ def temporary_hostname(temp_hostname, cf + class DataSourceAzure(sources.DataSource): + + dsname = 'Azure' +- # Regenerate network config new_instance boot and every boot +- default_update_events = {EventScope.NETWORK: { +- EventType.BOOT_NEW_INSTANCE, +- EventType.BOOT, +- EventType.BOOT_LEGACY +- }} +- + _negotiated = False + _metadata_imds = sources.UNSET + _ci_pkl_version = 1 diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 00000000..b43f57c1 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,2 @@ +cpick-28e56d99-Azure-Retry-dhcp-on-timeouts-when-polling +cpick-e69a8874-Set-Azure-to-only-update-metadata-on-BOOT_NEW_INSTANCE -- cgit v1.2.1