fix: raise when an update reader cannot read, and report host status
CI / test (3.10) (push) Successful in 26s
CI / test (3.11) (push) Successful in 25s
CI / test (3.12) (push) Successful in 26s
CI / test (3.10) (pull_request) Successful in 25s
CI / test (3.11) (pull_request) Successful in 24s
CI / test (3.12) (pull_request) Successful in 26s
CI / test (3.10) (push) Successful in 26s
CI / test (3.11) (push) Successful in 25s
CI / test (3.12) (push) Successful in 26s
CI / test (3.10) (pull_request) Successful in 25s
CI / test (3.11) (pull_request) Successful in 24s
CI / test (3.12) (pull_request) Successful in 26s
netOrk reads an empty update list as "no updates" and closes every patch clock on the host. A refused sudo, a failing pkg, syspatch or freebsd-update, or a pkg database pkg cannot read used to come back as that empty list. Each of these now raises. Only pkg's "is not installed" still means no packages. BsdDriver takes on napalm-device-types' HostStatusMixin. On FreeBSD it reports a host whose installed kernel differs from the running one as needing a reboot (device-types 4.1). OpenBSD stays unknown. Closes #4
This commit is contained in:
+24
-8
@@ -53,8 +53,18 @@ class FreeBSDDriver(BsdDriver):
|
||||
return parse.service_status(output)
|
||||
|
||||
def _has_pkg(self) -> bool:
|
||||
"""pkg is bootstrapped; a hand-installed classic system may have only the stub."""
|
||||
return self.run_command("pkg -N").exit_code == 0
|
||||
"""pkg is bootstrapped; a hand-installed classic system may have only the stub.
|
||||
|
||||
Only the stub's "not installed" means no pkg; any other failure (a
|
||||
database pkg cannot read) raises rather than read as "no packages".
|
||||
"""
|
||||
result = self.run_command("pkg -N")
|
||||
if result.exit_code == 0:
|
||||
return True
|
||||
message = (result.stderr or result.stdout).strip()
|
||||
if "is not installed" in message:
|
||||
return False
|
||||
raise RuntimeError(f"pkg -N: {message or f'exit {result.exit_code}'}")
|
||||
|
||||
def get_packages(self) -> list[dict]:
|
||||
return parse.pkg_query(self._out(self.PKG_QUERY)) if self._has_pkg() else []
|
||||
@@ -69,10 +79,13 @@ class FreeBSDDriver(BsdDriver):
|
||||
"""
|
||||
updates: list[dict] = []
|
||||
if self._has_pkg():
|
||||
updates = parse.pkg_upgrades(self._out("pkg upgrade -n", privileged=True, timeout=300))
|
||||
upgrade = self._read("pkg upgrade -n", privileged=True, timeout=300)
|
||||
updates = parse.pkg_upgrades(upgrade.stdout)
|
||||
audit = self.run_command("pkg audit -Fq", privileged=True, timeout=120)
|
||||
known = audit.exit_code in (0, 1) # 1: vulnerable packages found
|
||||
vulnerable = parse.pkg_audit(audit.stdout) if known else set()
|
||||
vulnerable = parse.pkg_audit(audit.stdout)
|
||||
# 1 is "vulnerable packages found" and any error alike; only a list
|
||||
# of packages makes it a verdict.
|
||||
known = audit.exit_code == 0 or (audit.exit_code == 1 and bool(vulnerable))
|
||||
for update in updates:
|
||||
update["security"] = (update["name"] in vulnerable) if known else None
|
||||
if "FreeBSD-base" in self._out("pkg repos -l").split():
|
||||
@@ -86,10 +99,13 @@ class FreeBSDDriver(BsdDriver):
|
||||
2 when there are none; it does not fetch, which ``freebsd-update cron``
|
||||
does daily where it is enabled.
|
||||
"""
|
||||
ready = self.run_command(
|
||||
"freebsd-update --not-running-from-cron updatesready", privileged=True, timeout=60
|
||||
ready = self._read(
|
||||
"freebsd-update --not-running-from-cron updatesready",
|
||||
privileged=True,
|
||||
timeout=60,
|
||||
ok=(0, 2),
|
||||
)
|
||||
if ready.exit_code != 0:
|
||||
if ready.exit_code == 2:
|
||||
return []
|
||||
return [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user