On ARM boards (Raspberry Pi, ODROID, etc.) /sys/class/dmi/id/ does not
exist. _collect_platform_info() now falls back to:
- /sys/firmware/devicetree/base/model (preferred)
- /proc/cpuinfo Model: / Serial: (fallback)
Three bugs fixed in the process:
1. systemd-detect-virt exits 1 on bare metal, so the old
"|| echo none" pattern produced d="none\nnone" (two lines),
shifting all subsequent fields by one. Fixed with ${d:-none}.
2. _send() calls .strip() on output, silently eating the five leading
blank lines that represent empty DMI fields on ARM. Fixed by
prefixing the printf output with a DMIBEGIN sentinel so the parser
can locate field 0 regardless of leading whitespace.
3. Vendor was always empty for ARM, falling back to the generic "Linux"
constant. Added _ARM_VENDOR_PREFIXES lookup table and
_arm_vendor_from_model() to derive the canonical vendor name from
the model string (e.g. "Raspberry Pi Foundation" for any RPi board).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
_collect_platform_info() reads sys_vendor, product_name/version,
product_serial, product_uuid and systemd-detect-virt in one SSH
round-trip. Result:
- Bare-metal: vendor from DMI sys_vendor (e.g. "Dell Inc."), model
from product_name (product_version preferred when it looks like a
marketing name), serial from product_serial.
- VM (KVM/VMware/Hyper-V/Xen/VirtualBox): vendor is the hypervisor
name, model is "Virtual Machine", serial prefers product_serial and
falls back to product_uuid (VM UUID).
- Container (Docker/LXC/Podman): vendor is the container runtime,
model is "Container".
- Junk DMI values ("To Be Filled By O.E.M." etc.) are filtered.
- Falls back to VENDOR = "Linux" when DMI is completely unavailable.
13 new unit tests covering all scenarios including SSH failure and
detect-virt unavailability.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- get_device_warnings(): checks /etc/apt/apt.conf.d/00proxy on apt systems
(only when apt_proxy_url is set via optional_args from NetOrk settings)
- _action_fix_apt_proxy(): writes the proxy config via sudo, uses base64 to
avoid quoting issues
- run_device_action(): routes 'fix_apt_proxy' to the new method
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- get_lldp_neighbors() via lldpctl JSON output
- install_package() / uninstall_package() via apt/dnf/apk/pacman
- search_packages() across package managers
- get_vpn_tunnels() for WireGuard via wg show
- get_health_metrics() delegated to OSDriver base class (UCD-MIB)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Initial commit mit bestehendem Code inkl. neuem get_route_to():
- Parsed ip -4 route show und ip -6 route show
- Protokoll-Map: kernel/dhcp/ra/boot→connected, static→static, ospf→ospf, bgp→bgp
- family-Feld aus Netzadresse oder Next-Hop (: = ipv6)
- default/default6 → 0.0.0.0/0 / ::/0; Host-Routen ohne Prefix bekommen /32
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>