Commit Graph
1553 Commits
Author SHA1 Message Date
Mattias Walström cc54b1d111 yangerd: Fix bugs with containers and boot order in CI 2026-06-17 11:54:25 +02:00
Mattias Walström 9a45ad7d4b yangerd: Add arm 32bit support
Int => int64
2026-06-17 11:54:25 +02:00
Mattias Walström efe3c04abf yangerd: add missing files 2026-06-17 11:54:25 +02:00
Mattias Walström c442119699 yangerd: Fix ntp and lldp status 2026-06-17 11:54:25 +02:00
Mattias Walström e74f3b1bd6 yangerd: Return {} instead of 404 if no match 2026-06-17 11:54:25 +02:00
Mattias Walström 0e1031ea65 statd: Adapt to yanger keys on module:container path
Instead of relying of the runtime xpath, which can be just /system-state
for example, resulting on no yangerd match.
2026-06-17 11:54:25 +02:00
Mattias Walström 4160a98636 yangerd: Add missing files 2026-06-17 11:54:25 +02:00
Mattias Walström 8abe24e32b yangerd: Add support for getting ARP neighbors 2026-06-17 11:54:25 +02:00
Mattias Walström 85cb5d4e90 statd: Remove old code 2026-06-17 11:54:25 +02:00
Mattias Walström 330601a57a yanger: Remove code duplication and fix upgrade
Remove a lot of duplication and move to seperate libs in internal/

Also, instead of polling upgrade status using src/rauc-installation-status,
hook into the dbus monitor.
2026-06-17 11:54:25 +02:00
Mattias Walström a4dca08840 yangerd: Add WiFi implementation 2026-06-17 11:54:25 +02:00
Mattias Walström 417cdf4648 yangerd: Add backoff if ip batch work have crashed 2026-06-17 11:54:25 +02:00
Mattias Walström 3c87338a79 yangerd: Add wireguard support 2026-06-17 11:54:25 +02:00
Mattias Walström de8d074cb9 yangerd: fix stp status 2026-06-17 11:54:25 +02:00
Mattias Walström 4dad023eae yangerd: Send sighup to yangerd on config change
This is to force yangerd to repoll polled things
2026-06-17 11:54:25 +02:00
Mattias Walström 52cea0a356 Fix containers, reactive now. 2026-06-17 11:54:25 +02:00
Mattias Walström 3372966f89 Fix ntp and dns status 2026-06-17 11:54:24 +02:00
Mattias Walström ae3d50a41d FRR does not send delete on OSPF route change
Handle this.
2026-06-17 11:54:24 +02:00
Mattias Walström 02d52f5a12 Fix interface and bridge race conditions 2026-06-17 11:54:24 +02:00
Mattias Walström 0c7293f97a zapi: Fix deletion of routes 2026-06-17 11:54:24 +02:00
Mattias Walström 6e415bbcdb yangerd: Continues 2026-06-17 11:54:24 +02:00
Mattias Walström 299146dd4e Fix routing and ip addresses 2026-06-17 11:54:24 +02:00
Mattias Walström 7956ca05fa update doc 2026-06-17 11:54:24 +02:00
Mattias Walström 6d0d047c30 statd: Include new yangerd backend for operational 2026-06-17 11:54:24 +02:00
Mattias Walström 0d6384021f move yanger 2026-06-17 11:54:24 +02:00
Mattias Walström e0af89154f yangerd: Initial 2026-06-17 11:54:24 +02:00
Mattias Walström ec87d50204 TEMP: Update yanger spec 2026-06-17 11:54:24 +02:00
Mattias Walström 4c13696091 TEMP: WiP document 2026-06-17 11:54:24 +02:00
Joachim Wiberg 7e19ee8777 webui: add Connectivity and Addresses cards to Overview
Surface network diagnostics the Overview lacked: default gateway(s) with
a live reachability dot, an Internet reachability check, the effective DNS
resolvers (origin static vs DHCP, plus the interface), search domains, NTP
sync, and the IP addresses of every L3 interface.

All from the operational datastore. Reachability is an async per-address
ping (pulsing green dot on reply, red cross on none).

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 21:02:16 +02:00
Joachim Wiberg 7e0e6f244d webui: user-menu Auto-logout and theme fixes
Auto-logout was client-side only while the server kept a fixed 1h idle
timeout, so "Off" still logged you out. Sessions now carry a per-session
timeout the client syncs from the menu (0 = never), capped at 24h.

Theme: the login toggle icon was never initialised on load (stuck on the
'auto' glyph); add color-scheme so native controls follow the OS on
'auto', and re-apply on OS theme change.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 21:02:15 +02:00
Joachim Wiberg d326939e10 webui: final touches
- Add missing Configure -> shortcuts
 - For shortcuts into YANG tree, expand and mark the tree node
 - Revamp the /mdns status page to mimic /ntp => more vertical space

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 21:02:15 +02:00
Joachim Wiberg a975f55284 webui: show device hostname in topbar
Surface the configured hostname right of the logo, pinned to the
sidebar's right edge so it reads as the start of the content area. When
location and/or contact are set they appear in a hover/focus popover, so
the bar stays uncluttered; the name links to Configure > System.

Loaded asynchronously (hx-trigger="load") to keep it out of every page's
data path — the topbar persists across htmx swaps, so it fetches once per
full page load and renders nothing on error or when no hostname is set.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:29 +02:00
Joachim Wiberg 89392c56be webui: add automatic .cfg migration when restoring a backup
Also adjust some card layout in both Backup and Restore cards.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:29 +02:00
Joachim Wiberg 67ec3faa54 webui: relocate and reorder some menu items
External services like the mdns-browser and the web console belong in
the User Menu next to the bundled user guide.  They all open another
browser tab and provide another service.

Place common tasks close to each other and high up: Interface overview,
routing table, and firewall.  Feels slightly better imo.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:29 +02:00
Joachim Wiberg 9272ae382d webui: type-aware Config column in interface overview
The collapsed Interfaces list left DHCP/SLAAC/zeroconf invisible until a
row was unfolded, so L3 interfaces showed only empty cells. Replace the
Addresses column with a Config column whose pills are chosen by role,
mirroring the Status > Interfaces data column but slanted to configured
intent: vid for VLANs, mode for WiFi, 802.1Q for filtering bridges, and
DHCPv4/DHCPv6/SLAAC/Zeroconf for IP interfaces, alongside any static
addresses.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:28 +02:00
Joachim Wiberg a78eeee651 webui: rebuild NTP & DNS client pages around per-item editing
Replace the single bulk-PUT form + client-side row cloning (which broke
when these pages were split out of System settings) with the
server-driven list pattern used by Keystore/Users: each server is a row
keyed by name that expands to edit, with per-row delete and a dedicated
add form.  DNS search domains become add/delete rows.  Server creates
its container on first use, and field-info ⓘ help is sourced from the
YANG descriptions.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:28 +02:00
Joachim Wiberg 1c3086be94 webui: re-render interface IP block in place after save
Surface confd-inferred values (DHCP option lists, etc.) on the curated
Interfaces page: SaveIPv4/IPv6Settings re-render just the interface's IP
block from the fresh candidate, swapped in place via outerHTML, so the
row stays expanded.  The DHCP foldout auto-expands after a save to reveal
the inferred options.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:27 +02:00
Joachim Wiberg cd19b626a7 webui: surface confd inference in the advanced tree editor
confd infers Infix-suggested values (DHCP option lists, related leaves,
normalised values) into the candidate when a change is written, but the
tree editor's write handlers only wrote — SaveLeaf echoed the typed value
back, SaveGroup returned 204 — so the inferred values never appeared
until a manual page reload.

After a save (cfgSaved) re-fetch the current tree page from the now
up-to-date candidate and re-render it, so inference surfaces wherever it
landed on the page.  SaveLeaf now emits cfgSaved + 204 like SaveGroup
(its form uses hx-swap="none") instead of echoing the raw input.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:26 +02:00
Joachim Wiberg b5b310f3c8 webui: fix enabling DHCP/L3 on an interface with no prior IPv4/IPv6
SaveIPv4Settings/SaveIPv6Settings PATCHed the ietf-ip:ipv4 container to
set forwarding, but a plain PATCH 400s ("Target resource does not exist")
when the interface has no L3 config yet — exactly the first-time
DHCP-enable case.  PATCH the interface instead, with the family container
nested in a single-element list entry (rousette rejects the bare-object
form with LY_EVALID once an augmented container is nested), so the
container is created on first use.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:26 +02:00
Joachim Wiberg f875056706 webui: reload page on reconnect -> /login
When we reconnect to a device we should reload the page instead of
silently resume.  Because the device may have been rebooted from the
CLI or experienced power loss.  Either way, our session in RAM only
is likely gone, and if so we'll be redirected to /login again.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:25 +02:00
Joachim Wiberg e412c28c37 webui: bundle on-device User's Guide
Build the mkdocs User's Guide into WebUI images and surface it in the UI.
post-build.sh runs `mkdocs build` from the top-level mkdocs.yml into
/var/www/guide when the webui package is selected and mkdocs is on the
build host; nginx serves it read-only at /guide/.  The build is
best-effort — a missing mkdocs warns and ships without the guide rather
than failing — and minimal images (no webui) skip it.

The WebUI gates a book icon in the topbar and a User Guide item in the
user menu on the docs being present on disk (os.Stat, fail-closed), both
opening /guide/ in a new tab.

CI: a local setup-mkdocs composite action installs mkdocs and the
plugins from mkdocs.yml; the build and release workflows run it before
the build so images produced in CI include the guide.  developers-guide
documents the new build dependency and restores the missing
mkdocs-glightbox plugin.

Fixes #633

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:25 +02:00
Joachim Wiberg 3ccbdf2f0b webui: add network browser shortcut to topbar and nav
Surface the mDNS network browser (netbrowse at network.local) from the
WebUI: a radar icon in the topbar and a Network Browser entry under
Status > Network, both opening it in a new tab.

Like the console, this is a config-gated capability; fold the console and
netbrowse enable flags into a single infix-services web read at login
(DetectWebShortcuts) and render each entry only when enabled, fail-closed
on a read error.  The link is a static https://network.local/ since
netbrowse is a fixed name-based vhost.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:24 +02:00
Joachim Wiberg 8b3ba1f5c5 webui: add web console shortcut to topbar and nav
Surface the ttyd web console (port 7681) from the WebUI: a terminal icon
in the topbar and a Console entry under Maintenance, both opening the
console in a new tab.  The link target is built client-side from the
current hostname since the console runs on its own HTTPS port.

The console is a config-gated capability (infix-services web/console
enabled), so both entries are detected at login and rendered only when
it is enabled — a disabled console shows no entry rather than a dead
link.  Detection fails closed: a config read error hides the entry.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:24 +02:00
Joachim Wiberg 629f0aa74a webui: add support bundle to Backup & Support
Rename the Maintenance > Backup & Restore page to Backup & Support and
add a Support Bundle card.  Download support runs the on-device
`support collect` tool, which gathers configuration, logs, routing,
interfaces, hardware inventory, and container and service status into a
single archive; the WebUI runs as root so the collection is complete.

The handler buffers the archive and only commits response headers once
collection succeeds, so a mid-collection failure is a clean error rather
than a truncated download.  An optional password encrypts the bundle via
the tool's GPG support, fed on stdin so it never reaches the process
list.  Collection blocks for up to a minute with no output, so the write
deadline is extended past the server's 15s WriteTimeout and nginx gets a
matching read timeout; the browser shows a "collecting" state and saves
the blob client-side using the server's filename.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:23 +02:00
Joachim Wiberg dc2d429093 webui: add Maintenance > Diagnostics
New Diagnostics page under Maintenance runs ping, traceroute, mtr and
nmap with live output, plus a one-shot DNS lookup.  A tab per tool
shares a target field, source-interface and address-family selectors,
and per-tool options; the field is focused on load and Enter runs the
active tool from any field.

Ping and traceroute stream their output line by line over SSE.  mtr
runs --raw and its records are translated into a live hop table —
Loss%, Snt, Last, Avg, Best, Worst updating in place — running
continuously until Stop, or for a set number of cycles.  nmap offers a
fixed set of scan profiles (quick, standard, service/version, host
discovery); a CIDR target sweeps a subnet.

Address family is forced with an explicit -4/-6 flag on the base
binary, so a dual-stack hostname no longer follows the system's
IPv6-first resolver preference on hosts that only have IPv4 routes.

The streamer hands the child a real OS pipe and reaps it on exit, so a
client disconnect (Stop closing the EventSource) kills the tool without
leaking processes.  User input is guarded: targets reject a leading
dash and whitespace, the source interface is allow-listed against
configured interfaces, and arguments are always passed as a slice.  The
target field keeps a history in localStorage.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:23 +02:00
Joachim Wiberg b1146cbb31 webui: add Maintenance > Logs viewer
New Logs page under Maintenance presents the on-disk syslog files
(messages, syslog, kern, auth, routing, firewall, upgrade, debug,
container, mail) with a tab per source and an (empty) chip for files
with no content.

The buffer loads the last 250 lines and pins to the bottom on open and
on tab change, with keyboard focus on the pane so PageUp/PageDown work
immediately.  Load earlier pages back 250 lines at a time, preserving
the reader's scroll position as older lines fill in above; once the
current file is exhausted the button re-labels to "Load previous from
<rotation>" and walks back through rotated and gzipped archives.

Live tail streams new entries over SSE.  The server runs tail -F -n 0
and debounces output; the client follows the bottom unless the reader
has scrolled up.  A status pill shows connecting/live/disconnected.
nginx gets a no-buffering location for the tail stream, mirroring the
software progress endpoint.

Download returns the full archive — current file plus every rotated and
gzipped predecessor — concatenated chronologically.

Severity is coloured by a keyword heuristic since sysklogd writes no
<PRI> to disk; BSD-format lines are shown unconditionally.  Filter is
client-side substring or /regex/, focusable with Ctrl/Cmd-F.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:22 +02:00
Joachim Wiberg 10ab88d93f webui: drop Status > Keystore page
GET /keystore was just an http.Redirect to /configure/keystore — no
actual status view ever existed; the link landed users in Configure
and folded the Status group on the way, which was confusing.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:22 +02:00
Joachim Wiberg d07c8a9b5e webui: styling and cleanup
Vendor a Lucide icon set under static/img/icons/ and partial:ize the
inline SVGs across base, login, firmware, sidebar, and yang-tree.

Reorganize the sidebar with mirrored Status/Configure section labels.
Rename NACM to Users & Groups and Firmware to Software; swap Routes and
Routing between Status and Configure.

Split Configure > System into General, NTP Client, and DNS Client pages,
which opens up for relocating the Set Time RPC from the Maintenance
section to a new Date & Time card in the System General config page.

Update browser tab title on htmx navigation via an HX-Trigger
setPageTitle event; encode the payload as 7-bit ASCII so the middle
dot in "Page · Context" survives header transit.

Add missing hover-help ⓘ icons to bridge port configuration, and adjust
their alignment slightly.  While in interface configuration:
 - fix the annoying Save => collapse so one can edit multiple
   interface sections without having to re-expand the iface
 - add missing dhcpv4 settings
 - add missing custom mac (use advanced view for other settings)
 - clean up Save button mess (consolidate)

Rename Firmware -> Software everywhere in the Maintenance section and
fix "Install progress stuck at 10%" issue.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:21 +02:00
Joachim Wiberg c40c1d0c10 webui: ethernet status and configuration
Status overview gains a Speed column reading ietf-interfaces:speed +
ethernet/duplex.  Interface detail page surfaces PHY type, PMD type,
supported and advertised PMDs.

Configure > Interfaces gains a per-row Ethernet panel: auto-negotiation
toggle, advertised PMDs picker, duplex tri-state, mdi-x tri-state.  Each
has a reset-to-YANG-default button.  Backend writes leaf-by-leaf via
PATCH+DELETE since a single PUT silently drops the duplex leaf.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:21 +02:00
Joachim Wiberg d9611c48a9 webui: rename Go module to infix/webui
The webui Go code now lives in the infix source tree rather than being
imported as an external module.  Switch the module path to match that
reality so the imports read coherently with the rest of the codebase.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-06-15 19:45:20 +02:00