Skip to content

Commit

Permalink
extra coverage and fallback to VERSION_CODENAME
Browse files Browse the repository at this point in the history
  • Loading branch information
holmanb committed Mar 6, 2024
1 parent 0daf83a commit 3e5c785
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 18 deletions.
5 changes: 3 additions & 2 deletions cloudinit/sources/DataSourceWSL.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,14 @@ def candidate_user_data_file_names(instance_name) -> List[str]:
Return a list of candidate file names that may contain user-data
in some supported format, ordered by precedence.
"""
distribution_id, version_id, _ = util.get_linux_distro()
distribution_id, version_id, version_codename = util.get_linux_distro()
version = version_id if version_id else version_codename

return [
# WSL instance specific:
"%s.user-data" % instance_name,
# release codename specific
"%s-%s.user-data" % (distribution_id, version_id),
"%s-%s.user-data" % (distribution_id, version),
# distribution specific (Alpine, Arch, Fedora, openSUSE, Ubuntu...)
"%s-all.user-data" % distribution_id,
# generic, valid for all WSL distros and instances.
Expand Down
6 changes: 4 additions & 2 deletions doc/rtd/reference/datasources/wsl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ order specified below:
instance named ``Sid-MLKit``.

2. ``%USERPROFILE%\.cloud-init\<ID>-<VERSION_ID>.user-data`` for the
distro-specific configuration, matched by the distro ID and VERSION_CODENAME
entries as specified in ``/etc/os-release``. Example:
distro-specific configuration, matched by the distro ID and VERSION_ID
entries as specified in ``/etc/os-release``. If VERSION_ID is not present,
then VERSION_CODENAME will be used instead.
Example:
``ubuntu-22.04.user-data`` will affect any instance created from an Ubuntu
22.04 Jammy Jellyfish image if a more specific configuration file does not
match.
Expand Down
35 changes: 27 additions & 8 deletions tests/unittests/sources/test_wsl.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
},
}
SAMPLE_LINUX_DISTRO = ("ubuntu", "24.04", "noble")
SAMPLE_LINUX_DISTRO_NO_VERSION_ID = ("debian", "", "trixie")


class TestWSLHelperFunctions:
Expand Down Expand Up @@ -122,19 +123,37 @@ def test_cmd_exe_no_win_mounts(self, m_mounts, m_os_access):
with pytest.raises(IOError):
wsl.cmd_executable()

@pytest.mark.parametrize(
"linux_distro_value,files",
(
(
SAMPLE_LINUX_DISTRO,
[
f"{INSTANCE_NAME}.user-data",
"ubuntu-24.04.user-data",
"ubuntu-all.user-data",
"default.user-data",
],
),
(
SAMPLE_LINUX_DISTRO_NO_VERSION_ID,
[
f"{INSTANCE_NAME}.user-data",
"debian-trixie.user-data",
"debian-all.user-data",
"default.user-data",
],
),
),
)
@mock.patch("cloudinit.util.get_linux_distro")
def test_candidate_files(self, m_gld):
def test_candidate_files(self, m_gld, linux_distro_value, files):
"""
Validate the file names candidate for holding user-data and their
order of precedence.
"""
m_gld.return_value = SAMPLE_LINUX_DISTRO
assert [
f"{INSTANCE_NAME}.user-data",
"ubuntu-24.04.user-data",
"ubuntu-all.user-data",
"default.user-data",
] == wsl.candidate_user_data_file_names(INSTANCE_NAME)
m_gld.return_value = linux_distro_value
assert files == wsl.candidate_user_data_file_names(INSTANCE_NAME)

@pytest.mark.parametrize(
"md_content,raises,errors,warnings,md_expected",
Expand Down
57 changes: 52 additions & 5 deletions tests/unittests/test_ds_identify.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@
LOGO=ubuntu-logo
"""
),
"os_release_no_version_id": dedent(
"""\
PRETTY_NAME="Debian GNU/Linux trixie/sid"
NAME="Debian GNU/Linux"
VERSION_CODENAME="trixie"
ID=debian
"""
),
}

shell_true = 0
Expand Down Expand Up @@ -1128,9 +1136,26 @@ def test_empty_cloudinitdir(self):
)
return self._check_via_dict(data, RC_NOT_FOUND)

def test_found_via_userdata_version_codename(self):
"""WLS datasource detected by VERSION_CODENAME when no VERSION_ID"""
data = copy.deepcopy(VALID_CFG["WSL-supported-debian"])
cloudinitdir = self.tmp_dir()
data["mocks"].append(
{
"name": "WSL_cloudinit_dir_in",
"ret": 0,
"RET": cloudinitdir,
},
)
filename = os.path.join(cloudinitdir, "debian-trixie.user-data")
Path(filename).touch()
self._check_via_dict(data, RC_FOUND, dslist=[data.get("ds"), DS_NONE])
Path(filename).unlink()

def test_found_via_userdata(self):
"""Asserts that WSL datasource is found if there is applicable
userdata files inside cloudinitdir."""
"""
WSL datasource is found on applicable userdata files in cloudinitdir.
"""
data = copy.deepcopy(VALID_CFG["WSL-supported"])
cloudinitdir = self.tmp_dir()
data["mocks"].append(
Expand Down Expand Up @@ -1159,11 +1184,8 @@ def test_found_via_userdata(self):
os.path.join(cloudinitdir, "default.user-data"),
]

# Ensures all applicable user data files exist.
for filename in userdata_files:
Path(filename).touch()

for filename in userdata_files:
self._check_via_dict(
data, RC_FOUND, dslist=[data.get("ds"), DS_NONE]
)
Expand Down Expand Up @@ -2236,4 +2258,29 @@ def _print_run_output(rc, out, err, cfg, files):
"etc/os-release": MOCK_WSL_INSTANCE_DATA["os_release"],
},
},
"WSL-supported-debian": {
"ds": "WSL",
"mocks": [
MOCK_VIRT_IS_WSL,
MOCK_UNAME_IS_WSL,
{
"name": "WSL_instance_name",
"ret": 0,
"RET": MOCK_WSL_INSTANCE_DATA["name"],
},
],
"files": {
"proc/mounts": (
"/dev/sdd / ext4 rw,errors=remount-ro,data=ordered 0 0\n"
"cgroup2 /sys/fs/cgroup cgroup2 rw,nosuid,nodev,noexec0 0\n"
"C:\\134 /mnt/c 9p rw,dirsync,aname=drvfs;path=C:\\;uid=0;"
"gid=0;symlinkroot=/mnt/...\n"
"snapfuse /snap/core22/1033 fuse.snapfuse ro,nodev,user_id=0,"
"group_id=0,allow_other 0 0"
),
"etc/os-release": MOCK_WSL_INSTANCE_DATA[
"os_release_no_version_id"
],
},
},
}
2 changes: 1 addition & 1 deletion tools/ds-identify
Original file line number Diff line number Diff line change
Expand Up @@ -1655,7 +1655,7 @@ dscheck_WSL() {
instance_name="${_RET}"
# shellcheck source=/dev/null
. "${PATH_ROOT}/etc/os-release"
for userdatafile in "${instance_name}.user-data" "${ID:-linux}-${VERSION_ID:-}" "${ID:-linux}-all.user-data" "default.user-data"; do
for userdatafile in "${instance_name}.user-data" "${ID:-linux}-${VERSION_ID:-${VERSION_CODENAME}}".user-data "${ID:-linux}-all.user-data" "default.user-data"; do
candidate="$cloudinitdir/$userdatafile"
if [ -f "$candidate" ]; then
debug 1 "Found applicable user data file for this instance at: $candidate"
Expand Down

0 comments on commit 3e5c785

Please sign in to comment.