Files
steward/scripts/mkdeb.sh
T
abrown38andClaude Opus 5.5 3c0808591f Steward 0.1.0 (in development): a DHCPv4 server with a web UI, API and CLI
Subnets served per interface, pools, reservations, options at three
levels, leases in SQLite saved before the ACK, ping and decline conflict
checks, validated changes with history and undo, users and tokens, an
audit log, a Kea importer, a sandboxed systemd unit and Debian packages.
Tested with real udhcpc and dhcpcd clients in Docker (scripts/e2e.sh).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 12:14:07 +01:00

118 lines
5.0 KiB
Bash
Executable File

#!/bin/sh
# Builds Steward's two Debian packages:
#
# dist/steward-cli_<version>_<arch>.deb the CLI, to install anywhere:
# /usr/bin/steward, its bash completion, and /usr/share/doc/steward-cli/
# (README, CHANGELOG, the CLI and permissions docs). No scripts:
# installing it changes nothing else on the machine.
# dist/steward_<version>_<arch>.deb the server, which depends on
# steward-cli of the same version:
# /usr/bin/stewardd and its bash completion
# /usr/lib/systemd/system/{steward.service,steward-backup.service,steward-backup.timer}
# /usr/lib/sysusers.d/steward.conf, /usr/lib/tmpfiles.d/steward.conf
# /usr/share/doc/steward/ (README, CHANGELOG, docs)
# Its scripts (deploy/debian) create the steward user and directories and
# /etc/steward/steward.yaml on the first install, turn on the daily backup
# timer, restart a running stewardd on upgrades, and stop both on removal.
# No file in /etc belongs to the package, so an upgrade never asks
# about configuration files.
#
# Run through 'make deb' (which sets the variables below); needs only
# dpkg-deb, no root and no debhelper.
#
# Variables: DEB_ARCH (Debian architecture, e.g. amd64, arm64, armhf),
# DEB_VERSION, VERSION, LDFLAGS, GOFLAGS, and DEB_MAINTAINER (default: your
# git name and email).
set -eu
: "${DEB_ARCH:?}" "${DEB_VERSION:?}" "${VERSION:?}" "${LDFLAGS:?}"
GOFLAGS=${GOFLAGS:-}
# Debian architecture -> Go architecture.
goarm=
case "$DEB_ARCH" in
amd64) goarch=amd64 ;;
arm64) goarch=arm64 ;;
armhf) goarch=arm goarm=7 ;;
i386) goarch=386 ;;
ppc64el) goarch=ppc64le ;;
riscv64) goarch=riscv64 ;;
s390x) goarch=s390x ;;
*) echo "mkdeb: unsupported architecture $DEB_ARCH" >&2; exit 1 ;;
esac
if [ -z "${DEB_MAINTAINER:-}" ]; then
name=$(git config user.name 2>/dev/null || true)
email=$(git config user.email 2>/dev/null || true)
DEB_MAINTAINER="${name:-Steward packager} <${email:-root@localhost}>"
fi
work=dist/deb/${DEB_VERSION}_${DEB_ARCH}
stage=$work/stage
rm -rf "$work"
# Older packages of this architecture (every development build has its
# own version), so 'apt install ./dist/steward_*_amd64.deb' finds just one.
rm -f dist/steward_*_"$DEB_ARCH".deb dist/steward-cli_*_"$DEB_ARCH".deb
mkdir -p "$stage"
# Binaries for the package's architecture (bin/ holds the host's, which
# also generated the completion scripts).
echo "mkdeb: building for linux/$goarch"
# go reads GOFLAGS (-trimpath) from the environment.
export GOFLAGS
GOOS=linux GOARCH=$goarch GOARM=$goarm CGO_ENABLED=0 go build -ldflags "$LDFLAGS" -o "$work/bin/stewardd" ./cmd/stewardd
GOOS=linux GOARCH=$goarch GOARM=$goarm CGO_ENABLED=0 go build -ldflags "$LDFLAGS" -o "$work/bin/steward" ./cmd/steward
# Everything 'make install' would install, then split in two.
make --no-print-directory install-files DESTDIR="$stage" PREFIX=/usr \
UNITDIR=/usr/lib/systemd/system STEWARDD_BIN="$work/bin/stewardd" STEWARD_BIN="$work/bin/steward" >/dev/null
cli=$work/steward-cli
srv=$work/steward
mkdir -p "$cli/DEBIAN" "$cli/usr/bin" "$cli/usr/share/bash-completion/completions" "$cli/usr/share/doc/steward-cli/docs"
mv "$stage/usr/bin/steward" "$cli/usr/bin/"
mv "$stage/usr/share/bash-completion/completions/steward" "$cli/usr/share/bash-completion/completions/"
cp "$stage/usr/share/doc/steward/README.md" "$stage/usr/share/doc/steward/CHANGELOG.md" "$cli/usr/share/doc/steward-cli/"
for d in cli permissions; do
cp "$stage/usr/share/doc/steward/docs/$d.md" "$cli/usr/share/doc/steward-cli/docs/"
done
mv "$stage" "$srv"
mkdir -p "$srv/DEBIAN"
for f in postinst prerm postrm; do
install -m 0755 "deploy/debian/$f" "$srv/DEBIAN/$f"
done
# Debian's machine-readable copyright file, from LICENSE.
indent() { sed -e 's/^$/./' -e 's/^/ /' "$1"; }
copyright() {
echo "Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/"
echo "Upstream-Name: steward"
echo
echo "Files: *"
echo "Copyright: $(sed -n 's/^Copyright (c) //p' LICENSE)"
echo "License: Expat"
indent LICENSE
}
# build PACKAGE ROOT: writes the control file and md5sums and builds the .deb.
build() {
pkg=$1 root=$2 out=dist/${1}_${DEB_VERSION}_${DEB_ARCH}.deb
copyright > "$root/usr/share/doc/$pkg/copyright"
rm -f "$root/usr/share/doc/$pkg/LICENSE"
# Directories 0755 and no group/other write, whatever the build's umask.
find "$root" -type d -exec chmod 0755 {} +
chmod -R go-w "$root"
size=$(du -sk --exclude=DEBIAN "$root" | cut -f1)
sed -e "s/@VERSION@/$DEB_VERSION/g" -e "s/@ARCH@/$DEB_ARCH/" -e "s/@SIZE@/$size/" \
-e "s|@MAINTAINER@|$DEB_MAINTAINER|" "deploy/debian/control-$pkg.in" > "$root/DEBIAN/control"
(cd "$root" && find . -path ./DEBIAN -prune -o -type f -print | sed 's|^\./||' | sort | xargs md5sum) > "$root/DEBIAN/md5sums"
chmod 0644 "$root/DEBIAN/control" "$root/DEBIAN/md5sums"
# Files belong to root in the package, whoever builds it.
dpkg-deb --root-owner-group -Zxz --build "$root" "$out" >/dev/null
echo "mkdeb: wrote $out"
dpkg-deb --info "$out" | sed -n 's/^ \(Package\|Version\|Architecture\|Installed-Size\|Depends\):/ \1:/p'
}
build steward-cli "$cli"
build steward "$srv"
rm -rf dist/deb