From eb1965a434360b3198768302f4196488d7c2511f Mon Sep 17 00:00:00 2001 From: Bryan Fraschetti Date: Mon, 3 Feb 2025 16:13:19 -0500 Subject: [PATCH] Fix: GCE _get_data crashes if DHCP lease fails (#5998) This commit addresses issue #5997 which reported crashes in init-local when cloud-init was examining GCELocal as a potential datasource. When all NICs failed at DHCP discovery cloud-init attempts to log the events by dereferencing a value that was never assigned. This commit modifies the _get_data function of DataSourceGCE.py by adding an empty dictionary definition for the ret variable at the top level of the function and some debugging logs when a candidate NIC fails to obtain a DHCP lease. At the same time, the commit replaces the direct key access operator on ret with the safe lookup method get(). This commit also adds a unit test that mocks the observed situation. Reference:https://github.com/canonical/cloud-init/commit/eb1965a434360b3198768302f4196488d7c2511f Conflict:not change test_gce.py (M_PATH and net.find_candidate_nics doesn't exist) Fixes GH-5997 --- cloudinit/sources/DataSourceGCE.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/cloudinit/sources/DataSourceGCE.py b/cloudinit/sources/DataSourceGCE.py index c730ae8..87dc4e0 100644 --- a/cloudinit/sources/DataSourceGCE.py +++ b/cloudinit/sources/DataSourceGCE.py @@ -88,6 +88,7 @@ class DataSourceGCE(sources.DataSource): def _get_data(self): url_params = self.get_url_params() + ret = {} if self.perform_dhcp_setup: candidate_nics = net.find_candidate_nics() if DEFAULT_PRIMARY_INTERFACE in candidate_nics: @@ -122,6 +123,9 @@ class DataSourceGCE(sources.DataSource): ) continue except NoDHCPLeaseError: + LOG.debug( + "Unable to obtain a DHCP lease for %s", candidate_nic + ) continue if ret["success"]: self._fallback_interface = candidate_nic @@ -142,14 +146,14 @@ class DataSourceGCE(sources.DataSource): }, ) - if not ret["success"]: - if ret["platform_reports_gce"]: - LOG.warning(ret["reason"]) + if not ret.get("success"): + if ret.get("platform_reports_gce"): + LOG.warning(ret.get("reason")) else: - LOG.debug(ret["reason"]) + LOG.debug(ret.get("reason")) return False - self.metadata = ret["meta-data"] - self.userdata_raw = ret["user-data"] + self.metadata = ret.get("meta-data") + self.userdata_raw = ret.get("user-data") return True @property -- 2.33.0