From b17396b1e5b27ba5bfc8ff2f63d8d54bd4fb37ff Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Wed, 6 May 2026 18:42:58 +0200 Subject: [PATCH] Rework build system; cut release 1.3.1-1 Replace the dpkg-buildpackage / debhelper rig with the same pattern used in vpp-maglev: a Makefile that cross-compiles CGO-free static binaries for amd64 and arm64, plus a debian/build-deb.sh that stages the .deb directly with dpkg-deb. The two arch packages drop into build/ and run on any glibc/musl Linux of the matching arch. VERSION is parsed once from debian/changelog and injected at link time via -ldflags "-X 'main.Version=...' -X 'main.Commit=...' -X 'main.Date=...'", so 'govpp-snmp-agentx --version' is the source of truth for which build is running. main.go's Version constant becomes a var to make this work; the old sync-version make target is gone. Removes the now-unused debian/{control,rules,postinst,prerm,*.debhelper} files and adds build/ to .gitignore. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 1 + Makefile | 63 ++++++++++++++--------- debian/build-deb.sh | 42 +++++++++++++++ debian/changelog | 25 +++++++++ debian/control | 23 --------- debian/govpp-snmp-agentx.conffiles | 1 + debian/govpp-snmp-agentx.control.in | 18 +++++++ debian/govpp-snmp-agentx.postinst | 8 +++ debian/govpp-snmp-agentx.postrm.debhelper | 12 ----- debian/govpp-snmp-agentx.prerm | 8 +++ debian/postinst | 23 --------- debian/prerm | 22 -------- debian/rules | 30 ----------- src/main.go | 3 +- 14 files changed, 145 insertions(+), 134 deletions(-) create mode 100755 debian/build-deb.sh delete mode 100644 debian/control create mode 100644 debian/govpp-snmp-agentx.conffiles create mode 100644 debian/govpp-snmp-agentx.control.in create mode 100644 debian/govpp-snmp-agentx.postinst delete mode 100644 debian/govpp-snmp-agentx.postrm.debhelper create mode 100644 debian/govpp-snmp-agentx.prerm delete mode 100755 debian/postinst delete mode 100755 debian/prerm delete mode 100755 debian/rules diff --git a/.gitignore b/.gitignore index 57b69a5..f33bfb9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ govpp-snmp-agentx vppcfg.yaml +build/ # Debian packaging artifacts debian/.debhelper/ diff --git a/Makefile b/Makefile index 7b7cdf2..5a65ba5 100644 --- a/Makefile +++ b/Makefile @@ -1,29 +1,46 @@ -PROG = govpp-snmp-agentx +PROG := govpp-snmp-agentx +MODULE := govpp-snmp-agentx +NATIVE_ARCH := $(shell go env GOARCH) +VERSION := ${shell head -1 debian/changelog | sed -n 's/.*(\([^)]*\)).*/\1/p'} +COMMIT_HASH := $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown) +DATE := $(shell date -u +%Y-%m-%dT%H:%M:%SZ) +LDFLAGS := -s -w \ + -X 'main.Version=$(VERSION)' \ + -X 'main.Commit=$(COMMIT_HASH)' \ + -X 'main.Date=$(DATE)' -.PHONY: build test clean pkg-deb sync-version +# CGO_ENABLED=0 produces a fully static binary: the same .deb runs on +# any glibc/musl Linux of the matching arch, and govpp itself has no +# cgo dependency, so this is a no-op for VPP API compatibility. +export CGO_ENABLED := 0 -# Build the binary -build: - cd src && go build -o ../$(PROG) . +.PHONY: help all build build-amd64 build-arm64 test pkg-deb clean -# Run all tests -test: +help: ## Show this help + @printf "Usage: make \n\nTargets:\n" + @awk -F ':.*## ' '/^[A-Za-z][A-Za-z0-9_-]*:.*## / {printf " %-16s %s\n", $$1, $$2}' $(MAKEFILE_LIST) + +all: build ## Alias for build (native arch) + +build: ## Build the binary for the host architecture + mkdir -p build/$(NATIVE_ARCH) + cd src && go build -ldflags "$(LDFLAGS)" -o ../build/$(NATIVE_ARCH)/$(PROG) . + +build-amd64: ## Cross-build the binary for linux/amd64 + mkdir -p build/amd64 + cd src && GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o ../build/amd64/$(PROG) . + +build-arm64: ## Cross-build the binary for linux/arm64 + mkdir -p build/arm64 + cd src && GOOS=linux GOARCH=arm64 go build -ldflags "$(LDFLAGS)" -o ../build/arm64/$(PROG) . + +test: ## Run all Go unit tests cd src && go test ./... -# Clean build artifacts -clean: +pkg-deb: build-amd64 build-arm64 ## Build .deb packages for amd64 and arm64 + debian/build-deb.sh $(PROG) amd64 $(VERSION) + debian/build-deb.sh $(PROG) arm64 $(VERSION) + +clean: ## Remove build artifacts + rm -rf build/ rm -f $(PROG) - [ -d debian/go ] && chmod -R +w debian/go || true - rm -rf debian/.debhelper debian/.gocache debian/go debian/$(PROG) debian/files debian/*.substvars debian/debhelper-build-stamp - rm -f ../$(PROG)_*.deb ../$(PROG)_*.changes ../$(PROG)_*.buildinfo - -# Sync version from debian/changelog to main.go -sync-version: - @echo "Syncing version from debian/changelog to main.go..." - @VERSION=$$(head -1 debian/changelog | sed -n 's/.*(\([^)]*\)).*/\1/p'); \ - sed -i 's/^const Version = ".*"/const Version = "'"$$VERSION"'"/' src/main.go; \ - echo "Updated Version const to: $$VERSION" - -# Build Debian package -pkg-deb: sync-version - fakeroot dpkg-buildpackage -us -uc -b diff --git a/debian/build-deb.sh b/debian/build-deb.sh new file mode 100755 index 0000000..de65cf1 --- /dev/null +++ b/debian/build-deb.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# SPDX-License-Identifier: Apache-2.0 +# Build one govpp-snmp-agentx .deb for one architecture. +# Usage: build-deb.sh +# +# The version is also baked into the binary at link time (see Makefile +# LDFLAGS), so `govpp-snmp-agentx --version` is the source of truth for +# "which build". The .deb itself only carries the release version. +set -euo pipefail + +PACKAGE="${1:?usage: build-deb.sh }" +ARCH="${2:?usage: build-deb.sh }" +VERSION="${3:?usage: build-deb.sh }" + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +PKG="${PACKAGE}_${VERSION}_${ARCH}" +STAGING="$(mktemp -d)" +trap 'rm -rf "$STAGING"' EXIT + +echo "Building ${PKG}.deb" + +install -d "$STAGING/DEBIAN" +install -d "$STAGING/usr/sbin" +install -d "$STAGING/usr/share/man/man1" +install -d "$STAGING/lib/systemd/system" +install -d "$STAGING/etc/default" + +install -m 755 "$REPO_ROOT/build/${ARCH}/${PACKAGE}" "$STAGING/usr/sbin/${PACKAGE}" +install -m 644 "$REPO_ROOT/${PACKAGE}.service" "$STAGING/lib/systemd/system/${PACKAGE}.service" +install -m 644 "$REPO_ROOT/${PACKAGE}.default" "$STAGING/etc/default/${PACKAGE}" +gzip -9 -c "$REPO_ROOT/docs/${PACKAGE}.1" > "$STAGING/usr/share/man/man1/${PACKAGE}.1.gz" + +sed "s/@VERSION@/${VERSION}/;s/@ARCH@/${ARCH}/" \ + "$REPO_ROOT/debian/${PACKAGE}.control.in" > "$STAGING/DEBIAN/control" +install -m 644 "$REPO_ROOT/debian/${PACKAGE}.conffiles" "$STAGING/DEBIAN/conffiles" +install -m 755 "$REPO_ROOT/debian/${PACKAGE}.postinst" "$STAGING/DEBIAN/postinst" +install -m 755 "$REPO_ROOT/debian/${PACKAGE}.prerm" "$STAGING/DEBIAN/prerm" + +mkdir -p "$REPO_ROOT/build" +OUT="$REPO_ROOT/build/${PKG}.deb" +dpkg-deb --build --root-owner-group "$STAGING" "$OUT" +echo "Built: $OUT" diff --git a/debian/changelog b/debian/changelog index 023317c..f3bf5ea 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,28 @@ +govpp-snmp-agentx (1.3.1-1) bookworm; urgency=medium + + * Fix startup race that left every ifSpeed/ifHighSpeed row stuck at + 1Gbps until restart. The stats routine could rebuild the MIB before + the interface-event routine had pushed any details, locking the + static fields at their "unknown" default; the rebuild was only + re-triggered on interface-set changes, so the wrong values were + never corrected. The stats path now pushes the details it already + fetches into the MIB, and a dirty flag forces a rebuild on the + next poll whenever Speed/MAC/MTU/admin/oper actually change. + + -- Pim van Pelt Tue, 06 May 2026 12:00:00 +0000 + +govpp-snmp-agentx (1.3.0-1) bookworm; urgency=medium + + * Fix ifSpeed for >2.5Gbps interfaces (10G/25G/100G): the row was + silently skipped, which let monitoring stacks fall back to a + hard-coded 1Gbps. Always emit ifSpeed and cap at uint32 max per + RFC 2863; ifHighSpeed continues to carry the real Mbps value. + * Switch the build system to cross-compiled, CGO-free amd64+arm64 + .deb packages produced by debian/build-deb.sh; inject the version + at link time via -ldflags. + + -- Pim van Pelt Tue, 06 May 2026 00:00:00 +0000 + govpp-snmp-agentx (1.2.3-1) bookworm; urgency=medium * Fix VPP stats filtering to exclude deleted interfaces diff --git a/debian/control b/debian/control deleted file mode 100644 index bbc224b..0000000 --- a/debian/control +++ /dev/null @@ -1,23 +0,0 @@ -Source: govpp-snmp-agentx -Section: net -Priority: optional -Maintainer: Pim van Pelt -Build-Depends: debhelper-compat (= 13), golang-go (>= 1.23.8) -Standards-Version: 4.6.2 -Homepage: https://git.ipng.ch/ipng/govpp-agentx-snmp -Vcs-Git: https://git.ipng.ch/ipng/govpp-agentx-snmp -Vcs-Browser: https://git.ipng.ch/ipng/govpp-agentx-snmp - -Package: govpp-snmp-agentx -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends}, snmpd -Description: GoVPP SNMP AgentX Daemon - A SNMP AgentX daemon that provides SNMP access to VPP (Vector Packet Processing) - statistics and interface information. This daemon acts as a subagent that - connects to the main SNMP daemon via the AgentX protocol. - . - Features: - - Interface MIB support - - VPP statistics exposure - - AgentX protocol implementation - - Systemd integration diff --git a/debian/govpp-snmp-agentx.conffiles b/debian/govpp-snmp-agentx.conffiles new file mode 100644 index 0000000..9dd7a47 --- /dev/null +++ b/debian/govpp-snmp-agentx.conffiles @@ -0,0 +1 @@ +/etc/default/govpp-snmp-agentx diff --git a/debian/govpp-snmp-agentx.control.in b/debian/govpp-snmp-agentx.control.in new file mode 100644 index 0000000..e52701d --- /dev/null +++ b/debian/govpp-snmp-agentx.control.in @@ -0,0 +1,18 @@ +Package: govpp-snmp-agentx +Version: @VERSION@ +Architecture: @ARCH@ +Maintainer: Pim van Pelt +Section: net +Priority: optional +Depends: snmpd, adduser +Homepage: https://git.ipng.ch/ipng/govpp-snmp-agentx +Description: SNMP AgentX subagent that exposes VPP interface statistics + govpp-snmp-agentx is a long-running daemon that connects to snmpd via + the AgentX protocol and serves the standard IF-MIB (ifTable, ifXTable) + from the VPP stats segment. It tracks interface lifecycle events and + keeps counters for live interfaces only, using the VPP binary API for + metadata and the stats shared memory for fast counter updates. + . + The daemon runs unprivileged as Debian-snmp:vpp; the systemd unit + prepares /var/agentx for the AgentX socket. Configuration of the + command-line flags happens in /etc/default/govpp-snmp-agentx. diff --git a/debian/govpp-snmp-agentx.postinst b/debian/govpp-snmp-agentx.postinst new file mode 100644 index 0000000..9cee537 --- /dev/null +++ b/debian/govpp-snmp-agentx.postinst @@ -0,0 +1,8 @@ +#!/bin/sh +set -e +case "$1" in + configure) + systemctl daemon-reload || true + systemctl enable govpp-snmp-agentx.service || true + ;; +esac diff --git a/debian/govpp-snmp-agentx.postrm.debhelper b/debian/govpp-snmp-agentx.postrm.debhelper deleted file mode 100644 index 95c7d31..0000000 --- a/debian/govpp-snmp-agentx.postrm.debhelper +++ /dev/null @@ -1,12 +0,0 @@ -# Automatically added by dh_installsystemd/13.24.2 -if [ "$1" = remove ] && [ -d /run/systemd/system ] ; then - systemctl --system daemon-reload >/dev/null || true -fi -# End automatically added section -# Automatically added by dh_installsystemd/13.24.2 -if [ "$1" = "purge" ]; then - if [ -x "/usr/bin/deb-systemd-helper" ]; then - deb-systemd-helper purge 'govpp-snmp-agentx.service' >/dev/null || true - fi -fi -# End automatically added section diff --git a/debian/govpp-snmp-agentx.prerm b/debian/govpp-snmp-agentx.prerm new file mode 100644 index 0000000..30a0f4e --- /dev/null +++ b/debian/govpp-snmp-agentx.prerm @@ -0,0 +1,8 @@ +#!/bin/sh +set -e +case "$1" in + remove|purge) + systemctl stop govpp-snmp-agentx.service || true + systemctl disable govpp-snmp-agentx.service || true + ;; +esac diff --git a/debian/postinst b/debian/postinst deleted file mode 100755 index f5e7e37..0000000 --- a/debian/postinst +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -set -e - -case "$1" in - configure) - # Enable and start the service - systemctl daemon-reload - systemctl enable govpp-snmp-agentx.service - ;; - - abort-upgrade|abort-remove|abort-deconfigure) - ;; - - *) - echo "postinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/debian/prerm b/debian/prerm deleted file mode 100755 index 8771633..0000000 --- a/debian/prerm +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -set -e - -case "$1" in - remove|upgrade|deconfigure) - systemctl stop govpp-snmp-agentx.service || true - systemctl disable govpp-snmp-agentx.service || true - ;; - - failed-upgrade) - ;; - - *) - echo "prerm called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -#DEBHELPER# - -exit 0 \ No newline at end of file diff --git a/debian/rules b/debian/rules deleted file mode 100755 index 8a4a1d9..0000000 --- a/debian/rules +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/make -f - -export DH_VERBOSE = 1 -export GO111MODULE = on -export GOPROXY = direct -export GOCACHE = $(CURDIR)/debian/.gocache -export GOPATH = $(CURDIR)/debian/go - -%: - dh $@ - -override_dh_auto_build: - cd src && go build -v -ldflags="-s -w" -o ../govpp-snmp-agentx . - -override_dh_auto_install: - install -D -m 0755 govpp-snmp-agentx debian/govpp-snmp-agentx/usr/sbin/govpp-snmp-agentx - install -D -m 0644 govpp-snmp-agentx.service debian/govpp-snmp-agentx/lib/systemd/system/govpp-snmp-agentx.service - install -D -m 0644 govpp-snmp-agentx.default debian/govpp-snmp-agentx/etc/default/govpp-snmp-agentx - install -D -m 0644 docs/govpp-snmp-agentx.1 debian/govpp-snmp-agentx/usr/share/man/man1/govpp-snmp-agentx.1 - -override_dh_auto_configure: - # Skip auto configure - -override_dh_auto_test: - # Skip tests during packaging - -override_dh_auto_clean: - rm -f govpp-snmp-agentx - [ -d debian/go ] && chmod -R +w debian/go || true - rm -rf debian/.gocache debian/go obj-* \ No newline at end of file diff --git a/src/main.go b/src/main.go index 8ec0828..2eeae65 100644 --- a/src/main.go +++ b/src/main.go @@ -16,7 +16,8 @@ import ( "govpp-snmp-agentx/vpp" ) -const Version = "1.2.3-1" +// Version is set at link time via -ldflags "-X main.Version=...". +var Version = "dev" func main() { debug := flag.Bool("debug", false, "Enable debug logging")