Skip to content

Commit

Permalink
fix(sources/wsl): no error with empty .cloud-init dir (SC-1862) (#5633)
Browse files Browse the repository at this point in the history
Do not treat the emptiness of .cloud-init/ as an error in the logs
if agent.yaml is present.

Fixes GH-5632
  • Loading branch information
aciba90 authored Aug 27, 2024
1 parent a38d6da commit bbdfe36
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 3 deletions.
3 changes: 2 additions & 1 deletion cloudinit/sources/DataSourceWSL.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,8 @@ def _get_data(self) -> bool:
user_data = ConfigData(self.find_user_data_file(seed_dir))

except (ValueError, IOError) as err:
LOG.error(
log = LOG.info if agent_data else LOG.error
log(
"Unable to load any user-data file in %s: %s",
seed_dir,
str(err),
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 @@ -52,6 +52,8 @@ User data can be supplied in any
cloud-config files or shell scripts. At runtime, the WSL datasource looks for
user data in the following locations inside the Windows host filesystem, in the
order specified below.
The WSL datasource will be enabled if cloud-init discovers at least one of the
applicable config files described below.

First, configurations from Ubuntu Pro/Landscape are checked for in the
following paths:
Expand All @@ -71,8 +73,8 @@ following paths:
used instead of the one provided by the ``agent.yaml``, which is treated as
a default.

Then, if a file from (1) is not found, a user-provided configuration will be
looked for instead in the following order:
Then, if a file from (1) is not found, optional user-provided configuration
will be looked for in the following order:

1. ``%USERPROFILE%\.cloud-init\<InstanceName>.user-data`` holds user data for a
specific instance configuration. The datasource resolves the name attributed
Expand Down
47 changes: 47 additions & 0 deletions tests/unittests/sources/test_wsl.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# This file is part of cloud-init. See LICENSE file for license information.
import logging
import os
import re
from copy import deepcopy
from email.mime.multipart import MIMEMultipart
from pathlib import PurePath
Expand Down Expand Up @@ -460,6 +461,52 @@ def test_get_data_jinja(self, m_lsb_release, paths, tmpdir):
cast(MIMEMultipart, ud), "text/cloud-config"
), "No cloud-config part should exist"

@pytest.mark.parametrize("with_agent_data", [True, False])
@mock.patch("cloudinit.util.lsb_release")
def test_get_data_x(
self, m_lsb_release, with_agent_data, caplog, paths, tmpdir
):
"""
Assert behavior of empty .cloud-config dir with and without agent data
"""
m_lsb_release.return_value = SAMPLE_LINUX_DISTRO
data_path = tmpdir.join(".cloud-init", f"{INSTANCE_NAME}.user-data")
data_path.dirpath().mkdir()

if with_agent_data:
ubuntu_pro_tmp = tmpdir.join(".ubuntupro", ".cloud-init")
os.makedirs(ubuntu_pro_tmp, exist_ok=True)
agent_path = ubuntu_pro_tmp.join("agent.yaml")
agent_path.write(AGENT_SAMPLE)

ds = wsl.DataSourceWSL(
sys_cfg=SAMPLE_CFG,
distro=_get_distro("ubuntu"),
paths=paths,
)

assert ds.get_data() is with_agent_data
if with_agent_data:
assert ds.userdata_raw == AGENT_SAMPLE
else:
assert ds.userdata_raw is None

expected_log_level = logging.INFO if with_agent_data else logging.ERROR
regex = (
"Unable to load any user-data file in /[^:]*/.cloud-init:"
" /.*/.cloud-init directory is empty"
)
messages = [
x.message
for x in caplog.records
if x.levelno == expected_log_level and re.match(regex, x.message)
]
assert (
len(messages) > 0
), "Expected log message matching '{}' with log level '{}'".format(
regex, expected_log_level
)

@mock.patch("cloudinit.util.get_linux_distro")
def test_data_precedence(self, m_get_linux_dist, tmpdir, paths):
"""Validates the precedence of user-data files."""
Expand Down

0 comments on commit bbdfe36

Please sign in to comment.