Skip to content

Take a machine's registrations and rules somewhere else - #69

Merged
vxnsin merged 1 commit into
mainfrom
a-machine-that-can-move
Sep 7, 2026
Merged

vxnsin merged 1 commit into
mainfrom
a-machine-that-can-move

Conversation

@vxnsin

@vxnsin vxnsin commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Closes #61.

Registrations and firewall rules live in one SQLite file, so rebuilding a machine meant either losing them or copying that file — which also carries the history, the snapshots, and whatever schema version that warden happened to be on.

warden state export > machine.json
warden state import machine.json --dry-run
warden state import machine.json

What does not travel

  • The history. It is a record of what happened on that machine and means nothing on another one.
  • The snapshots. A snapshot is some other firewall's ruleset, and restoring one onto a different machine is the single thing this whole design exists to make impossible by accident. That one is not a nicety.

It lands a row at a time

$ warden state import machine.json --dry-run
  service  docs
  rule     allow-ssh
  skipped  shop-api - already registered here
  skipped  allow-8443 - already written down here

2 would land, 2 would not - nothing was written

A name already registered here, or a port this machine does not hand out, is one row's problem rather than a reason to refuse the other forty — and every row that does not land is named.

Flag
--dry-run Say what would land, and land nothing
--any-port Let a service whose port is outside this machine's pool take a free one

The pool belongs to the machine, so an imported registration does not get to widen it. --any-port is the other right answer on a different day.

Rules land written down, not applied, and the import says so rather than letting somebody assume otherwise — the same gap #57 is about, said the same way.

The shape

The file carries a shape number and the version that wrote it. A file from a later warden is refused by name instead of read hopefully. The field exists so that the first time the shape changes is not the first time anybody thinks about it.

701 → 712 tests.

Both live in one SQLite file, so rebuilding a machine meant either losing them
or copying that file - which also carries the history, the snapshots, and
whatever schema version that warden happened to be on.

`warden state export` writes what somebody wrote down: which services hold
which ports, and which rules decide what crosses. The history stays where it
happened, because it is a record of that machine and means nothing on another
one. The snapshots stay too, and that one is not a nicety: a snapshot is some
other firewall's ruleset, and restoring one onto a different machine is the
single thing this whole design exists to make impossible by accident.

`warden state import` lands a row at a time. A name already registered here, or
a port this machine does not hand out, is one row's problem rather than a reason
to refuse the other forty - and every row that does not land is named. The pool
belongs to the machine, so an imported registration does not get to widen it;
`--any-port` says to take a free one instead, which is the other right answer on
a different day.

`--dry-run` says all of it and writes nothing, which is the reason somebody runs
an import against a machine they care about at all.

Rules land written down and not applied, and the import says so rather than
letting somebody assume otherwise.

The file carries a shape number and the version that wrote it. A file from a
later warden is refused by name instead of read hopefully - the field exists so
that the first time the shape changes is not the first time anybody thinks about
it.

Closes #61
@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 24 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: aae3b9ae-ba63-4647-ade3-b17afa62a78f

📥 Commits

Reviewing files that changed from the base of the PR and between 7f83622 and d164b53.

📒 Files selected for processing (5)
  • README.md
  • src/warden/cli/commands/admin.py
  • src/warden/core/moving.py
  • tests/test_cli.py
  • tests/test_moving.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@vxnsin
vxnsin merged commit 47978b9 into main Sep 7, 2026
12 checks passed
@vxnsin
vxnsin deleted the a-machine-that-can-move branch September 8, 2026 05:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Moving a machine means copying a database file

1 participant