Split Debian package into vpp-maglevd + vpp-maglev; add maglevt.1 manpage

vpp-maglevd ships maglevd, maglevd-frontend, both systemd units, and
the config conffiles. vpp-maglev ships maglevc and maglevt as pure
client tools so jump hosts and workstations can install them without
pulling in the daemon. pkg-deb now emits four .debs per release
(2 packages x 2 archs); build-deb.sh takes a package-name argument
and dispatches accordingly.
This commit is contained in:
2026-04-15 15:15:04 +02:00
parent 1664382d25
commit 177d81cca1
9 changed files with 245 additions and 49 deletions

View File

@@ -88,8 +88,10 @@ $(FRONTEND_WEB_DIST): $(FRONTEND_WEB_SRC)
cd cmd/frontend/web && npm install && npm run build cd cmd/frontend/web && npm install && npm run build
pkg-deb: build-amd64 build-arm64 pkg-deb: build-amd64 build-arm64
debian/build-deb.sh amd64 $(VERSION) debian/build-deb.sh vpp-maglevd amd64 $(VERSION)
debian/build-deb.sh arm64 $(VERSION) debian/build-deb.sh vpp-maglevd arm64 $(VERSION)
debian/build-deb.sh vpp-maglev amd64 $(VERSION)
debian/build-deb.sh vpp-maglev arm64 $(VERSION)
test: $(GEN_FILES) test: $(GEN_FILES)
go test ./... go test ./...

111
debian/build-deb.sh vendored
View File

@@ -1,64 +1,93 @@
#!/bin/bash #!/bin/bash
# Build a vpp-maglev Debian package for one architecture. # Build one vpp-maglev* Debian package for one architecture.
# Usage: build-deb.sh <amd64|arm64> <version> # Usage: build-deb.sh <package> <amd64|arm64> <version>
#
# <package> is one of:
# vpp-maglevd — health-checker daemon + optional web dashboard,
# with both systemd units, the default config, and
# the /etc/default/vpp-maglev environment file.
# vpp-maglev — maglevc CLI client and maglevt out-of-band tester.
# Pure client-side tools, no systemd units, no conffiles.
# #
# The commit hash is baked into the binaries at link time via -ldflags # The commit hash is baked into the binaries at link time via -ldflags
# in the Makefile, so `maglevd --version` / `maglevc --version` / # in the Makefile, so `maglevd --version` / `maglevc --version` / etc.
# `maglevd-frontend --version` are the source of truth for "which # are the source of truth for "which build". The .deb itself carries
# build". The .deb itself carries only the release version. # only the release version.
set -euo pipefail set -euo pipefail
ARCH="${1:?usage: build-deb.sh <amd64|arm64> <version>}" PACKAGE="${1:?usage: build-deb.sh <vpp-maglevd|vpp-maglev> <amd64|arm64> <version>}"
VERSION="${2:?usage: build-deb.sh <amd64|arm64> <version>}" ARCH="${2:?usage: build-deb.sh <vpp-maglevd|vpp-maglev> <amd64|arm64> <version>}"
VERSION="${3:?usage: build-deb.sh <vpp-maglevd|vpp-maglev> <amd64|arm64> <version>}"
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
PKG="vpp-maglev_${VERSION}_${ARCH}" PKG="${PACKAGE}_${VERSION}_${ARCH}"
STAGING="$(mktemp -d)" STAGING="$(mktemp -d)"
trap 'rm -rf "$STAGING"' EXIT trap 'rm -rf "$STAGING"' EXIT
echo "Building ${PKG}.deb" echo "Building ${PKG}.deb"
# Directories
install -d "$STAGING/usr/sbin"
install -d "$STAGING/usr/bin"
install -d "$STAGING/usr/share/man/man1"
install -d "$STAGING/usr/share/man/man8"
install -d "$STAGING/lib/systemd/system"
install -d "$STAGING/etc/default"
install -d "$STAGING/etc/vpp-maglev"
install -d "$STAGING/DEBIAN" install -d "$STAGING/DEBIAN"
# Binaries. maglevd and maglevd-frontend are daemons and live under case "$PACKAGE" in
# /usr/sbin; maglevc is the interactive CLI client and lives under vpp-maglevd)
# /usr/bin so it's on every login shell's PATH. install -d "$STAGING/usr/sbin"
install -m 755 "$REPO_ROOT/build/${ARCH}/maglevd" "$STAGING/usr/sbin/maglevd" install -d "$STAGING/usr/share/man/man8"
install -m 755 "$REPO_ROOT/build/${ARCH}/maglevc" "$STAGING/usr/bin/maglevc" install -d "$STAGING/lib/systemd/system"
install -m 755 "$REPO_ROOT/build/${ARCH}/maglevd-frontend" "$STAGING/usr/sbin/maglevd-frontend" install -d "$STAGING/etc/default"
install -d "$STAGING/etc/vpp-maglev"
# Man pages # Binaries. Both daemons live under /usr/sbin; they are long-running
gzip -9 -c "$REPO_ROOT/docs/maglevd.8" > "$STAGING/usr/share/man/man8/maglevd.8.gz" # services, not interactive tools.
gzip -9 -c "$REPO_ROOT/docs/maglevc.1" > "$STAGING/usr/share/man/man1/maglevc.1.gz" install -m 755 "$REPO_ROOT/build/${ARCH}/maglevd" "$STAGING/usr/sbin/maglevd"
gzip -9 -c "$REPO_ROOT/docs/maglevd-frontend.8" > "$STAGING/usr/share/man/man8/maglevd-frontend.8.gz" install -m 755 "$REPO_ROOT/build/${ARCH}/maglevd-frontend" "$STAGING/usr/sbin/maglevd-frontend"
# Systemd units # Man pages
install -m 644 "$REPO_ROOT/debian/vpp-maglev.service" "$STAGING/lib/systemd/system/vpp-maglev.service" gzip -9 -c "$REPO_ROOT/docs/maglevd.8" > "$STAGING/usr/share/man/man8/maglevd.8.gz"
install -m 644 "$REPO_ROOT/debian/vpp-maglev-frontend.service" "$STAGING/lib/systemd/system/vpp-maglev-frontend.service" gzip -9 -c "$REPO_ROOT/docs/maglevd-frontend.8" > "$STAGING/usr/share/man/man8/maglevd-frontend.8.gz"
# /etc/default/vpp-maglev (conffile — dpkg won't overwrite on upgrade) # Systemd units
install -m 644 "$REPO_ROOT/debian/default.vpp-maglev" "$STAGING/etc/default/vpp-maglev" install -m 644 "$REPO_ROOT/debian/vpp-maglev.service" "$STAGING/lib/systemd/system/vpp-maglev.service"
install -m 644 "$REPO_ROOT/debian/vpp-maglev-frontend.service" "$STAGING/lib/systemd/system/vpp-maglev-frontend.service"
# /etc/vpp-maglev/maglev.yaml (conffile) # /etc/default/vpp-maglev (conffile — dpkg won't overwrite on upgrade)
install -m 644 "$REPO_ROOT/debian/maglev.yaml" "$STAGING/etc/vpp-maglev/maglev.yaml" install -m 644 "$REPO_ROOT/debian/default.vpp-maglev" "$STAGING/etc/default/vpp-maglev"
# DEBIAN/control # /etc/vpp-maglev/maglev.yaml (conffile)
sed "s/@VERSION@/${VERSION}/;s/@ARCH@/${ARCH}/" \ install -m 644 "$REPO_ROOT/debian/maglev.yaml" "$STAGING/etc/vpp-maglev/maglev.yaml"
"$REPO_ROOT/debian/control.in" > "$STAGING/DEBIAN/control"
# DEBIAN/conffiles, postinst, prerm, postrm # DEBIAN metadata
install -m 644 "$REPO_ROOT/debian/conffiles" "$STAGING/DEBIAN/conffiles" sed "s/@VERSION@/${VERSION}/;s/@ARCH@/${ARCH}/" \
install -m 755 "$REPO_ROOT/debian/postinst" "$STAGING/DEBIAN/postinst" "$REPO_ROOT/debian/vpp-maglevd.control.in" > "$STAGING/DEBIAN/control"
install -m 755 "$REPO_ROOT/debian/prerm" "$STAGING/DEBIAN/prerm" install -m 644 "$REPO_ROOT/debian/vpp-maglevd.conffiles" "$STAGING/DEBIAN/conffiles"
install -m 755 "$REPO_ROOT/debian/postrm" "$STAGING/DEBIAN/postrm" install -m 755 "$REPO_ROOT/debian/vpp-maglevd.postinst" "$STAGING/DEBIAN/postinst"
install -m 755 "$REPO_ROOT/debian/vpp-maglevd.prerm" "$STAGING/DEBIAN/prerm"
install -m 755 "$REPO_ROOT/debian/vpp-maglevd.postrm" "$STAGING/DEBIAN/postrm"
;;
vpp-maglev)
install -d "$STAGING/usr/bin"
install -d "$STAGING/usr/share/man/man1"
# Binaries. Both client tools live under /usr/bin so they land on
# every login shell's PATH without needing /usr/sbin on PATH.
install -m 755 "$REPO_ROOT/build/${ARCH}/maglevc" "$STAGING/usr/bin/maglevc"
install -m 755 "$REPO_ROOT/build/${ARCH}/maglevt" "$STAGING/usr/bin/maglevt"
# Man pages
gzip -9 -c "$REPO_ROOT/docs/maglevc.1" > "$STAGING/usr/share/man/man1/maglevc.1.gz"
gzip -9 -c "$REPO_ROOT/docs/maglevt.1" > "$STAGING/usr/share/man/man1/maglevt.1.gz"
# DEBIAN metadata. The client package has no conffiles and no
# maintainer scripts — it ships binaries and manpages only.
sed "s/@VERSION@/${VERSION}/;s/@ARCH@/${ARCH}/" \
"$REPO_ROOT/debian/vpp-maglev.control.in" > "$STAGING/DEBIAN/control"
;;
*)
echo "error: unknown package '${PACKAGE}' (expected vpp-maglevd or vpp-maglev)" >&2
exit 2
;;
esac
# Emit package into build/ # Emit package into build/
mkdir -p "$REPO_ROOT/build" mkdir -p "$REPO_ROOT/build"

22
debian/vpp-maglev.control.in vendored Normal file
View File

@@ -0,0 +1,22 @@
Package: vpp-maglev
Version: @VERSION@
Architecture: @ARCH@
Maintainer: Pim van Pelt <pim@ipng.ch>
Section: net
Priority: optional
Description: Maglev CLI client and out-of-band VIP tester
maglevc is an interactive CLI client for maglevd with tab completion,
inline help, and a one-shot mode for scripting. It talks to maglevd
over gRPC and can drive either a local daemon or a remote one.
.
maglevt is an out-of-band HTTP probe TUI that reads a maglev.yaml,
hits each configured frontend on a configurable HTTP path, and
reports latency plus a response-header tally so operators can see
Maglev failover as it happens. It does not talk gRPC and does not
depend on a running maglevd; it is useful for validating a maglevd
restart end-to-end from a client perspective and for debugging pool
failover.
.
Install alongside the vpp-maglevd package to manage a local daemon,
or install standalone on a jump host or operator workstation to
manage remote maglevds over gRPC.

View File

@@ -1,19 +1,21 @@
Package: vpp-maglev Package: vpp-maglevd
Version: @VERSION@ Version: @VERSION@
Architecture: @ARCH@ Architecture: @ARCH@
Maintainer: Pim van Pelt <pim@ipng.ch> Maintainer: Pim van Pelt <pim@ipng.ch>
Section: net Section: net
Priority: optional Priority: optional
Depends: systemd, adduser Depends: systemd, adduser
Description: Maglev health-checker daemon, CLI client, and web frontend Recommends: vpp-maglev
Description: Maglev health-checker daemon and web frontend for the VPP lb plugin
maglevd monitors backends (HTTP, TCP, ICMP) with a rise/fall counter maglevd monitors backends (HTTP, TCP, ICMP) with a rise/fall counter
model and exposes their aggregated state over a gRPC API. Configuration model, programs the VPP lb plugin via its binary API, and exposes the
result over a gRPC API and Prometheus metrics endpoint. Configuration
is loaded from a YAML file and supports live reload via SIGHUP. is loaded from a YAML file and supports live reload via SIGHUP.
. .
maglevc is an interactive CLI client for maglevd with tab completion,
inline help, and one-shot mode for scripting.
.
maglevd-frontend is an optional web dashboard that fans one or more maglevd-frontend is an optional web dashboard that fans one or more
maglevd gRPC streams out to browsers over Server-Sent Events. It is maglevd gRPC streams out to browsers over Server-Sent Events. It is
installed but not enabled by default; enable with: installed but not enabled by default; enable with:
systemctl enable --now vpp-maglev-frontend systemctl enable --now vpp-maglev-frontend
.
The maglevc CLI client and the maglevt out-of-band tester live in
the vpp-maglev package (recommended but not required).

141
docs/maglevt.1 Normal file
View File

@@ -0,0 +1,141 @@
.TH MAGLEVT 1 "April 2026" "vpp\-maglev" "User Commands"
.SH NAME
maglevt \- Maglev out\-of\-band VIP probe TUI
.SH SYNOPSIS
.B maglevt
[\fB\-config\fR \fIfile\fR]...
[\fB\-interval\fR \fIdur\fR]
[\fB\-timeout\fR \fIdur\fR]
[\fB\-host\fR \fIstr\fR]
[\fB\-uri\fR \fIpath\fR]
[\fB\-header\fR \fIname\fR]
[\fB\-insecure\fR[=\fIbool\fR]]
[\fB\-keepalive\fR]
[\fB\-filter\fR \fIregex\fR]
[\fB\-version\fR]
.SH DESCRIPTION
.B maglevt
is an out\-of\-band VIP probe TUI for
.B vpp\-maglev
deployments. It reads one or more
.B maglev.yaml
configuration files, enumerates the configured TCP/HTTP frontends, and
probes each one on a configurable HTTP path at a configurable interval.
It does not talk gRPC, does not depend on a running
.BR maglevd (8),
and reports its results as a live full\-screen TUI rather than to any
machine\-readable channel.
.PP
Typical uses:
.IP \(bu 2
Validate a
.B maglevd
restart end\-to\-end from a client perspective. The probe tally keeps
running independently of the control plane, so a brief dataplane blip
or a missed failover is visible directly in the TUI.
.IP \(bu 2
Debug pool failover. With keep\-alives off (the default), each probe
opens a fresh TCP connection and is reshuffled by VPP's Maglev hash,
so the response\-header tally visibly changes the moment a standby
pool takes over.
.IP \(bu 2
Sanity\-check VIP reachability across sites when the gRPC control
plane is unavailable or out of reach from the operator's machine.
.SH OPTIONS
.TP
.BI \-config " file"
Path to a
.B maglev.yaml
configuration file. The flag is repeatable and also accepts a
comma\-separated list. Frontends are unioned across all supplied files
and de\-duplicated by
.IR "(scheme, address, port)" ,
so the same VIP is never probed twice even when multiple files
reference it.
.RI "(default: " /etc/vpp-maglev/maglev.yaml )
.TP
.BI \-interval " dur"
Probe interval per VIP. Uniform
.B \(+-10%
jitter is applied per probe to prevent phase\-locking after a
restart.
.RI "(default: " 100ms )
.TP
.BI \-timeout " dur"
Per\-request timeout. Bounds a single probe attempt; the interval
bounds the time between the
.I start
of consecutive attempts.
.RI "(default: " 2s )
.TP
.BI \-host " str"
Override for the HTTP
.B Host
header. When unset,
.B maglevt
uses the VIP's address literal as the
.B Host
header.
.TP
.BI \-uri " path"
HTTP request path used in the
.B GET
request. The flag
.B \-path
is accepted as an alias.
.RI "(default: " /.well-known/ipng/healthz )
.TP
.BI \-header " name"
Response header whose value is extracted and tallied, so the TUI can
show which backend served each request.
.RI "(default: " X-IPng-Frontend )
.TP
.B \-insecure
Skip TLS certificate verification for HTTPS frontends.
.RI "(default: " true )
.TP
.BR \-keepalive ", " \-k
Enable HTTP keep\-alives. Off by default: every probe opens a fresh
connection, which is necessary for failover visibility because a
pinned keep\-alive would mask a Maglev reshuffle.
.RI "(default: " false )
.TP
.BI \-filter " regex"
Regular expression restricting which frontends are probed; only
frontends whose name matches are included.
.TP
.B \-version
Print version, commit hash, and build date, then exit.
.SH "USER INTERFACE"
The TUI is built with Bubble Tea and shows a deterministic grid: one
tile per VIP, with IPv6 tiles before IPv4 and HTTPS before HTTP so the
layout is stable across runs and across machines. Each tile carries a
rolling latency summary (min, max, average, and several percentiles),
running success and failure counts, and a tally of the configured
response\-header values seen from that VIP.
.PP
Press
.B d
to toggle reverse\-DNS resolution on the addresses shown in the tile
headers. Press
.B q
or Ctrl\-C to exit. There is no machine\-readable output; use the
Prometheus
.B /metrics
endpoint on
.BR maglevd (8)
when you need metrics.
.SH "FULL DOCUMENTATION"
This manpage documents only the invocation of
.BR maglevt .
For the full operational guide see the user guide at:
.PP
.RS
https://git.ipng.ch/ipng/vpp-maglev/docs/user-guide.md
.RE
.SH "SEE ALSO"
.BR maglevd (8),
.BR maglevc (1),
.BR maglevd\-frontend (8)
.SH AUTHOR
Pim van Pelt <pim@ipng.ch>