From 402913efb3122047b453ea43a24788df09e5ebad Mon Sep 17 00:00:00 2001 From: sjat Date: Sat, 6 Jun 2026 19:15:38 +0200 Subject: [PATCH] fix(base): make rollback snapshot restorable (flush-prefixed) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bare 'nft list ruleset' has no leading flush, so the timer's 'nft -f rollback' was a no-op on first apply (empty file) and errored ('table exists') on later applies — the auto-rollback silently did nothing, defeating the askari lockout safeguard. Prepend 'flush ruleset' so the revert is atomic + self-contained. Verified the snapshot->lockout->revert round-trip in an isolated netns. Also fix stale STATUS prose (base is partially built, not absent). --- STATUS.md | 4 ++-- roles/base/tasks/firewall.yml | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/STATUS.md b/STATUS.md index 32f99b8..8a4a689 100644 --- a/STATUS.md +++ b/STATUS.md @@ -36,8 +36,8 @@ _Last reviewed: 2026-06-06._ | `inventories/*/hosts.yml` | Structured stubs with empty host maps (`hosts: {}`); regenerated by `make tf-inventory` once Terraform has hosts | | `inventories/production/group_vars/{docker_hosts,proxmox_hosts}/` | Empty dirs | -So `make deploy PLAYBOOK=site` currently **fails** on a clean clone — the `base` and -`docker_host` roles it calls do not exist yet. +So `make deploy PLAYBOOK=site` is still incomplete — `base` is only partially built (its +`firewall` concern only) and the `docker_host` role does not exist yet. ## Designed but not built diff --git a/roles/base/tasks/firewall.yml b/roles/base/tasks/firewall.yml index 0045e61..d9fa6ae 100644 --- a/roles/base/tasks/firewall.yml +++ b/roles/base/tasks/firewall.yml @@ -36,7 +36,11 @@ tags: [firewall] block: - name: Snapshot the current ruleset as the rollback point - ansible.builtin.shell: "nft list ruleset > /etc/nftables.rollback" + # Prepend `flush ruleset` so the revert is atomic and self-contained: on a + # first-ever apply the snapshot is just `flush ruleset` (reverts to an empty, + # kernel-default-accept state → reachable); on later applies it avoids + # "table exists" errors when replayed. Without the flush the rollback is a no-op. + ansible.builtin.shell: "{ echo 'flush ruleset'; nft list ruleset; } > /etc/nftables.rollback" changed_when: false - name: Stop stale rollback timer unit