From bbbb3fb816aa223b8f62dbe01e46bf6b296c85b2 Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Wed, 2 Feb 2022 16:12:32 -0700 Subject: [PATCH 1/3] integration: do not bind mount /etc/cloud/cloud.cfg.d Since lxc bind mounts will be read-only as nobody:nogroup we don't want to bind mount /etc/cloud/cloud.cfg.d into the instance because some tests add artifacts to /etc/cloud/cloud.cfg.d. Also make LXD push_file pull_file methods assert that the file transfer was a success, otherwise we miss the root-cause for test failures. --- tests/integration_tests/clouds.py | 18 +++++++++++++++--- tests/integration_tests/instances.py | 4 ++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tests/integration_tests/clouds.py b/tests/integration_tests/clouds.py index 81d5b9a088d..903ac14acf2 100644 --- a/tests/integration_tests/clouds.py +++ b/tests/integration_tests/clouds.py @@ -134,7 +134,7 @@ def launch( user_data=None, launch_kwargs=None, settings=integration_settings, - **kwargs + **kwargs, ) -> IntegrationInstance: if launch_kwargs is None: launch_kwargs = {} @@ -260,7 +260,7 @@ def _mount_source(instance: LXDInstance): (cloudinit_path, "/usr/lib/python3/dist-packages/cloudinit"), ( os.path.join(cloudinit_path, "..", "config", "cloud.cfg.d"), - "/etc/cloud/cloud.cfg.d", + "/var/tmp/etc/cloud/cloud.cfg.d", ), ( os.path.join(cloudinit_path, "..", "templates"), @@ -286,6 +286,18 @@ def _mount_source(instance: LXDInstance): ).format(**format_variables) subp(command.split()) + # /etc/cloud/cloud.cfg.d is a directory we write to in some + # integration tests. We can't use lxc mount in the container + # as /etc/cloud/cloud.cfg.d will then be owned nobody:nogroup and be + # read-only for root. + # Instead copy static files to the instance under test. + config_dir = os.path.join( + cloudinit_path, "..", "config", "cloud.cfg.d" + ) + for src_file in os.listdir(config_dir): + command = f"lxc file push {config_dir}/{src_file} {instance.name}/etc/cloud/cloud.cfg.d/" + subp(command.split()) + def _perform_launch(self, launch_kwargs, **kwargs): launch_kwargs["inst_type"] = launch_kwargs.pop("instance_type", None) wait = launch_kwargs.pop("wait", True) @@ -304,7 +316,7 @@ def _perform_launch(self, launch_kwargs, **kwargs): launch_kwargs.pop("name", default_name), release, profile_list=profile_list, - **launch_kwargs + **launch_kwargs, ) if self.settings.CLOUD_INIT_SOURCE == "IN_PLACE": self._mount_source(pycloudlib_instance) diff --git a/tests/integration_tests/instances.py b/tests/integration_tests/instances.py index e3d597affb9..f30456fc282 100644 --- a/tests/integration_tests/instances.py +++ b/tests/integration_tests/instances.py @@ -81,13 +81,13 @@ def pull_file(self, remote_path, local_path): # First copy to a temporary directory because of permissions issues tmp_path = _get_tmp_path() self.instance.execute("cp {} {}".format(str(remote_path), tmp_path)) - self.instance.pull_file(tmp_path, str(local_path)) + assert self.instance.pull_file(tmp_path, str(local_path)).ok def push_file(self, local_path, remote_path): # First push to a temporary directory because of permissions issues tmp_path = _get_tmp_path() self.instance.push_file(str(local_path), tmp_path) - self.execute("mv {} {}".format(tmp_path, str(remote_path))) + assert self.execute("mv {} {}".format(tmp_path, str(remote_path))).ok def read_from_file(self, remote_path) -> str: result = self.execute("cat {}".format(remote_path)) From b8c447ff414871ef5e9944482d51f278d8ebce35 Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Wed, 2 Feb 2022 16:14:24 -0700 Subject: [PATCH 2/3] tests: update pycloudlib deps to add Azure Jammy image support --- integration-requirements.txt | 2 +- tests/integration_tests/clouds.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/integration-requirements.txt b/integration-requirements.txt index f6c52b280da..37a2ed76e27 100644 --- a/integration-requirements.txt +++ b/integration-requirements.txt @@ -1,5 +1,5 @@ # PyPI requirements for cloud-init integration testing # https://cloudinit.readthedocs.io/en/latest/topics/integration_tests.html # -pycloudlib @ git+https://github.com/canonical/pycloudlib.git@e52cc257c5467bb16442a8ef943ca1931c4e1757 +pycloudlib @ git+https://github.com/canonical/pycloudlib.git@d8c7654dbef1a7daf47417337e50515e6842aed6 pytest diff --git a/tests/integration_tests/clouds.py b/tests/integration_tests/clouds.py index 903ac14acf2..b6990d9c5a9 100644 --- a/tests/integration_tests/clouds.py +++ b/tests/integration_tests/clouds.py @@ -295,7 +295,10 @@ def _mount_source(instance: LXDInstance): cloudinit_path, "..", "config", "cloud.cfg.d" ) for src_file in os.listdir(config_dir): - command = f"lxc file push {config_dir}/{src_file} {instance.name}/etc/cloud/cloud.cfg.d/" + command = ( + f"lxc file push {config_dir}/{src_file} " + f"{instance.name}/etc/cloud/cloud.cfg.d/" + ) subp(command.split()) def _perform_launch(self, launch_kwargs, **kwargs): From a62ef18273af85d880faea9e10ffff6280c94ebd Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Wed, 2 Feb 2022 20:50:29 -0700 Subject: [PATCH 3/3] tests: drop mount of cloud.cfg.d --- tests/integration_tests/clouds.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/integration_tests/clouds.py b/tests/integration_tests/clouds.py index b6990d9c5a9..ef6133390db 100644 --- a/tests/integration_tests/clouds.py +++ b/tests/integration_tests/clouds.py @@ -258,10 +258,6 @@ def _mount_source(instance: LXDInstance): cloudinit_path = cloudinit.__path__[0] mounts = [ (cloudinit_path, "/usr/lib/python3/dist-packages/cloudinit"), - ( - os.path.join(cloudinit_path, "..", "config", "cloud.cfg.d"), - "/var/tmp/etc/cloud/cloud.cfg.d", - ), ( os.path.join(cloudinit_path, "..", "templates"), "/etc/cloud/templates",