Skip to content
48 changes: 39 additions & 9 deletions lisa/microsoft/testsuites/ltp/ltp.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,15 +385,30 @@ def _install_dependencies(self) -> None:
]
)
elif isinstance(self.node.os, CBLMariner):
self.node.os.install_packages(
[
"kernel-headers",
"binutils",
"diffutils",
"glibc-devel",
"zlib-devel",
]
)
if self.node.os.information.version >= "4.0.0":
self.node.os.install_packages(
[
"libaio-devel",
"libattr",
"libcap-devel",
"pkgconf",
"kernel-headers",
"glibc-devel",
"binutils",
"diffutils",
"zlib-devel",
]
)
else:
self.node.os.install_packages(
[
"kernel-headers",
"binutils",
"diffutils",
"glibc-devel",
"zlib-devel",
]
)
else:
raise LisaException(f"{self.node.os} is not supported")

Expand Down Expand Up @@ -463,6 +478,21 @@ def _build_from_source(self) -> None:
else:
cur_ltp_path = self._clone_source(self.LTP_GIT_URL, top_src_dir)

# Workaround for AzL 4.0: create pkg-config cross-compilation symlink
# TODO: Fix this in Azl 4.0 Specs, DO NOT MERGE this workaround.
if (
isinstance(self.node.os, CBLMariner)
and self.node.os.information.version >= "4.0.0"
):
self.node.execute(
"ln -sf /usr/bin/pkgconf"
" /usr/bin/$(rpm --eval"
" '%{_target_cpu}-%{_vendor}-%{_target_os}%{?_gnu}')"
"-pkg-config",
sudo=True,
shell=True,
)

# better to install ltp in /opt/ltp since this path is used by some
# tests, e.g, block_dev test
make = self.node.tools[Make]
Expand Down
33 changes: 32 additions & 1 deletion lisa/microsoft/testsuites/xfstests/xfstests.py
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,18 @@ class Xfstests(Tool):
"psmisc",
"perl-CPAN",
]
# CBL Mariner 4.0 Dependencies
mariner_4_dep = [
"libattr-devel",
"binutils",
"kernel-headers",
"perl-CPAN",
"diffutils",
"btrfs-progs-devel",
"zlib-ng-compat-devel",
"libblkid-devel",
"libmount-devel",
]
# Regular expression for parsing xfstests output
# Example:
# Passed all 35 tests
Expand Down Expand Up @@ -941,7 +953,11 @@ def _install_dep(self) -> None:
elif isinstance(self.node.os, Suse):
package_list.extend(self.suse_dep)
elif isinstance(self.node.os, CBLMariner):
package_list.extend(self.mariner_dep)
if self.node.os.information.version >= "4.0.0":
package_list.extend(self.fedora_dep)
package_list.extend(self.mariner_4_dep)
else:
package_list.extend(self.mariner_dep)
else:
raise LisaException(
f"Current distro {self.node.os.name} doesn't support xfstests."
Expand Down Expand Up @@ -1067,6 +1083,21 @@ def _install(
file=str(code_path / "src" / "Makefile"),
)

# Temporary Workaround to test xfs in Azurelinux 4.0
# DO NOT MERGE
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be a bug (missing symlink in pkg-config package) in 4.0 Alpha image, added a workaround to test xfs. will remove this once upstream gets fixed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only issue in Alpha1 image.
Fix is present in azurelinux-stage1-compact package. installing that package creates this symlink. in stage2 image this change would not be required.

if (
isinstance(self.node.os, CBLMariner)
and self.node.os.information.version >= "4.0.0"
):
self.node.execute(
"ln -sf /usr/bin/pkgconf"
" /usr/bin/$(rpm --eval"
" '%{_target_cpu}-%{_vendor}-%{_target_os}%{?_gnu}')"
"-pkg-config",
sudo=True,
shell=True,
)

# Regenerate configure script to fix PKG_CHECK_MODULES macro expansion issue.
# The pre-generated configure script in xfstests-dev git repo may have
# unexpanded PKG_CHECK_MODULES macros if it was generated without pkg-config.
Expand Down
10 changes: 8 additions & 2 deletions lisa/operating_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -2068,7 +2068,7 @@ def name_pattern(cls) -> Pattern[str]:

def __init__(self, node: Any) -> None:
super().__init__(node)
self._dnf_tool_name: str
self._dnf_tool_name: str = "dnf"
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting _dnf_tool_name default to "dnf" can cause CBLMariner to run dnf before _initialize_package_installation() has had a chance to detect whether only tdnf is available. Since RPMDistro._install_packages/_uninstall_packages call _dnf_tool() without first calling _initialize_package_installation(), consider ensuring tool selection is initialized before any package operation (e.g., lazy-init inside _dnf_tool() or overriding _install_packages/_uninstall_packages to gate on _first_time_installation).

Copilot uses AI. Check for mistakes.

def _initialize_package_installation(self) -> None:
self.set_kill_user_processes()
Expand Down Expand Up @@ -2136,9 +2136,15 @@ def _create_local_repo(self, source_tarball: Path) -> None:
# the SSH session is reset
def set_kill_user_processes(self) -> None:
sed = self._node.tools[Sed]
# Azure Linux 4.0 moved logind.conf to /usr/lib/systemd/
logind_conf = "/etc/systemd/logind.conf"
if not self._node.shell.exists(
self._node.get_pure_path(logind_conf)
):
logind_conf = "/usr/lib/systemd/logind.conf"
Comment on lines +2141 to +2144
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fallback to /usr/lib/systemd/logind.conf is not validated for existence. If neither /etc/systemd/logind.conf nor /usr/lib/systemd/logind.conf exists, sed -i will fail and this method will raise unexpectedly. Consider checking the fallback path too and either creating /etc/systemd/logind.conf (preferred) or raising a clear error/skip when systemd config is not present.

Suggested change
if not self._node.shell.exists(
self._node.get_pure_path(logind_conf)
):
logind_conf = "/usr/lib/systemd/logind.conf"
shell = self._node.shell
primary_path = self._node.get_pure_path(logind_conf)
if not shell.exists(primary_path):
fallback_logind_conf = "/usr/lib/systemd/logind.conf"
fallback_path = self._node.get_pure_path(fallback_logind_conf)
if shell.exists(fallback_path):
logind_conf = fallback_logind_conf
else:
# Neither primary nor fallback exist; create the primary config file
self._log.debug(
"Neither /etc/systemd/logind.conf nor /usr/lib/systemd/logind.conf "
"exists. Creating /etc/systemd/logind.conf."
)
self._node.execute(
"mkdir -p /etc/systemd && touch /etc/systemd/logind.conf",
sudo=True,
shell=True,
expected_exit_code=0,
expected_exit_code_failure_message=(
"Failed to create /etc/systemd/logind.conf"
),
)

Copilot uses AI. Check for mistakes.
sed.append(
text="KillUserProcesses=no",
file="/etc/systemd/logind.conf",
file=logind_conf,
Comment on lines +2139 to +2147
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Editing the vendor config at /usr/lib/systemd/logind.conf is brittle (package updates may overwrite it) and may not be the correct override location for systemd. Prefer writing the setting to /etc/systemd/logind.conf (create it if missing) or a drop-in under /etc/systemd/logind.conf.d/, and keep /usr/lib untouched.

Copilot uses AI. Check for mistakes.
sudo=True,
)
self._node.tools[Service].restart_service("systemd-logind")
Comment on lines 2145 to 2150
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set_kill_user_processes() always uses sed.append(...) and restarts systemd-logind, so repeated calls will keep appending duplicate KillUserProcesses=no lines and repeatedly restart the service (this is also currently invoked from _initialize_package_installation). Making the change idempotent (e.g., replace existing KillUserProcesses= or check if the setting already exists before editing/restarting) would avoid config bloat and unnecessary service churn.

Copilot uses AI. Check for mistakes.
Expand Down
4 changes: 2 additions & 2 deletions lisa/tools/fips.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ def create(cls, node: "Node", *args: Any, **kwargs: Any) -> Tool:
if isinstance(node.os, CBLMariner):
if node.os.information.release == "2.0":
return AzlV2Fips(node, args, kwargs)
if node.os.information.release == "3.0":
if node.os.information.release in ("3.0", "4.0"):
return AzlV3Fips(node, args, kwargs)

raise UnsupportedDistroException(
os=node.os, message="FIPS tool only supported on CBLMariner 2.0 and 3.0."
os=node.os, message="FIPS tool only supported on CBLMariner 2.0, 3.0 and 4.0."
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The UnsupportedDistroException(...) call is now long enough to violate the repo's flake8 max-line-length = 88 setting, which will fail linting. Please wrap the arguments across multiple lines (similar to grub_config.py) so each line stays within 88 chars.

Suggested change
os=node.os, message="FIPS tool only supported on CBLMariner 2.0, 3.0 and 4.0."
os=node.os,
message="FIPS tool only supported on CBLMariner 2.0, 3.0 and 4.0.",

Copilot uses AI. Check for mistakes.
)

def __init__(self, node: "Node", *args: Any, **kwargs: Any) -> None:
Expand Down
4 changes: 2 additions & 2 deletions lisa/tools/grub_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def create(cls, node: "Node", *args: Any, **kwargs: Any) -> Tool:
if isinstance(node.os, CBLMariner):
if node.os.information.release == "2.0":
return GrubConfigAzl2(node, args, kwargs)
if node.os.information.release == "3.0":
if node.os.information.release in ("3.0", "4.0"):
return GrubConfigAzl3(node, args, kwargs)
elif isinstance(node.os, Debian):
return GrubConfigDebian(node, args, kwargs)
Expand All @@ -31,7 +31,7 @@ def create(cls, node: "Node", *args: Any, **kwargs: Any) -> Tool:

raise UnsupportedDistroException(
os=node.os,
message="Grub tool only supported on CBLMariner 2.0/3.0, "
message="Grub tool only supported on CBLMariner 2.0, 3.0 and 4.0, "
"Debian-based distributions, and RHEL-based distributions.",
)

Expand Down
Loading