For netOrk MVP 5 (patch management). It adds shared parsers and a host-status reader: where a pending update comes from, whether it is a security update, whether the host needs a reboot, and whether it patches itself. The commit message has the details.
It also adds the contract rule that a reader raises when it cannot read, and never returns [] for "don't know". netOrk keeps "pending since" per package, so a false empty list would reset those clocks.
no reboot (two kernel flavours installed, the running one is the newest)
Debian 13 / OMV
2, stable-backports
reboot required, patches itself
Proxmox VE 9
15, stable (Ceph)
no reboot
Before the pipe, the OMV and Raspberry Pi reads broke on terminal codes. The fix is the | cat in both commands; strip_terminal_codes keeps any remaining codes out of the parsers.
Tests
$ PYTHONPATH=. pytest -q tests
312 passed
$ ruff check --isolated --line-length 100 <new and touched files>
All checks passed!
$ mypy napalm_device_types # only the existing base.py / _ucd_metrics.py findings remain
For netOrk MVP 5 (patch management). It adds shared parsers and a host-status reader: where a pending update comes from, whether it is a security update, whether the host needs a reboot, and whether it patches itself. The commit message has the details.
It also adds the contract rule that **a reader raises when it cannot read, and never returns `[]` for "don't know"**. netOrk keeps "pending since" per package, so a false empty list would reset those clocks.
## Checked against real hosts (netOrk test server)
| Host | Updates read | Host status |
|---|---|---|
| Ubuntu 24.04 (z2m-garden) | 1, `origin=noble`, not security | reboot required (`/var/run/reboot-required`), patches itself |
| Ubuntu 24.04 (vault-01) | 1 | no reboot, patches itself |
| Raspberry Pi OS | 0 | no reboot (two kernel flavours installed, the running one is the newest) |
| Debian 13 / OMV | 2, `stable-backports` | reboot required, patches itself |
| Proxmox VE 9 | 15, `stable` (Ceph) | no reboot |
Before the pipe, the OMV and Raspberry Pi reads broke on terminal codes. The fix is the `| cat` in both commands; `strip_terminal_codes` keeps any remaining codes out of the parsers.
## Tests
```
$ PYTHONPATH=. pytest -q tests
312 passed
$ ruff check --isolated --line-length 100 <new and touched files>
All checks passed!
$ mypy napalm_device_types # only the existing base.py / _ucd_metrics.py findings remain
```
netOrk MVP 5 measures "security updates applied within N days" and starts
patch runs inside agreed windows. That needs three things every Linux driver
reads the same way, so they live here once:
- UpdateDict gains optional `origin` and `security` (None = unknown).
- package_updates: APT_UPGRADABLE_COMMAND and parse_apt_upgradable(). apt's
suites are the origin; a "-security" suite makes it a security update;
several architectures of one package are one entry. The command runs
through a pipe with its exit status printed inside the group: through a
pseudo-terminal apt drew progress and keypad codes, one of which (ESC >)
a screen-scraping read took for a prompt and stopped at. The parser raises
ValueError when apt failed or its status never arrived.
DNF_SECURITY_COMMAND / parse_dnf_security() / nevra_name() for dnf/yum.
- host_status: HOST_STATUS_COMMAND, parse_host_status(), HostStatusMixin
(template form, hook _run_host_status_command). reboot_required from
/var/run/reboot-required, needs-restarting -r, or a newer kernel of the
running flavour (a Raspberry Pi carries two flavours side by side);
auto_updates from APT::Periodic::Unattended-Upgrade with its timer, or
dnf-automatic. HostStatusDict in models.py.
- terminal.strip_terminal_codes(): CSI, OSC and two-character escapes, now
also used by the systemd parser.
- UpdateMixin: contract refresh_available_updates(); get_available_updates'
docstring now states the rule that a reader raises when it cannot read and
never returns [] for "don't know".
Fixtures are real output from Ubuntu 24.04, Debian 13 / OMV, Raspberry Pi OS
and Proxmox VE 9. Version 2.3.0.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
For netOrk MVP 5 (patch management). It adds shared parsers and a host-status reader: where a pending update comes from, whether it is a security update, whether the host needs a reboot, and whether it patches itself. The commit message has the details.
It also adds the contract rule that a reader raises when it cannot read, and never returns
[]for "don't know". netOrk keeps "pending since" per package, so a false empty list would reset those clocks.Checked against real hosts (netOrk test server)
origin=noble, not security/var/run/reboot-required), patches itselfstable-backportsstable(Ceph)Before the pipe, the OMV and Raspberry Pi reads broke on terminal codes. The fix is the
| catin both commands;strip_terminal_codeskeeps any remaining codes out of the parsers.Tests