Files
napalm-linux/README.md
Christian Manivong 84717ff53b feat: start, stop, restart, enable and disable services, and list them in one round trip
napalm-device-types' SystemdServicesMixin (2.2.0) now provides get_services()
and manage_service(); this driver supplies only the transport (#7):

- _run_service_command(): unprivileged reads and root logins run as they
  are -- the user is asked once per session with "id -u", so a root login on a
  box without sudo is not prefixed with one. With a sudo password the command
  goes through _sudo(); without one through "sudo -n", which fails at once
  instead of hanging the session on a password prompt until the read timeout.
- get_services(): one round trip instead of an is-enabled and a show per unit
  (6.0 s -> 0.8 s on a 184-unit Ubuntu host). A host without systemd still
  falls back to "service --status-all".
- manage_service(): when sudo wants a password netOrk does not have, the
  failure says how to fix it -- the same hint the apt and SNMP actions give,
  now one constant (_SUDO_PASSWORD_HINT) instead of two copies.

OpenMediaVault and QNAP inherit this driver. OMV gets service control with
it; QNAP opts out (napalm-qnap-qts), since QTS has no systemd.

README: the sudo option is sudo_password, not secret; manage_service and the
systemctl permissions are listed.

Closes #7
2026-10-05 13:12:13 +02:00

188 lines
5.7 KiB
Markdown

# 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](https://github.com/ktbyers/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
```bash
pip install napalm napalm-linux
```
Or from source:
```bash
git clone https://github.com/chrismanivong/napalm-linux
pip install -e napalm-linux/
```
When working in the NetOrk monorepo, install both packages as editable:
```bash
pip install -e vendor/napalm-device-types/ -e vendor/napalm-linux/
```
## Quick start
```python
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
# "sudo_password": "sudo-pass", # for commands that need root; without it,
# # `sudo -n` (passwordless sudo) is tried
# "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([])
# Restart a service (start, stop, restart, enable, disable)
result = dev.manage_service("cron", "restart")
print(result) # {"success": True, "output": ""}
```
## 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, one round trip (fallback: SysV `service`) |
| `manage_service(name, action)` | ✅ | systemd: start, stop, restart, enable, disable |
| `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:
```python
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 list-unit-files`, `systemctl show` | unprivileged |
| `systemctl start/stop/restart/enable/disable` | `root`, or `sudo` (with `sudo_password`, or passwordless) |
| `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.
`get_services()` and `manage_service()` come from napalm-device-types'
`SystemdServicesMixin`; this driver supplies only the transport. An action runs as
`timeout 45 systemctl --no-ask-password <action> -- <unit>.service`, so a unit that hangs
on its way up or down cannot hold the session, and only the exit status decides whether it
succeeded. Without a sudo password it uses `sudo -n`, which fails at once instead of
waiting for a password prompt.
On OpenMediaVault (napalm-openmediavault inherits this driver), enabling or disabling a
unit that OMV manages itself — Samba, NFS, SSH — may be reverted the next time OMV applies
its configuration.
## 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
```bash
# 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