e8eadb46c609fdc71a6a91d9eb05eb167b3ed1dc
OSV states Debian ranges in *source* package versions. A source package that ships several binaries gives each its own upstream version, and the two are unrelated numbers: `libldb2` is `2:2.11.0+samba4.22.11+dfsg-0+deb13u1` while its source, samba, is `2:4.22.11+dfsg-…`. A consumer that resolves the coordinate on `source_package` — which is what this driver's `source:Package` is for — and then compares `version` is comparing ldb's version against samba's range. dpkg reads `2.11.0` as older than the `2:4.17.4+dfsg-1` that fixed CVE-2022-44640, so a Debian 13 host running samba 4.22.11, five releases past the fix, was reported vulnerable on four packages at once. This driver cannot fix that comparison. It is the only place that can supply the number to make it with. Empty when dpkg considers it equal to `Version`, and empty on a dpkg that does not know the field, so it falls back to `Version` — which is the previous behaviour and correct everywhere except the shape above. `maxsplit` goes from 4 to 5 with the extra field. Summary stays last, so it keeps whatever it contains. **The fixture was carrying four fields against a format string asking for five.** `source_package` had been silently receiving the description, and no assertion looked at it. It now carries what dpkg-query actually returns, including a package whose source version is a different number from its own. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
napalm-linux
NAPALM driver for generic Linux systems — Debian, Ubuntu, RHEL, Rocky, Alpine, Arch and any other distribution reachable via SSH.
Connects over SSH using Netmiko (linux device type) and
automatically detects the installed package manager (apt, dnf, yum, apk, pacman).
Requirements
| Dependency | Minimum version |
|---|---|
| Python | 3.9 |
| NAPALM | 4.0 |
| Netmiko | 4.0 |
| napalm-device-types | 0.2.0 |
Installation
pip install napalm napalm-linux
Or from source:
git clone https://github.com/chrismanivong/napalm-linux
pip install -e napalm-linux/
When working in the NetOrk monorepo, install both packages as editable:
pip install -e vendor/napalm-device-types/ -e vendor/napalm-linux/
Quick start
from napalm import get_network_driver
Driver = get_network_driver("linux")
with Driver(
"10.0.0.5",
"admin",
"s3cr3t",
optional_args={
# "port": 22,
# "pkg_manager": "apt", # force package manager; auto-detected by default
# "secret": "sudo-pass", # password for sudo / enable (defaults to login password)
# "debugging": True, # enable verbose logging
},
) as dev:
facts = dev.get_facts()
print(facts)
# OS-specific methods (from napalm-device-types OSDriver)
packages = dev.get_packages()
updates = dev.get_pending_updates()
services = dev.get_services()
users = dev.get_users()
procs = dev.get_processes()
jobs = dev.get_cron_jobs()
# Upgrade specific packages
result = dev.apply_updates(["openssh-server", "curl"])
print(result) # {"success": True, "output": "..."}
# Upgrade everything with pending updates
result = dev.apply_updates([])
Supported NAPALM methods
Standard NAPALM
| Method | Supported | Notes |
|---|---|---|
open() / close() |
✅ | SSH via netmiko linux |
is_alive() |
✅ | |
get_facts() |
✅ | DMI / /proc/uptime / ip link |
get_interfaces() |
✅ | ip link show |
get_interfaces_ip() |
✅ | ip addr show |
get_arp_table() |
✅ | ip neigh show |
get_config() |
✅ | Returns ip addr + ip route output |
ping() |
✅ | Executes ping on the remote host |
load_merge_candidate() |
❌ | Not applicable for generic Linux |
load_replace_candidate() |
❌ | Not applicable for generic Linux |
compare_config() |
❌ | Not applicable for generic Linux |
commit_config() |
❌ | Not applicable for generic Linux |
discard_config() |
❌ | Not applicable for generic Linux |
rollback() |
❌ | Not applicable for generic Linux |
OSDriver extensions (napalm-device-types)
| Method | Supported | Package managers |
|---|---|---|
get_packages() |
✅ | apt, dnf, yum, apk, pacman |
get_pending_updates() |
✅ | apt, dnf, yum, apk, pacman |
apply_updates(packages) |
✅ | apt, dnf, yum, apk, pacman |
get_services() |
✅ | systemd (fallback: SysV service) |
get_users() |
✅ | /etc/passwd + /etc/group |
get_processes() |
✅ | ps axo |
get_cron_jobs() |
✅ | user crontabs + /etc/cron.d/ |
Package manager auto-detection
The driver probes for each binary in order via command -v:
apt → dnf → yum → apk → pacman
Force a specific package manager:
optional_args={"pkg_manager": "dnf"}
SSH user permissions
The SSH user needs read access to:
| Data | Required permission |
|---|---|
/etc/passwd, /etc/group |
world-readable (default) |
/proc/uptime, /sys/class/dmi/… |
world-readable (default) |
User crontabs (/var/spool/cron/…) |
root or sudo required |
systemctl is-enabled <unit> |
unprivileged on most distros |
apt list --upgradable |
may require apt-get update (root) |
dnf check-update / yum check-update |
unprivileged, but slower without cache |
For full functionality it is recommended to run as root or grant passwordless sudo for
the above commands.
Tested distributions
| Distribution | Version | Package manager | Tested |
|---|---|---|---|
| Debian | 12 (Bookworm) | apt | ✅ |
| Ubuntu | 22.04 LTS | apt | ✅ |
| Rocky Linux | 9 | dnf | planned |
| Alpine Linux | 3.19 | apk | planned |
| Arch Linux | rolling | pacman | planned |
Contributions for additional distributions and versions are welcome.
Development
# Create venv
python -m venv .venv
source .venv/bin/activate
# Install in editable mode with dev dependencies
pip install -e ../napalm-device-types/ -e ".[dev]"
# Run tests
pytest tests/ -v
# Lint / format
ruff check napalm_linux/
ruff format napalm_linux/
License
Apache 2.0
Languages
Python
100%