Wheelhouse docs

The .deb#

wheelhouse-agent_<version>_<arch>.deb is the whole product minus the base: the agent binary, the built web UI, the installer, the seed tooling, the OPNsense importer, four systemd units and the licence files. It is built with the Python standard library only: no dpkg-deb, no build dependencies, no toolchain in CI.

Installing it on a running router reloads the units, starts the console-banner timer and restarts the agent, so an upgrade takes effect without a reboot.

Control fields#

Package: wheelhouse-agent
Version: <version>
Architecture: <arch>
Maintainer: <set by --maintainer>
Installed-Size: <computed>
Depends: bash, python3, dialog, curl
Section: net
Priority: optional
Homepage: https://releases.rhymelikedi.me
Description: Wheelhouse router control plane (agent + web UI)

Four runtime dependencies:

DependencyNeeded by
bashThe installer, the seed finder, first boot, the console banner, the wait script.
python3seed-to-answers.py, install-driver.py, the OPNsense importer, and the live-boot check inside the installer.
dialogThe interactive installer's whole interface.
curlFetching a seed or a payload over HTTPS.

Installed-Size is computed from the binary plus the UI tree, in kilobytes, with 64 KB of slack. The Maintainer field comes from --maintainer, whose default is a string set in the build script; it is not a monitored inbox and no maintainer address has been decided, so do not read it as a support route.

What it installs#

The full path list, with modes, is on Files and directories. In summary:

WhereWhat
/usr/bin/wheelhouse-agent, wheelhouse-install, wheelhouse-autoinstall, wheelhouse-opnsense-import
/usr/lib/wheelhouse/firstboot.sh, wait-for-vyos.sh, console-banner.sh, install-driver.py, seed-to-answers.py
/usr/share/wheelhouse/ui/, dialogrc and logo.txt
/lib/systemd/system/three services and one timer
/lib/systemd/system-generators/wheelhouse-live-installer
/usr/share/doc/wheelhouse-agent/copyright, README and third-party.md

The package does not run systemctl enable. It ships the symlinks directly:

/etc/systemd/system/multi-user.target.wants/wheelhouse-agent.service
/etc/systemd/system/multi-user.target.wants/wheelhouse-firstboot.service
/etc/systemd/system/multi-user.target.wants/wheelhouse-console.service
/etc/systemd/system/getty.target.wants/wheelhouse-console.service
/etc/systemd/system/timers.target.wants/wheelhouse-console.timer

That is what lets the same package install inside a live-build chroot, where systemctl cannot talk to anything.

The console banner has two of them because its [Install] section names two targets. multi-user.target.wants runs it; getty.target.wants puts it in the same transaction as the gettys, which is what its Before= ordering needs.

postinst and prerm#

sh
# postinst
set -e
if [ "$1" = configure ] && [ -d /run/systemd/system ]; then
    systemctl daemon-reload || true
    systemctl start wheelhouse-console.timer || true
    systemctl try-restart wheelhouse-agent.service || true
fi
exit 0
sh
# prerm
set -e
if [ -d /run/systemd/system ] && [ "$1" = remove ]; then
    systemctl stop wheelhouse-agent.service || true
fi
exit 0

Both are guarded on /run/systemd/system and every call is allowed to fail, because inside the image build there is no systemd to talk to. try-restart rather than restart: an agent that was deliberately stopped stays stopped.

README is the file Documentation= on every unit points at. It says what this is, what it is built on, and where the corresponding source lives.

What an upgrade does not do#

Removing the package stops the agent and removes the files it owns. It does not remove /config/wheelhouse, and it does not undo the configuration nodes first boot committed — the API key, the REST switch and the loopback binding stay in the router's configuration.

Building one#

bash
(cd ui && npm ci && npm run build)
(cd agent && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
  go build -trimpath -ldflags="-s -w -X main.version=1.2.3" -o wheelhouse-agent-amd64 .)
packaging/build-deb.py --version 1.2.3 --arch amd64 \
  --binary agent/wheelhouse-agent-amd64 --ui ui/dist --out dist/
OptionDefaultMeaning
--version(required)Goes into the control file and the file name.
--archamd64amd64 or arm64.
--binary(required)The built agent for that architecture.
--ui(required)ui/dist. Refused if it holds no index.html.
--out.Output directory.
--maintainera string in the scriptThe Debian Maintainer field.

SOURCE_DATE_EPOCH sets the timestamp stamped into every archive member, so the same inputs produce the same bytes.

Architectures#

amd64 and arm64 packages are both built. That is not the same as an arm64 product: there is no arm64 image and no VM image of any kind. The arm64 package exists for running the agent off-router against an arm64 router. The supported install is amd64 UEFI.

Inspecting one#

bash
dpkg-deb --info  wheelhouse-agent_0.5.1_amd64.deb
dpkg-deb --contents wheelhouse-agent_0.5.1_amd64.deb
dpkg -L wheelhouse-agent                              # on an installed box

See also#

Updated 2026-09-03 packaging deb debian upgrade