Wheelhouse docs

Rebuild a dead router onto a new box#

You will end up with a new machine that is the old router: the same configuration, the same accounts and passwords, the same API tokens, the same audit history, the same certificate and the same licence key. Roughly twenty minutes, and every step is manual.

This is the procedure people judge a product on, so here it is without varnish. There is no one-click restore. There is no factory-reset button. What there is is one directory that holds everything, and a sequence that puts it back in the right order.

Before you start#

  • A backup, taken as Take a backup that is actually complete describes. If all you have is a config.boot, you can restore the router but not the accounts — see Restore a configuration and expect to bootstrap a new admin account.
  • The same Wheelhouse version the backup came from. Restoring a newer config.boot onto an older image is not something this project has tested.
  • New hardware that meets the same constraints as the old: amd64, UEFI.
  • Physical or console access to the new box.

Step 1 — Install#

Boot the Wheelhouse ISO on the new machine and run through the installer. Answer the questions with anything sensible; you are about to overwrite the result. The one answer that matters is the LAN address — make it something you can reach, because you will need to get a file onto the box.

If you keep a config.boot with your backups, you can collapse this step and step 5 into one boot with a seed — see Rebuild without a keyboard below.

Step 2 — Get the backup onto the new box#

bash
scp wheelhouse-2026-09-02.tgz wheelhouse@<new-router>:/tmp/
ssh wheelhouse@<new-router>

Step 3 — Stop the agent#

So that it is not writing state.json while you replace it.

bash
sudo systemctl stop wheelhouse-agent

Step 4 — Restore the agent's data#

bash
cd /tmp && sudo tar -xzf wheelhouse-2026-09-02.tgz          # unpacks ./config
sudo rm -rf /config/wheelhouse
sudo cp -a /tmp/config/wheelhouse /config/wheelhouse
sudo cp -a /tmp/config/archive    /config/archive           # optional: commit history

That is the accounts, the password hashes, the TOTP secrets, the token hashes, the settings and the licence key (state.json), the audit log (audit.jsonl), the certificate and the agent's copy of the VyOS API key.

Step 5 — Restore the configuration#

This also restores the API key inside config.boot that the api-key file you just copied expects — which is why these two steps belong together.

bash
configure
load /tmp/config/config.boot
compare
commit
save
exit

To rename them in the configuration session, delete the old node and set the new one for each interface, then compare again before committing.

Step 6 — Start the agent and check it#

bash
sudo systemctl start wheelhouse-agent
curl -sk https://127.0.0.1:8443/health
sudo rm -rf /tmp/config /tmp/wheelhouse-*.tgz

{"status":"ok"} means the agent is up. It says nothing about whether the agent can reach the router — that is the next step.

Step 7 — Sign in#

Use your old admin account and password. Then check three things:

  1. The pages have data. If every page reports the router unreachable while the login screen works, the two copies of the VyOS API key have come from different backups. Compare them and fix config.boot or /config/wheelhouse/api-key so they match.
  2. The audit log shows your history. If it is empty, state.json did not come across.
  3. The certificate. If it came across, browsers that trusted the old box still trust this one. If you skipped it, everyone gets a fresh warning once.

Step 8 — Fix the licence#

The router's licence fingerprint is derived from /etc/machine-id, so a new machine is a new fingerprint, and the licence server counts it as an additional activation against your router limit. The key itself came across in state.json and keeps working.

The retired router's activation has to be released on the licence server by whoever issued your key. There is no button on the router for it. Contact <TODO: owner>.

Rebuild without a keyboard#

If you keep a config.boot — or a file of set commands — with your backups, the unattended installer applies it during the install, before it hands the machine back. That collapses steps 1 and 5 into one boot:

bash
tools/wheelhouse-seed.py --user-data seed.yaml --out seed.iso

with config: { boot: config.boot } in the cloud-config, and config.boot sitting beside seed.yaml so the tool copies it onto the seed. Full reference: Build a seed.

This restores the router configuration. The accounts, the audit log and the licence still come from steps 3 and 4.

Check it worked#

Beyond the three checks in step 7:

bash
# The interfaces the configuration declares all exist
show interfaces

# The forwarding table has a default route
show ip route 0.0.0.0/0

# The agent is talking to the router
curl -sk -H "Authorization: Bearer $T" https://127.0.0.1:8443/api/system | head -c 200

Then leave the old router powered off but intact for a week.

Undoing it#

There is nothing to undo — the new box is new. If the restore went wrong, wipe it by installing again from the ISO and start at step 1.

See also#


Checked against docs/backup-restore.md · agent/license.go · docs/security.md · tools/wheelhouse-seed.py

Updated 2026-09-02 restore backup hardware operations