fix: adapt to napalm-device-types 4.7
CI / test (3.10) (push) Successful in 38s
CI / test (3.11) (push) Successful in 37s
CI / test (3.12) (push) Successful in 39s

napalm-device-types 4.7 changed three things this driver depends on:

- parse_dnf_security needs the "__DNF_RC=<status>" line that
  DNF_SECURITY_COMMAND prints and raises ValueError without it or when dnf
  failed. The yum security query had no such line, so listing updates on
  any yum host raised. _YUM_SECURITY_COMMAND now prints the marker the same
  way ("{ ...; echo __DNF_RC=$?; } | cat"). _rpm_security_names checks
  __DNF_RC itself and turns a failed query, or output cut short before the
  marker, into None (security unknown) rather than "no advisories" or an
  exception.
- OSDriver.get_users was renamed to get_os_users, since NAPALM's own
  get_users has another shape. LinuxDriver.get_users is now get_os_users
  with the same return value.
- run_on_transport reads an exec channel to EOF after its exit status
  arrives; the tests' fake channels gain recv/recv_stderr for that.

Require napalm-device-types>=4.7.1 and bump the version to 0.6.0.
This commit is contained in:
christianmanivong committed 2026-10-13 06:25:17 +00:00
1 parent 81b2df9d71
commit 350e3a6d6e
8 files changed
+141 -15

No files matched your search

+19 -3
View File
@@ -125,7 +125,14 @@ _REFRESH = {
"yum": "yum makecache -q 2>&1",
"apk": "apk update -q 2>&1",
}
_YUM_SECURITY_COMMAND = "LC_ALL=C yum updateinfo list security -q 2>/dev/null"
#: yum's counterpart of DNF_SECURITY_COMMAND, in the same shape: parse_dnf_security
#: (napalm-device-types 4.7) needs the ``__DNF_RC=`` line, and behind ``| cat`` it is
#: the only place yum's own exit status survives.
_YUM_SECURITY_COMMAND = (
"{ LC_ALL=C yum updateinfo list security -q 2>/dev/null; echo __DNF_RC=$?; } | cat"
)
#: The exit status ``DNF_SECURITY_COMMAND`` and ``_YUM_SECURITY_COMMAND`` report.
_DNF_RC_RE = re.compile(r"^__DNF_RC=(\d+)\s*$", re.MULTILINE)
#: Restart the host two seconds later, detached from this session: the launcher's
#: exit status comes back before the host goes down, and closing the session
@@ -1512,7 +1519,16 @@ class LinuxDriver(
"""Packages a pending security advisory covers; None when dnf/yum cannot say."""
cmd = DNF_SECURITY_COMMAND if self._pkg_manager == "dnf" else _YUM_SECURITY_COMMAND
output, status = _split_status(self._run_privileged(f"{cmd}; echo {_RC_MARKER}$?", 120))
return parse_dnf_security(output) if status == 0 else None
# Both commands pipe through cat, so the outer status is cat's: dnf/yum's own
# is in __DNF_RC. A failed run prints nothing on stdout and must not read as
# "no advisories"; neither may output cut short before the marker.
rc = _DNF_RC_RE.findall(output)
if status != 0 or not rc or rc[-1] != "0":
return None
try:
return parse_dnf_security(output)
except ValueError:
return None
def refresh_available_updates(self) -> dict[str, Any]:
"""Refresh the package index (apt-get update, dnf makecache, apk update)."""
@@ -1695,7 +1711,7 @@ class LinuxDriver(
# OSDriver – users
# ------------------------------------------------------------------
def get_users(self) -> list[UserDict]:
def get_os_users(self) -> list[UserDict]:
"""Return local user accounts from /etc/passwd plus supplementary groups."""
passwd_out = self._send("getent passwd 2>/dev/null || cat /etc/passwd")
groups_out = self._send("getent group 2>/dev/null || cat /etc/group")