Add WatchEvents, enable/disable/weight RPCs, and config check

gRPC / proto
- Rename WatchBackendEvents → WatchEvents; return a stream of Event
  oneof (LogEvent, BackendEvent, FrontendEvent) with optional filter
  flags (log, log_level, backend, frontend)
- Add EnableBackend, DisableBackend, SetFrontendPoolBackendWeight RPCs
- Rename PauseResumeRequest → BackendRequest
- Add CheckConfig RPC returning ok/parse_error/semantic_error

maglevd
- Route slog through a LogBroadcaster (slog.Handler) so WatchEvents
  subscribers can receive structured log records independently of the
  daemon's own --log-level
- Add --reflection flag (default true) to toggle gRPC server reflection
- Add --check flag: validates config file and exits 0/1/2
- SIGHUP: use config.Check before applying reload; log parse vs semantic
  error separately; refuse reload on any error
- Rename default config path /etc/maglev → /etc/vpp-maglev

maglevc
- Add 'watch events [num <n>] [log [level <level>]] [backend] [frontend]'
  command; prints compact protojson, stops on any keypress or Ctrl-C;
  uses cbreak mode (not raw) so output post-processing is preserved
- Add 'set backend <name> enable|disable'
- Add 'set frontend <name> pool <pool> backend <name> weight <0-100>'
- Add 'config check' command

Debian packaging
- Rename service unit to vpp-maglevd.service
- Rename conffiles to /etc/default/vpp-maglev and /etc/vpp-maglev/
- Create maglevd system user/group in postinst; add to vpp group if present
- Add postrm; add adduser to Depends
This commit is contained in:
2026-04-11 16:42:11 +02:00
parent d612086a5f
commit 58391f5463
26 changed files with 1969 additions and 400 deletions

15
debian/build-deb.sh vendored
View File

@@ -22,7 +22,7 @@ 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/maglev"
install -d "$STAGING/etc/vpp-maglev"
install -d "$STAGING/DEBIAN"
# Binaries
@@ -34,22 +34,23 @@ gzip -9 -c "$REPO_ROOT/docs/maglevd.8" > "$STAGING/usr/share/man/man8/maglevd.8.
gzip -9 -c "$REPO_ROOT/docs/maglevc.1" > "$STAGING/usr/share/man/man1/maglevc.1.gz"
# Systemd unit
install -m 644 "$REPO_ROOT/debian/maglevd.service" "$STAGING/lib/systemd/system/maglevd.service"
install -m 644 "$REPO_ROOT/debian/vpp-maglevd.service" "$STAGING/lib/systemd/system/vpp-maglevd.service"
# /etc/default/maglev (conffile — dpkg won't overwrite on upgrade)
install -m 644 "$REPO_ROOT/debian/default.maglev" "$STAGING/etc/default/maglev"
# /etc/default/vpp-maglev (conffile — dpkg won't overwrite on upgrade)
install -m 644 "$REPO_ROOT/debian/default.vpp-maglev" "$STAGING/etc/default/vpp-maglev"
# /etc/maglev/maglev.yaml (conffile)
install -m 644 "$REPO_ROOT/debian/maglev.yaml" "$STAGING/etc/maglev/maglev.yaml"
# /etc/vpp-maglev/maglev.yaml (conffile)
install -m 644 "$REPO_ROOT/debian/maglev.yaml" "$STAGING/etc/vpp-maglev/maglev.yaml"
# DEBIAN/control (version field uses full_version including commit)
sed "s/@VERSION@/${FULL_VERSION}/;s/@ARCH@/${ARCH}/" \
"$REPO_ROOT/debian/control.in" > "$STAGING/DEBIAN/control"
# DEBIAN/conffiles, postinst, prerm
# DEBIAN/conffiles, postinst, prerm, postrm
install -m 644 "$REPO_ROOT/debian/conffiles" "$STAGING/DEBIAN/conffiles"
install -m 755 "$REPO_ROOT/debian/postinst" "$STAGING/DEBIAN/postinst"
install -m 755 "$REPO_ROOT/debian/prerm" "$STAGING/DEBIAN/prerm"
install -m 755 "$REPO_ROOT/debian/postrm" "$STAGING/DEBIAN/postrm"
# Emit package into build/
mkdir -p "$REPO_ROOT/build"

4
debian/conffiles vendored
View File

@@ -1,2 +1,2 @@
/etc/default/maglev
/etc/maglev/maglev.yaml
/etc/default/vpp-maglev
/etc/vpp-maglev/maglev.yaml

2
debian/control.in vendored
View File

@@ -4,7 +4,7 @@ Architecture: @ARCH@
Maintainer: Pim van Pelt <pim@ipng.ch>
Section: net
Priority: optional
Depends: systemd
Depends: systemd, adduser
Description: Maglev health-checker daemon and CLI client
maglevd monitors backends (HTTP, TCP, ICMP) with a rise/fall counter
model and exposes their aggregated state over a gRPC API. Configuration

View File

@@ -1,9 +1,9 @@
# Default settings for maglevd.
# This file is sourced by /lib/systemd/system/maglevd.service.
# After editing, run: systemctl restart maglevd
# This file is sourced by /lib/systemd/system/vpp-maglevd.service.
# After editing, run: systemctl restart vpp-maglevd
# Path to the YAML configuration file.
MAGLEV_CONFIG=/etc/maglev/maglev.yaml
MAGLEV_CONFIG=/etc/vpp-maglev/maglev.yaml
# gRPC listen address (default: :9090)
#MAGLEV_GRPC_ADDR=:9090

16
debian/postinst vendored
View File

@@ -2,7 +2,21 @@
set -e
case "$1" in
configure)
# Create system user and group if they don't exist.
if ! getent group maglevd > /dev/null 2>&1; then
addgroup --system --quiet maglevd
fi
if ! getent passwd maglevd > /dev/null 2>&1; then
adduser --system --no-create-home --shell /usr/sbin/nologin \
--ingroup maglevd --quiet maglevd
fi
# Add maglevd to vpp group if it exists (needed for VPP API socket access).
if getent group vpp > /dev/null 2>&1; then
adduser --quiet maglevd vpp || true
fi
systemctl daemon-reload || true
systemctl enable maglevd.service || true
systemctl enable vpp-maglevd.service || true
;;
esac

12
debian/postrm vendored Normal file
View File

@@ -0,0 +1,12 @@
#!/bin/sh
set -e
case "$1" in
purge)
if getent passwd maglevd > /dev/null 2>&1; then
deluser --quiet --system maglevd || true
fi
if getent group maglevd > /dev/null 2>&1; then
delgroup --quiet --system maglevd || true
fi
;;
esac

4
debian/prerm vendored
View File

@@ -2,7 +2,7 @@
set -e
case "$1" in
remove|purge)
systemctl stop maglevd.service || true
systemctl disable maglevd.service || true
systemctl stop vpp-maglevd.service || true
systemctl disable vpp-maglevd.service || true
;;
esac

View File

@@ -5,11 +5,18 @@ After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=/etc/default/maglev
User=maglevd
Group=maglevd
EnvironmentFile=/etc/default/vpp-maglev
ExecStart=/usr/sbin/maglevd --config ${MAGLEV_CONFIG}
Restart=on-failure
RestartSec=5s
Type=simple
# Grant only CAP_NET_RAW (needed for ICMP probes) and drop everything else.
AmbientCapabilities=CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_RAW
NoNewPrivileges=yes
[Install]
WantedBy=multi-user.target