← Back to team overview

cloud-init-dev team mailing list archive

[Merge] ~chad.smith/cloud-init:bug/1841454-exoscale-config-modules into cloud-init:master

 

Chad Smith has proposed merging ~chad.smith/cloud-init:bug/1841454-exoscale-config-modules into cloud-init:master.

Commit message:
exoscale: fix sysconfig cloud_config_modules overrides

Make sure Exoscale supplements or overrides existing system config
setting cloud_config_modules instead of replacing it with a one item
list set-passords

LP: #1841454


Requested reviews:
  cloud-init commiters (cloud-init-dev)
Related bugs:
  Bug #1841454 in cloud-init: "Exoscale datasource overwrites *all* cloud_config_modules"
  https://bugs.launchpad.net/cloud-init/+bug/1841454

For more details, see:
https://code.launchpad.net/~chad.smith/cloud-init/+git/cloud-init/+merge/371823
-- 
Your team cloud-init commiters is requested to review the proposed merge of ~chad.smith/cloud-init:bug/1841454-exoscale-config-modules into cloud-init:master.
diff --git a/cloudinit/sources/DataSourceExoscale.py b/cloudinit/sources/DataSourceExoscale.py
index 52e7f6f..14be3fd 100644
--- a/cloudinit/sources/DataSourceExoscale.py
+++ b/cloudinit/sources/DataSourceExoscale.py
@@ -20,12 +20,10 @@ URL_RETRIES = 6
 
 EXOSCALE_DMI_NAME = "Exoscale"
 
-BUILTIN_DS_CONFIG = {
-    # We run the set password config module on every boot in order to enable
-    # resetting the instance's password via the exoscale console (and a
-    # subsequent instance reboot).
-    'cloud_config_modules': [["set-passwords", "always"]]
-}
+# We run the set password config module on every boot in order to enable
+# resetting the instance's password via the exoscale console (and a
+# subsequent instance reboot).
+BUILTIN_SYS_CONFIG_MODULE_OVERRIDES = [['set-passwords', 'always']]
 
 
 class DataSourceExoscale(sources.DataSource):
@@ -43,7 +41,20 @@ class DataSourceExoscale(sources.DataSource):
         self.url_timeout = self.ds_cfg.get('timeout', URL_TIMEOUT)
         self.url_retries = self.ds_cfg.get('retries', URL_RETRIES)
 
-        self.extra_config = BUILTIN_DS_CONFIG
+        # Override sysconfig cloud_config_modules frequency with builtin
+        cloud_config_modules = []
+        for config_module in sys_cfg.get('cloud_config_modules', []):
+            for name, frequency in BUILTIN_SYS_CONFIG_MODULE_OVERRIDES:
+                if config_module[0] == name:  # handle tuple/lists
+                    cloud_config_modules.append([name, frequency])
+                elif config_module == name:   # handle str
+                    cloud_config_modules.append([name, frequency])
+                else:
+                    cloud_config_modules.append(config_module)
+        for override in BUILTIN_SYS_CONFIG_MODULE_OVERRIDES:
+            if override not in cloud_config_modules:
+                cloud_config_modules.append(override)
+        self.extra_config = {'cloud_config_modules': cloud_config_modules}
 
     def wait_for_metadata_service(self):
         """Wait for the metadata service to be reachable."""
diff --git a/tests/unittests/test_datasource/test_exoscale.py b/tests/unittests/test_datasource/test_exoscale.py
index 350c330..9663845 100644
--- a/tests/unittests/test_datasource/test_exoscale.py
+++ b/tests/unittests/test_datasource/test_exoscale.py
@@ -63,6 +63,28 @@ class TestDatasourceExoscale(HttprettyTestCase):
         password = get_password()
         self.assertEqual(expected_password, password)
 
+    def test_init_extends_existing_sys_config_cloud_config_modules(self):
+        """Extend any existing cloud_config_modules settings from SysConfig."""
+        ds = DataSourceExoscale(
+            {'cloud_config_modules': ['something']}, None, {})
+        self.assertEqual(
+            ['something', ['set-passwords', 'always']],
+            ds.get_config_obj()['cloud_config_modules'])
+
+    def test_init_replaces_existing_sys_config_cloud_config_modules(self):
+        """Replace set-passwords when present in SysConfig settings."""
+        ds = DataSourceExoscale(
+            {'cloud_config_modules': ['set-passwords', 'something']}, None, {})
+        self.assertEqual(
+            [['set-passwords', 'always'], 'something'],
+            ds.get_config_obj()['cloud_config_modules'])
+        ds = DataSourceExoscale(
+            {'cloud_config_modules': [
+                 ['set-passwords', 'per-instance'], 'something']}, None, {})
+        self.assertEqual(
+            [['set-passwords', 'always'], 'something'],
+            ds.get_config_obj()['cloud_config_modules'])
+
     def test_get_data(self):
         """The datasource conforms to expected behavior when supplied
         full test data."""

Follow ups