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:
6
Makefile
6
Makefile
@@ -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
111
debian/build-deb.sh
vendored
@@ -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
22
debian/vpp-maglev.control.in
vendored
Normal 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.
|
||||||
@@ -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).
|
||||||
0
debian/prerm → debian/vpp-maglevd.prerm
vendored
0
debian/prerm → debian/vpp-maglevd.prerm
vendored
141
docs/maglevt.1
Normal file
141
docs/maglevt.1
Normal 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>
|
||||||
Reference in New Issue
Block a user