|
|
591b7e |
From bbe1338c356cb5bbc1196b7f4ba620f95d2b5fd1 Mon Sep 17 00:00:00 2001
|
|
|
591b7e |
From: Eduardo Otubo <otubo@redhat.com>
|
|
|
591b7e |
Date: Tue, 5 May 2020 08:08:18 +0200
|
|
|
591b7e |
Subject: [PATCH 3/5] exoscale: fix sysconfig cloud_config_modules overrides
|
|
|
591b7e |
|
|
|
591b7e |
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
|
|
591b7e |
Message-id: <20200504085238.25884-4-otubo@redhat.com>
|
|
|
591b7e |
Patchwork-id: 96246
|
|
|
591b7e |
O-Subject: [RHEL-7.8.z cloud-init PATCH 3/5] exoscale: fix sysconfig cloud_config_modules overrides
|
|
|
591b7e |
Bugzilla: 1827207
|
|
|
591b7e |
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
|
591b7e |
RH-Acked-by: Mohammed Gamal <mgamal@redhat.com>
|
|
|
591b7e |
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
|
|
591b7e |
|
|
|
591b7e |
commit d1b022217a652c7a84d5430c9e571987864d3982
|
|
|
591b7e |
Author: Chad Smith <chad.smith@canonical.com>
|
|
|
591b7e |
Date: Wed Aug 28 00:58:16 2019 +0000
|
|
|
591b7e |
|
|
|
591b7e |
exoscale: fix sysconfig cloud_config_modules overrides
|
|
|
591b7e |
|
|
|
591b7e |
Make sure Exoscale supplements or overrides existing system config
|
|
|
591b7e |
setting cloud_config_modules instead of replacing it with a one item
|
|
|
591b7e |
list set-passords
|
|
|
591b7e |
|
|
|
591b7e |
LP: #1841454
|
|
|
591b7e |
|
|
|
591b7e |
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
|
|
591b7e |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
591b7e |
---
|
|
|
591b7e |
cloudinit/sources/DataSourceExoscale.py | 26 ++++++++++++++++--------
|
|
|
591b7e |
tests/unittests/test_datasource/test_exoscale.py | 24 ++++++++++++++--------
|
|
|
591b7e |
2 files changed, 33 insertions(+), 17 deletions(-)
|
|
|
591b7e |
|
|
|
591b7e |
diff --git a/cloudinit/sources/DataSourceExoscale.py b/cloudinit/sources/DataSourceExoscale.py
|
|
|
591b7e |
index 52e7f6f..fdfb4ed 100644
|
|
|
591b7e |
--- a/cloudinit/sources/DataSourceExoscale.py
|
|
|
591b7e |
+++ b/cloudinit/sources/DataSourceExoscale.py
|
|
|
591b7e |
@@ -6,6 +6,7 @@
|
|
|
591b7e |
from cloudinit import ec2_utils as ec2
|
|
|
591b7e |
from cloudinit import log as logging
|
|
|
591b7e |
from cloudinit import sources
|
|
|
591b7e |
+from cloudinit import helpers
|
|
|
591b7e |
from cloudinit import url_helper
|
|
|
591b7e |
from cloudinit import util
|
|
|
591b7e |
|
|
|
591b7e |
@@ -20,13 +21,6 @@ URL_RETRIES = 6
|
|
|
591b7e |
|
|
|
591b7e |
EXOSCALE_DMI_NAME = "Exoscale"
|
|
|
591b7e |
|
|
|
591b7e |
-BUILTIN_DS_CONFIG = {
|
|
|
591b7e |
- # We run the set password config module on every boot in order to enable
|
|
|
591b7e |
- # resetting the instance's password via the exoscale console (and a
|
|
|
591b7e |
- # subsequent instance reboot).
|
|
|
591b7e |
- 'cloud_config_modules': [["set-passwords", "always"]]
|
|
|
591b7e |
-}
|
|
|
591b7e |
-
|
|
|
591b7e |
|
|
|
591b7e |
class DataSourceExoscale(sources.DataSource):
|
|
|
591b7e |
|
|
|
591b7e |
@@ -42,8 +36,22 @@ class DataSourceExoscale(sources.DataSource):
|
|
|
591b7e |
self.ds_cfg.get('password_server_port', PASSWORD_SERVER_PORT))
|
|
|
591b7e |
self.url_timeout = self.ds_cfg.get('timeout', URL_TIMEOUT)
|
|
|
591b7e |
self.url_retries = self.ds_cfg.get('retries', URL_RETRIES)
|
|
|
591b7e |
-
|
|
|
591b7e |
- self.extra_config = BUILTIN_DS_CONFIG
|
|
|
591b7e |
+ self.extra_config = {}
|
|
|
591b7e |
+
|
|
|
591b7e |
+ def activate(self, cfg, is_new_instance):
|
|
|
591b7e |
+ """Adjust set-passwords module to run 'always' during each boot"""
|
|
|
591b7e |
+ # We run the set password config module on every boot in order to
|
|
|
591b7e |
+ # enable resetting the instance's password via the exoscale console
|
|
|
591b7e |
+ # (and a subsequent instance reboot).
|
|
|
591b7e |
+ # Exoscale password server only provides set-passwords user-data if
|
|
|
591b7e |
+ # a user has triggered a password reset. So calling that password
|
|
|
591b7e |
+ # service generally results in no additional cloud-config.
|
|
|
591b7e |
+ # TODO(Create util functions for overriding merged sys_cfg module freq)
|
|
|
591b7e |
+ mod = 'set_passwords'
|
|
|
591b7e |
+ sem_path = self.paths.get_ipath_cur('sem')
|
|
|
591b7e |
+ sem_helper = helpers.FileSemaphores(sem_path)
|
|
|
591b7e |
+ if sem_helper.clear('config_' + mod, None):
|
|
|
591b7e |
+ LOG.debug('Overriding module set-passwords with frequency always')
|
|
|
591b7e |
|
|
|
591b7e |
def wait_for_metadata_service(self):
|
|
|
591b7e |
"""Wait for the metadata service to be reachable."""
|
|
|
591b7e |
diff --git a/tests/unittests/test_datasource/test_exoscale.py b/tests/unittests/test_datasource/test_exoscale.py
|
|
|
591b7e |
index 350c330..f006119 100644
|
|
|
591b7e |
--- a/tests/unittests/test_datasource/test_exoscale.py
|
|
|
591b7e |
+++ b/tests/unittests/test_datasource/test_exoscale.py
|
|
|
591b7e |
@@ -11,8 +11,10 @@ from cloudinit.sources.DataSourceExoscale import (
|
|
|
591b7e |
PASSWORD_SERVER_PORT,
|
|
|
591b7e |
read_metadata)
|
|
|
591b7e |
from cloudinit.tests.helpers import HttprettyTestCase, mock
|
|
|
591b7e |
+from cloudinit import util
|
|
|
591b7e |
|
|
|
591b7e |
import httpretty
|
|
|
591b7e |
+import os
|
|
|
591b7e |
import requests
|
|
|
591b7e |
|
|
|
591b7e |
|
|
|
591b7e |
@@ -63,6 +65,18 @@ class TestDatasourceExoscale(HttprettyTestCase):
|
|
|
591b7e |
password = get_password()
|
|
|
591b7e |
self.assertEqual(expected_password, password)
|
|
|
591b7e |
|
|
|
591b7e |
+ def test_activate_removes_set_passwords_semaphore(self):
|
|
|
591b7e |
+ """Allow set_passwords to run every boot by removing the semaphore."""
|
|
|
591b7e |
+ path = helpers.Paths({'cloud_dir': self.tmp})
|
|
|
591b7e |
+ sem_dir = self.tmp_path('instance/sem', dir=self.tmp)
|
|
|
591b7e |
+ util.ensure_dir(sem_dir)
|
|
|
591b7e |
+ sem_file = os.path.join(sem_dir, 'config_set_passwords')
|
|
|
591b7e |
+ with open(sem_file, 'w') as stream:
|
|
|
591b7e |
+ stream.write('')
|
|
|
591b7e |
+ ds = DataSourceExoscale({}, None, path)
|
|
|
591b7e |
+ ds.activate(None, None)
|
|
|
591b7e |
+ self.assertFalse(os.path.exists(sem_file))
|
|
|
591b7e |
+
|
|
|
591b7e |
def test_get_data(self):
|
|
|
591b7e |
"""The datasource conforms to expected behavior when supplied
|
|
|
591b7e |
full test data."""
|
|
|
591b7e |
@@ -95,8 +109,6 @@ class TestDatasourceExoscale(HttprettyTestCase):
|
|
|
591b7e |
self.assertEqual(ds.get_config_obj(),
|
|
|
591b7e |
{'ssh_pwauth': True,
|
|
|
591b7e |
'password': expected_password,
|
|
|
591b7e |
- 'cloud_config_modules': [
|
|
|
591b7e |
- ["set-passwords", "always"]],
|
|
|
591b7e |
'chpasswd': {
|
|
|
591b7e |
'expire': False,
|
|
|
591b7e |
}})
|
|
|
591b7e |
@@ -130,9 +142,7 @@ class TestDatasourceExoscale(HttprettyTestCase):
|
|
|
591b7e |
self.assertEqual(ds.userdata_raw.decode("utf-8"), "#cloud-config")
|
|
|
591b7e |
self.assertEqual(ds.metadata, {"instance-id": expected_id,
|
|
|
591b7e |
"local-hostname": expected_hostname})
|
|
|
591b7e |
- self.assertEqual(ds.get_config_obj(),
|
|
|
591b7e |
- {'cloud_config_modules': [
|
|
|
591b7e |
- ["set-passwords", "always"]]})
|
|
|
591b7e |
+ self.assertEqual(ds.get_config_obj(), {})
|
|
|
591b7e |
|
|
|
591b7e |
def test_get_data_no_password(self):
|
|
|
591b7e |
"""The datasource conforms to expected behavior when no password is
|
|
|
591b7e |
@@ -163,9 +173,7 @@ class TestDatasourceExoscale(HttprettyTestCase):
|
|
|
591b7e |
self.assertEqual(ds.userdata_raw.decode("utf-8"), "#cloud-config")
|
|
|
591b7e |
self.assertEqual(ds.metadata, {"instance-id": expected_id,
|
|
|
591b7e |
"local-hostname": expected_hostname})
|
|
|
591b7e |
- self.assertEqual(ds.get_config_obj(),
|
|
|
591b7e |
- {'cloud_config_modules': [
|
|
|
591b7e |
- ["set-passwords", "always"]]})
|
|
|
591b7e |
+ self.assertEqual(ds.get_config_obj(), {})
|
|
|
591b7e |
|
|
|
591b7e |
@mock.patch('cloudinit.sources.DataSourceExoscale.get_password')
|
|
|
591b7e |
def test_read_metadata_when_password_server_unreachable(self, m_password):
|
|
|
591b7e |
--
|
|
|
591b7e |
1.8.3.1
|
|
|
591b7e |
|