From 1eb9eb3982f07d7b6247aa92fb4fb7a3fea2e004 Mon Sep 17 00:00:00 2001 From: Srikanth Myakam <374767+SRIKKANTH@users.noreply.github.com> Date: Sun, 2 Aug 2026 10:42:12 -0700 Subject: [PATCH 1/2] core/dns: tolerate unattended-upgrade held-back packages on FDE/Ubuntu Pro images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit verify_dns_name_resolution_after_upgrade failed with a false negative on Ubuntu 22.04 FDE Confidential VM images. `unattended-upgrade -d -v` returns a non-zero exit code whenever it holds back a package (conffile prompt, blacklisted or pinned package such as ubuntu-pro-client / ubuntu-advantage- tools), even though it prints "All upgrades installed" and every applicable upgrade — including the linux-*-azure-fde kernel stack — installed cleanly. _upgrade_system() treated any non-zero exit as fatal and raised LisaException, failing the case even though DNS resolution succeeded at every checkpoint and the VM rebooted into the new kernel. Fix: on a non-zero exit, treat the run as success when stdout contains "All upgrades installed" and no genuine apt/dpkg error marker is present (dpkg: error, E:, Errors were encountered, not fully installed, dpkg sub- process error). Only raise LisaException on a real error. A non-fatal held-back condition is now logged at INFO. Work item: 63384991 --- lisa/microsoft/testsuites/core/dns.py | 36 ++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/lisa/microsoft/testsuites/core/dns.py b/lisa/microsoft/testsuites/core/dns.py index 4ea976861b..be4f56938d 100644 --- a/lisa/microsoft/testsuites/core/dns.py +++ b/lisa/microsoft/testsuites/core/dns.py @@ -40,6 +40,18 @@ class Dns(TestSuite): _fail_to_install_package_pattern = re.compile( r"ModuleNotFoundError: No module named \'apt_inst\'", re.M ) + # unattended-upgrade prints this once all applicable upgrades are applied. + _upgrade_success_pattern = re.compile(r"All upgrades installed", re.M) + # Genuine failures from apt/dpkg. unattended-upgrade returns a non-zero exit + # code when it only holds back packages (conffile prompts, blacklisted or + # pinned packages such as ubuntu-pro-client on FDE/Ubuntu Pro images), which + # is not a real failure; these markers distinguish an actual error. + _upgrade_real_error_pattern = re.compile( + r"^(?:dpkg: error|E: |Errors were encountered)|" + r"not fully installed|" + r"Sub-process /usr/bin/dpkg returned an error", + re.M, + ) def after_case(self, log: Logger, **kwargs: Any) -> None: log.debug("after_case: mark node as dirty to avoid affecting other test cases") @@ -147,8 +159,24 @@ def _upgrade_system(self, node: Node) -> None: timeout=2400, ) if result.exit_code != 0: - # make node as dirty, so the node will be not used in next test case - node.mark_dirty() - raise LisaException( - "fail to run apt update && unattended-upgrade -d -v" + upgrade_succeeded = bool( + self._upgrade_success_pattern.findall(result.stdout) + ) + has_real_error = bool( + self._upgrade_real_error_pattern.findall(result.stdout) ) + if upgrade_succeeded and not has_real_error: + # unattended-upgrade returns a non-zero exit code when it + # holds back packages (conffile prompts, blacklisted or + # pinned packages such as ubuntu-pro-client on FDE/Ubuntu + # Pro images) even though all applicable upgrades installed + # successfully. This is not a failure for this test. + node.log.info( + "unattended-upgrade reported 'All upgrades installed' " + f"with exit code {result.exit_code}; treating held-back " + "packages as a non-fatal condition." + ) + else: + raise LisaException( + "fail to run apt update && unattended-upgrade -d -v" + ) From ea223e7418d12603423344e99b28a1b4caafdff6 Mon Sep 17 00:00:00 2001 From: SrikanthMyakam Date: Mon, 3 Aug 2026 08:56:48 +0530 Subject: [PATCH 2/2] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- lisa/microsoft/testsuites/core/dns.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lisa/microsoft/testsuites/core/dns.py b/lisa/microsoft/testsuites/core/dns.py index be4f56938d..05fc589600 100644 --- a/lisa/microsoft/testsuites/core/dns.py +++ b/lisa/microsoft/testsuites/core/dns.py @@ -159,11 +159,12 @@ def _upgrade_system(self, node: Node) -> None: timeout=2400, ) if result.exit_code != 0: + combined_output = (result.stdout or "") + (result.stderr or "") upgrade_succeeded = bool( - self._upgrade_success_pattern.findall(result.stdout) + self._upgrade_success_pattern.search(combined_output) ) has_real_error = bool( - self._upgrade_real_error_pattern.findall(result.stdout) + self._upgrade_real_error_pattern.search(combined_output) ) if upgrade_succeeded and not has_real_error: # unattended-upgrade returns a non-zero exit code when it