feat: ServicePackagesMixin, which packages a systemd service is (NetOrk/netork#1236) #50

Merged
christianmanivong merged 2 commits from feat/service-packages-1236 into main 2026-10-19 16:56:16 +00:00
Owner

Summary

get_service_packages() returns, per systemd service, the installed packages it is made of: the package shipping its unit file and the one shipping the binary its ExecStart runs (nginx-common + nginx-core). netOrk needs it so that a vulnerability decision about one system service (the postgresql unit on db-01) reaches the host's findings on that unit's packages (NetOrk/netork#1236, phase 3).

Priority: P3

Changes

  • napalm_device_types/service_packages.py: SERVICE_PACKAGES_COMMAND (POSIX sh, read-only, no privileges), parse_service_packages() and ServicePackagesMixin in the template form of KernelFactsMixin: a driver supplies _run_service_packages_command.
  • The command prints systemctl show -p Id -p FragmentPath -p ExecStart for every loaded service unit, then asks the package manager about every path at once: one dpkg -S for all paths (each also across the /usr merge, since dpkg knows a file by the path its package shipped), or rpm -qf per path. One dpkg -S per path took minutes on an ordinary host; the batched call takes well under a second here (201 units).
  • Only the unit's own packages, never the libraries its binary links against: those are every service's at once.
  • The report is framed; one cut short raises ValueError, so a list cut short never reads as services that own nothing. A unit no package owns maps to [].
  • Exported from the package root; README paragraph next to KernelFactsMixin; version 4.20.0.

Related Issue

NetOrk/netork#1236 (phase 3). Consumers: NAPALM/napalm-linux and NAPALM/napalm-proxmox PRs on branch feat/service-packages-1236.

Testing

tests/test_service_packages.py (13 tests): dpkg and rpm answers, the /usr merge, architectures and several owners, diversions and rpm's "not owned" line, units owning nothing, noise around the frame, a report cut short, the command being read-only and frame-free, the mixin handing its command to the driver, and the command run and parsed on this host. Whole suite: 761 passed.

## Summary `get_service_packages()` returns, per systemd service, the installed packages it is made of: the package shipping its unit file and the one shipping the binary its `ExecStart` runs (`nginx-common` + `nginx-core`). netOrk needs it so that a vulnerability decision about one system service (the postgresql unit on db-01) reaches the host's findings on that unit's packages (NetOrk/netork#1236, phase 3). Priority: P3 ## Changes - `napalm_device_types/service_packages.py`: `SERVICE_PACKAGES_COMMAND` (POSIX sh, read-only, no privileges), `parse_service_packages()` and `ServicePackagesMixin` in the template form of `KernelFactsMixin`: a driver supplies `_run_service_packages_command`. - The command prints `systemctl show -p Id -p FragmentPath -p ExecStart` for every loaded service unit, then asks the package manager about every path at once: one `dpkg -S` for all paths (each also across the `/usr` merge, since dpkg knows a file by the path its package shipped), or `rpm -qf` per path. One `dpkg -S` per path took minutes on an ordinary host; the batched call takes well under a second here (201 units). - Only the unit's own packages, never the libraries its binary links against: those are every service's at once. - The report is framed; one cut short raises `ValueError`, so a list cut short never reads as services that own nothing. A unit no package owns maps to `[]`. - Exported from the package root; README paragraph next to `KernelFactsMixin`; version 4.20.0. ## Related Issue NetOrk/netork#1236 (phase 3). Consumers: NAPALM/napalm-linux and NAPALM/napalm-proxmox PRs on branch `feat/service-packages-1236`. ## Testing `tests/test_service_packages.py` (13 tests): dpkg and rpm answers, the `/usr` merge, architectures and several owners, diversions and rpm's "not owned" line, units owning nothing, noise around the frame, a report cut short, the command being read-only and frame-free, the mixin handing its command to the driver, and the command run and parsed on this host. Whole suite: 761 passed.
christianmanivong added 1 commit 2026-10-19 16:03:23 +00:00
feat: ServicePackagesMixin, which packages a systemd service is (NetOrk/netork#1236)
CI / test (3.10) (push) Failing after 17s
CI / test (3.11) (push) Failing after 14s
CI / test (3.12) (push) Failing after 15s
CI / test (3.13) (push) Failing after 16s
CI / test (3.10) (pull_request) Failing after 17s
CI / test (3.11) (pull_request) Failing after 15s
CI / test (3.12) (pull_request) Failing after 20s
CI / test (3.13) (pull_request) Failing after 26s
cce26eff44
get_service_packages() returns, per systemd service, the installed packages
it is made of: the one shipping its unit file and the one shipping the
binary its ExecStart runs -- not the libraries that binary links against.
One read-only command: systemctl show for every loaded service unit, then
one dpkg -S for all paths (each also across the /usr merge), or rpm -qf per
path. The report is framed; one cut short raises. A driver supplies
_run_service_packages_command, as for KernelFactsMixin.

Version 4.20.0.
christianmanivong added 1 commit 2026-10-19 16:50:42 +00:00
fix: annotate the unit path set so mypy accepts service_packages (NetOrk/netork#1236)
CI / test (3.10) (push) Successful in 44s
CI / test (3.11) (push) Successful in 33s
CI / test (3.12) (push) Successful in 32s
CI / test (3.13) (push) Successful in 30s
CI / test (3.10) (pull_request) Successful in 42s
CI / test (3.11) (pull_request) Successful in 43s
CI / test (3.12) (pull_request) Successful in 38s
CI / test (3.13) (pull_request) Successful in 35s
a21e365c4e
christianmanivong merged commit be3958e561 into main 2026-10-19 16:56:16 +00:00
christianmanivong deleted branch feat/service-packages-1236 2026-10-19 16:56:16 +00:00
Sign in to join this conversation.