Rename maglev-frontend → maglevd-frontend; v0.9.1; API RX/TX pulse

Rename the web dashboard binary to maglevd-frontend and move it to
/usr/sbin (it's a daemon and belongs with maglevd). The systemd unit
name stays vpp-maglev-frontend.service since that prefix is the
package name. Manpage, README, user-guide, and debian packaging all
updated in lockstep; bump to 0.9.1 for the first real release.

All frontend env vars are now prefixed MAGLEV_FRONTEND_ so a single
/etc/default/vpp-maglev can be shared with maglevd without collisions.
Every flag has an env equivalent for Docker use. MAGLEV_FRONTEND_USER
and MAGLEV_FRONTEND_PASSWORD still gate the /admin surface.

VPPInfoPanel now pulses "API: ↑↓" indicators in the zippy title
whenever a vpp-api-send / vpp-api-recv log event arrives on the SSE
stream for the scoped maglevd — 250ms blue flash, re-triggerable,
with the two arrows tightly kerned via negative letter-spacing.
This commit is contained in:
2026-04-13 00:13:47 +02:00
parent 1191b3d994
commit 35643fd774
20 changed files with 380 additions and 83 deletions

View File

@@ -241,3 +241,83 @@ keyword. The `?` character is not added to the input line.
Commands and keywords support **prefix matching**: typing `sh ba` is equivalent
to `show backends`, and `sh ba nginx0` is equivalent to `show backends nginx0`.
---
## maglevd-frontend
`maglevd-frontend` is an optional web dashboard that connects to one or
more running `maglevd` instances over gRPC and renders a live view of
frontends, backends, health checks, and VPP load-balancer state. It is
a single Go binary with the SolidJS SPA embedded via `//go:embed`; no
runtime file dependencies.
Installed by the Debian package to `/usr/sbin/maglevd-frontend` but
**not** enabled by default — the operator opts in via:
```sh
systemctl enable --now vpp-maglev-frontend
```
The systemd unit (`vpp-maglev-frontend.service`) reads its arguments
from `/etc/default/vpp-maglev` via `MAGLEV_FRONTEND_ARGS`. The same
env file is shared with `maglevd`; all `maglevd-frontend`-specific
variables are prefixed with `MAGLEV_FRONTEND_` so there's no overlap.
### Flags
| Flag | Environment variable | Default | Description |
|---|---|---|---|
| `--server` | `MAGLEV_FRONTEND_SERVERS` | *(required)* | Comma-separated list of `host:port` maglevd addresses. |
| `--listen` | `MAGLEV_FRONTEND_LISTEN` | `:8080` | HTTP bind address. |
| `--log-level` | `MAGLEV_FRONTEND_LOG_LEVEL` | `info` | Structured-log verbosity for `maglevd-frontend`'s own logs. |
| `--version` | — | — | Print version, commit hash, and build date, then exit. |
In addition to flags, two env-only variables control the admin surface:
| Environment variable | Purpose |
|---|---|
| `MAGLEV_FRONTEND_USER` | HTTP basic-auth username for `/admin/`. |
| `MAGLEV_FRONTEND_PASSWORD` | HTTP basic-auth password for `/admin/`. |
When **both** are set and non-empty the admin surface is mounted and
the SPA's "admin…" toggle becomes visible. When either is missing or
empty the `/admin/` route returns 404 and the SPA hides the toggle —
`/view/` is always reachable read-only.
### HTTP surface
- **`/view/`** — static SPA (dashboard). No authentication.
- **`/view/api/state`**, **`/view/api/state/{name}`** — full JSON
snapshot for every maglevd, or one maglevd.
- **`/view/api/maglevds`** — configured maglevds and connection status.
- **`/view/api/version`** — build info + `admin_enabled` flag.
- **`/view/api/events`** — Server-Sent Events stream; log, backend,
frontend, maglevd-status, vpp-status events with
`Last-Event-ID` replay from a 30-second / 2000-event ring buffer.
- **`/healthz`** — liveness; returns 200 if the HTTP server is up.
- **`/admin/`** — SPA shell behind basic auth (when configured).
- **`POST /admin/api/{maglevd}/backend/{name}/{action}`** — backend
lifecycle action. `action` is `pause`, `resume`, `enable`, or
`disable`. Returns the fresh backend snapshot as JSON.
- **`POST /admin/api/{maglevd}/frontend/{fe}/pool/{pool}/backend/{name}/weight`**
— weight change. Body: `{"weight": 0-100, "flush": bool}`. When
`flush=true`, VPP's flow table for the backend is cleared;
otherwise only the new-buckets map is updated and existing
sessions keep reaching the backend until they finish.
### Reverse-proxy requirements (SSE)
Nginx, HAProxy, or any proxy in front of `maglevd-frontend` must:
- Disable buffering on the events endpoint. `X-Accel-Buffering: no`
is sent by the server; a global `proxy_buffering off;` in the
nginx server block is the more robust answer.
- Raise `proxy_read_timeout` to at least 300s so the stream isn't
torn down between the 15-second `: ping` heartbeats the server
sends.
- Not wrap the events endpoint in any gzip/brotli middleware —
response compression buffers until its window fills and destroys
the live-stream property.
See `maglevd-frontend(8)` for the full reference.