Blob Blame History Raw
From 9e3ac98097ed1c7f49ec8975a40aec7229231aae Mon Sep 17 00:00:00 2001
From: Louis Bouchard <bouchard.louis@gmail.com>
Date: Wed, 29 Jan 2020 16:55:09 +0100
Subject: [PATCH] Scaleway: Fix DatasourceScaleway to avoid backtrace (#128)

Make sure network_config is created when self._network_config is unset.

Co-authored-by: Scott Moser <smoser@brickies.net>
---
 cloudinit/sources/DataSourceScaleway.py       |  9 +++-
 .../test_datasource/test_scaleway.py          | 49 +++++++++++++++++++
 2 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/cloudinit/sources/DataSourceScaleway.py b/cloudinit/sources/DataSourceScaleway.py
index b573b382..83c2bf65 100644
--- a/cloudinit/sources/DataSourceScaleway.py
+++ b/cloudinit/sources/DataSourceScaleway.py
@@ -188,7 +188,7 @@ class DataSourceScaleway(sources.DataSource):
         self.retries = int(self.ds_cfg.get('retries', DEF_MD_RETRIES))
         self.timeout = int(self.ds_cfg.get('timeout', DEF_MD_TIMEOUT))
         self._fallback_interface = None
-        self._network_config = None
+        self._network_config = sources.UNSET
 
     def _crawl_metadata(self):
         resp = url_helper.readurl(self.metadata_address,
@@ -227,7 +227,12 @@ class DataSourceScaleway(sources.DataSource):
         Configure networking according to data received from the
         metadata API.
         """
-        if self._network_config:
+        if self._network_config is None:
+            LOG.warning('Found None as cached _network_config. '
+                        'Resetting to %s', sources.UNSET)
+            self._network_config = sources.UNSET
+
+        if self._network_config != sources.UNSET:
             return self._network_config
 
         if self._fallback_interface is None:
diff --git a/tests/unittests/test_datasource/test_scaleway.py b/tests/unittests/test_datasource/test_scaleway.py
index f96bf0a2..1b4dd0ad 100644
--- a/tests/unittests/test_datasource/test_scaleway.py
+++ b/tests/unittests/test_datasource/test_scaleway.py
@@ -7,6 +7,7 @@ import requests
 
 from cloudinit import helpers
 from cloudinit import settings
+from cloudinit import sources
 from cloudinit.sources import DataSourceScaleway
 
 from cloudinit.tests.helpers import mock, HttprettyTestCase, CiTestCase
@@ -403,3 +404,51 @@ class TestDataSourceScaleway(HttprettyTestCase):
 
         netcfg = self.datasource.network_config
         self.assertEqual(netcfg, '0xdeadbeef')
+
+    @mock.patch('cloudinit.sources.DataSourceScaleway.net.find_fallback_nic')
+    @mock.patch('cloudinit.util.get_cmdline')
+    def test_network_config_unset(self, m_get_cmdline, fallback_nic):
+        """
+        _network_config will be set to sources.UNSET after the first boot.
+        Make sure it behave correctly.
+        """
+        m_get_cmdline.return_value = 'scaleway'
+        fallback_nic.return_value = 'ens2'
+        self.datasource.metadata['ipv6'] = None
+        self.datasource._network_config = sources.UNSET
+
+        resp = {'version': 1,
+                'config': [{
+                     'type': 'physical',
+                     'name': 'ens2',
+                     'subnets': [{'type': 'dhcp4'}]}]
+                }
+
+        netcfg = self.datasource.network_config
+        self.assertEqual(netcfg, resp)
+
+    @mock.patch('cloudinit.sources.DataSourceScaleway.LOG.warning')
+    @mock.patch('cloudinit.sources.DataSourceScaleway.net.find_fallback_nic')
+    @mock.patch('cloudinit.util.get_cmdline')
+    def test_network_config_cached_none(self, m_get_cmdline, fallback_nic,
+                                        logwarning):
+        """
+        network_config() should return config data if cached data is None
+        rather than sources.UNSET
+        """
+        m_get_cmdline.return_value = 'scaleway'
+        fallback_nic.return_value = 'ens2'
+        self.datasource.metadata['ipv6'] = None
+        self.datasource._network_config = None
+
+        resp = {'version': 1,
+                'config': [{
+                     'type': 'physical',
+                     'name': 'ens2',
+                     'subnets': [{'type': 'dhcp4'}]}]
+                }
+
+        netcfg = self.datasource.network_config
+        self.assertEqual(netcfg, resp)
+        logwarning.assert_called_with('Found None as cached _network_config. '
+                                      'Resetting to %s', sources.UNSET)
-- 
2.18.1