summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authord1r3ct0r <calvin.mwadime@canonical.com>2023-02-03 05:08:22 +0300
committerGitHub <noreply@github.com>2023-02-02 19:08:22 -0700
commit3b8b46926b7ef46ac0ee73d51285dd274906e4f3 (patch)
treeed9d9a0618ef7ab40c68309ad1754522ab7d4c62
parente06e501e2d93254001f157fda29dadada072add6 (diff)
downloadcloud-init-git-3b8b46926b7ef46ac0ee73d51285dd274906e4f3.tar.gz
cloud-id: better handling of change in datasource files
Stop deleting cloud-id-<cloudname> unless there is a change in discovered datasource cloud-id. LP: #1998998
-rw-r--r--cloudinit/sources/__init__.py11
-rw-r--r--tests/integration_tests/modules/test_combined.py17
-rw-r--r--tests/unittests/sources/test_init.py10
3 files changed, 31 insertions, 7 deletions
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
index 85e094ac..12430401 100644
--- a/cloudinit/sources/__init__.py
+++ b/cloudinit/sources/__init__.py
@@ -435,12 +435,15 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
cloud_id = instance_data["v1"].get("cloud_id", "none")
cloud_id_file = os.path.join(self.paths.run_dir, "cloud-id")
util.write_file(f"{cloud_id_file}-{cloud_id}", f"{cloud_id}\n")
+ # cloud-id not found, then no previous cloud-id fle
+ prev_cloud_id_file = None
+ new_cloud_id_file = f"{cloud_id_file}-{cloud_id}"
+ # cloud-id found, then the prev cloud-id file is source of symlink
if os.path.exists(cloud_id_file):
prev_cloud_id_file = os.path.realpath(cloud_id_file)
- else:
- prev_cloud_id_file = cloud_id_file
- util.sym_link(f"{cloud_id_file}-{cloud_id}", cloud_id_file, force=True)
- if prev_cloud_id_file != cloud_id_file:
+
+ util.sym_link(new_cloud_id_file, cloud_id_file, force=True)
+ if prev_cloud_id_file and prev_cloud_id_file != new_cloud_id_file:
util.del_file(prev_cloud_id_file)
write_json(json_sensitive_file, processed_data, mode=0o600)
json_file = self.paths.get_runpath("instance_data")
diff --git a/tests/integration_tests/modules/test_combined.py b/tests/integration_tests/modules/test_combined.py
index 3c1013eb..647e8728 100644
--- a/tests/integration_tests/modules/test_combined.py
+++ b/tests/integration_tests/modules/test_combined.py
@@ -424,6 +424,23 @@ class TestCombined:
assert v1_data["instance_id"] == client.instance.instance_id
assert v1_data["local_hostname"] == client.instance.name
+ @pytest.mark.lxd_container
+ @pytest.mark.azure
+ @pytest.mark.gce
+ @pytest.mark.ec2
+ def test_instance_cloud_id_across_reboot(
+ self, class_client: IntegrationInstance
+ ):
+ client = class_client
+ platform = client.settings.PLATFORM
+ cloud_id_alias = {"ec2": "aws", "lxd_container": "lxd"}
+ cloud_file = f"cloud-id-{cloud_id_alias.get(platform, platform)}"
+ assert client.execute(f"test -f /run/cloud-init/{cloud_file}").ok
+ assert client.execute("test -f /run/cloud-init/cloud-id").ok
+ client.restart()
+ assert client.execute(f"test -f /run/cloud-init/{cloud_file}").ok
+ assert client.execute("test -f /run/cloud-init/cloud-id").ok
+
@pytest.mark.user_data(USER_DATA)
class TestCombinedNoCI:
diff --git a/tests/unittests/sources/test_init.py b/tests/unittests/sources/test_init.py
index a81c33a2..0447e02c 100644
--- a/tests/unittests/sources/test_init.py
+++ b/tests/unittests/sources/test_init.py
@@ -716,9 +716,13 @@ class TestDataSource(CiTestCase):
"cloudinit.sources.canonical_cloud_id", return_value="my-cloud"
):
datasource.get_data()
- self.assertEqual("my-cloud\n", util.load_file(cloud_id_link))
- # A symlink with the generic /run/cloud-init/cloud-id link is present
- self.assertTrue(util.is_link(cloud_id_link))
+ self.assertEqual("my-cloud\n", util.load_file(cloud_id_link))
+ # A symlink with the generic /run/cloud-init/cloud-id
+ # link is present
+ self.assertTrue(util.is_link(cloud_id_link))
+ datasource.persist_instance_data()
+ # cloud-id<cloud-type> not deleted: no cloud-id change
+ self.assertTrue(os.path.exists(cloud_id_file))
# When cloud-id changes, symlink and content change
with mock.patch(
"cloudinit.sources.canonical_cloud_id", return_value="my-cloud2"