Add Debian packaging, Makefile, manpages, tests, and design doc

Introduces a static-binary build and Debian package (amd64/arm64) with
version/commit/date stamped via -ldflags. Ships section-1 manpages for
ctool, ctfetch, and ctail. Adds a `version` subcommand reachable as
`ctool version`, `ctool -version`, `ctool --version`, `ctool fetch
version`, `ctool tail version`, and via the ctfetch/ctail symlinks. Adds
tests covering the dispatcher, fetch/tail argument parsing, and the
formatter/helper functions. Adds a retrofit design document modelled on
the vpp-maglev one, with FRs and NFRs for each tool and the dispatcher.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-21 22:21:32 +02:00
parent bbd566d10e
commit e18a89dcf0
15 changed files with 1632 additions and 8 deletions

55
debian/build-deb.sh vendored Executable file
View File

@@ -0,0 +1,55 @@
#!/bin/bash
# SPDX-License-Identifier: Apache-2.0
# Build the ctool Debian package for one architecture.
# Usage: build-deb.sh ctool <amd64|arm64> <version>
#
# The commit hash and build date are baked into the binary at link time
# via -ldflags in the Makefile, so `ctool version` is the source of truth
# for "which build". The .deb itself carries only the release version.
set -euo pipefail
PACKAGE="${1:?usage: build-deb.sh ctool <amd64|arm64> <version>}"
ARCH="${2:?usage: build-deb.sh ctool <amd64|arm64> <version>}"
VERSION="${3:?usage: build-deb.sh ctool <amd64|arm64> <version>}"
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
PKG="${PACKAGE}_${VERSION}_${ARCH}"
STAGING="$(mktemp -d)"
trap 'rm -rf "$STAGING"' EXIT
echo "Building ${PKG}.deb"
if [ "$PACKAGE" != "ctool" ]; then
echo "error: unknown package '${PACKAGE}' (expected ctool)" >&2
exit 2
fi
install -d "$STAGING/DEBIAN"
install -d "$STAGING/usr/bin"
install -d "$STAGING/usr/share/man/man1"
# Binary. ctool is an interactive tool, not a daemon, so it lives in
# /usr/bin and is on every login shell's PATH by default.
install -m 755 "$REPO_ROOT/build/${ARCH}/ctool" "$STAGING/usr/bin/ctool"
# ctfetch and ctail are busybox-style aliases: the binary dispatches on
# argv[0], so a symlink is all it takes for `ctfetch ...` to mean
# `ctool fetch ...` and `ctail ...` to mean `ctool tail ...`.
ln -s ctool "$STAGING/usr/bin/ctfetch"
ln -s ctool "$STAGING/usr/bin/ctail"
# Manpages — one overview (ctool) plus one detailed page per subcommand.
gzip -9 -c "$REPO_ROOT/docs/ctool.1" > "$STAGING/usr/share/man/man1/ctool.1.gz"
gzip -9 -c "$REPO_ROOT/docs/ctfetch.1" > "$STAGING/usr/share/man/man1/ctfetch.1.gz"
gzip -9 -c "$REPO_ROOT/docs/ctail.1" > "$STAGING/usr/share/man/man1/ctail.1.gz"
# DEBIAN metadata. No conffiles and no maintainer scripts — the package
# ships a single binary, two symlinks, and three manpages.
sed "s/@VERSION@/${VERSION}/;s/@ARCH@/${ARCH}/" \
"$REPO_ROOT/debian/${PACKAGE}.control.in" > "$STAGING/DEBIAN/control"
# Emit package into build/
mkdir -p "$REPO_ROOT/build"
OUT="$REPO_ROOT/build/${PKG}.deb"
dpkg-deb --build --root-owner-group "$STAGING" "$OUT"
echo "Built: $OUT"

24
debian/ctool.control.in vendored Normal file
View File

@@ -0,0 +1,24 @@
Package: ctool
Version: @VERSION@
Architecture: @ARCH@
Maintainer: Pim van Pelt <pim@ipng.ch>
Section: net
Priority: optional
Description: Tools for working with Static CT log tiles
ctool is a busybox-style binary that fetches and decodes entries
from Static CT API logs (c2sp.org/static-ct-api).
.
ctool fetch reads one or more log entries from a data tile —
either by leaf index or by dumping a whole tile URL / local file —
and prints them as structured JSON. Optional modifiers decode
embedded SCTs, fetch the issuer certificate from the log, and
enrich each SCT with operator and state information from the
Chrome CT log list.
.
ctool tail follows a log's /checkpoint endpoint and prints a
one-line summary per certificate or precertificate as new data
tiles complete. Useful for live monitoring of a log's growth.
.
The package installs ctool under /usr/bin along with ctfetch
and ctail symlinks, which invoke the matching subcommand
directly for scripting convenience.