Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cloudinit/config/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ def _fixup_modules(self, raw_mods) -> List[ModuleDetails]:
raw_name,
freq,
)
# Reset it so when ran it will get set to a known value
# Misconfigured in /etc/cloud/cloud.cfg. Reset so cc_* module
# default meta attribute "frequency" value is used.
freq = None
mod_locs, looked_locs = importer.find_module(
mod_name, ["", type_utils.obj_name(config)], ["handle"]
Expand All @@ -186,6 +187,9 @@ def _fixup_modules(self, raw_mods) -> List[ModuleDetails]:
continue
mod = importer.import_module(mod_locs[0])
validate_module(mod, raw_name)
if freq is None:
Comment thread
blackboxsw marked this conversation as resolved.
# Use cc_* module default setting since no cloud.cfg overrides
freq = mod.meta["frequency"]
mostly_mods.append(
ModuleDetails(
module=mod,
Expand Down
24 changes: 24 additions & 0 deletions tests/integration_tests/modules/test_combined.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
the same instance launch. Most independent module coherence tests can go
here.
"""
import glob
import importlib
import json
import re
import uuid
from pathlib import Path

import pytest

import cloudinit.config
from tests.integration_tests.clouds import ImageSpecification
from tests.integration_tests.decorators import retry
from tests.integration_tests.instances import IntegrationInstance
Expand Down Expand Up @@ -223,6 +227,26 @@ def test_cloud_id_file_symlink(self, class_client: IntegrationInstance):
class_client.execute("stat -c %N /run/cloud-init/cloud-id")
)

def test_run_frequency(self, class_client: IntegrationInstance):
log = class_client.read_from_file("/var/log/cloud-init.log")
config_dir = Path(cloudinit.config.__file__).parent
module_paths = glob.glob(str(config_dir / "cc*.py"))
module_names = [Path(x).stem for x in module_paths]
found_count = 0
for name in module_names:
mod = importlib.import_module(f"cloudinit.config.{name}")
frequency = mod.meta["frequency"]
# cc_ gets replaced with config- in logs
log_name = name.replace("cc_", "config-")
# Some modules have been filtered out in /etc/cloud/cloud.cfg,
if f"running {log_name}" in log:
found_count += 1 # Ensure we're matching on the right text
assert f"running {log_name} with frequency {frequency}" in log
assert (
found_count > 10
), "Not enough modules found in log. Did the log message change?"
assert "with frequency None" not in log

def _check_common_metadata(self, data):
assert data["base64_encoded_keys"] == []
assert data["merged_cfg"] == "redacted for non-root user"
Expand Down
33 changes: 33 additions & 0 deletions tests/integration_tests/modules/test_frequency_override.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import pytest

from tests.integration_tests.instances import IntegrationInstance

USER_DATA = """\
#cloud-config
runcmd:
- echo "hi" >> /var/tmp/hi
"""


@pytest.mark.user_data(USER_DATA)
def test_frequency_override(client: IntegrationInstance):
# Some pre-checks
assert (
"running config-scripts-user with frequency once-per-instance"
in client.read_from_file("/var/log/cloud-init.log")
)
assert client.read_from_file("/var/tmp/hi").strip().count("hi") == 1

# Change frequency of scripts-user to always
config = client.read_from_file("/etc/cloud/cloud.cfg")
new_config = config.replace("- scripts-user", "- [ scripts-user, always ]")
client.write_to_file("/etc/cloud/cloud.cfg", new_config)

client.restart()

# Ensure the script was run again
assert (
"running config-scripts-user with frequency always"
in client.read_from_file("/var/log/cloud-init.log")
)
assert client.read_from_file("/var/tmp/hi").strip().count("hi") == 2
6 changes: 6 additions & 0 deletions tests/integration_tests/modules/test_write_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
defer: true
owner: 'myuser'
permissions: '0644'
append: true
""".format(
B64_CONTENT.decode("ascii")
)
Expand Down Expand Up @@ -91,3 +92,8 @@ def test_write_files_deferred(self, class_client):
class_client.execute('stat -c "%U %a" /home/testuser/my-file')
== "myuser 644"
)
# Assert write_files per-instance is honored and run only once.
# Given append: true multiple runs across would append new content.
class_client.restart()
out = class_client.read_from_file("/home/testuser/my-file")
assert "echo 'hello world!'" == out