Releases: realmcuser/nspawn-vault
Release list
Release nspawn-vault-web-v0.1.0-26
nspawn-vault-web v0.1.0-26
Fixes a real race condition in how config files are written
(notify.conf, gfs.conf, <host>/containers, <host>/notify-email).
Every writer now goes through a temp-file + atomic rename
(os.replace()) instead of writing straight onto the target file in
place. The previous approach truncated the existing file before writing
the new content, leaving a narrow window where a concurrent reader -
check-stale.sh's 30-minute timer sourcing notify.conf, or an admin
clicking "send test email" right as a settings save is in flight - could
read a half-written file.
Why
Found live while setting up the new SMTP relay from v0.1.0-25: several
"send test email" attempts returned an intermittent curl "login denied",
some immediately following an Admin save. Config writes weren't atomic,
so a reader could occasionally catch the file mid-rewrite.
Verified
- A 200-write/4000-read concurrent stress test locally: zero partial
reads with the fix, reproducible torn reads without it. - Re-ran the existing shell-quoting injection test against the
refactored write path - still inert. - Live on the production vault: repeated test-email sends immediately
after saving settings, no further curl "login denied" errors.
Release nspawn-vault-web-v0.1.0-25
nspawn-vault-web v0.1.0-25
Adds the Admin-side half of the new email alert channel introduced in
nspawn-vault v1.0.0-11: SMTP relay configuration, a "send test
email" button, and a per-source-host recipients editor.
- New SMTP relay fields in the Notifications section (host, port,
STARTTLS/implicit TLS, from address, optional username/password) -
secrets follow the existing********sentinel convention, never
echoed back in plaintext. - Send test email fires a real email synchronously via the engine's
send-email.shand shows the result inline - same pattern as the
existing LDAP/SSH "test connection" buttons, so setting up the relay
doesn't mean waiting for a real dead-man's-switch trigger to find out
it's misconfigured. - New per-host email recipients editor next to the existing container
list editor in the Source Hosts table, validated server-side before
ever touching disk (same pattern as hostname/container name
validation).
Why
Companion to the engine-side email alert work - lets an admin configure
and verify the SMTP relay from the dashboard instead of hand-editing
notify.conf and <host>/notify-email over SSH.
Verified live
Installed on the production vault (nspawn-vault.vpn.fhd.se) and sent
real test emails end to end through a live SMTP relay to two different
real addresses - confirmed delivered.
Release nspawn-vault-v1.0.0-11
nspawn-vault v1.0.0-11
Adds email as a third dead-man's-switch alert channel, alongside the
existing Pushover and Slack alerts. Pushover/Slack stay exactly as they
were (one shared config for the whole vault); email adds per-source-host
recipients against a single shared SMTP relay, since a large fleet needs
different people notified about different source hosts, not one global
recipient list.
- New
SMTP_HOST/SMTP_PORT/SMTP_TLS_MODE/SMTP_USER/SMTP_PASS
/SMTP_FROMkeys innotify.conf(STARTTLS on 587 or implicit TLS on
465, both configurable). - New per-host recipients file:
/etc/nspawn-vault/<host>/notify-email,
one address per line. - New
usr/libexec/nspawn-vault/send-email.sh, a curl-based SMTP sender
shared bycheck-stale.shand nspawn-vault-web's new "send test email"
admin button. check-stale.shnow loops configured hosts/containers instead of
globbing state files directly - needed to know which host a container
belongs to (the state filename alone can't be split back into an
unambiguous host/container pair). Existing per-container Pushover/Slack
alerts are unchanged; email is batched one message per host listing
every problem container, instead of one email per container, to avoid
flooding recipients across a large fleet.
Why
Built for a fleet of roughly 200 source hosts. A single flat alert
recipient list stops working at that scale - different teams/people care
about different hosts, and email is the lowest common denominator every
admin can receive without extra setup.
Verified live
Ran the rewritten check-stale.sh against real production config and
state data on nspawn-vault.vpn.fhd.se (besten.alsike.minten.se,
knorrhane2.alsike.minten.se) - identical OK/ALERT results to before the
rewrite. Also live-tested the shell-quoting on the new SMTP_PASS field
with a $()/backtick injection payload (same class of protection as the
existing Pushover/Slack secrets) - confirmed inert.
Release nspawn-vault-zfs-bootstrap-v0.1.0-7
Release nspawn-vault-zfs-bootstrap-v0.1.0-7
nspawn-vault-web v0.1.0-24
nspawn-vault-web v0.1.0-24
Adds a manual "Run prune now" button to the Admin GFS Retention
section - starts nspawn-vault-prune.service immediately instead of
waiting for its daily 04:00 timer.
Why
Same reasoning as the existing per-host "Run now" pull trigger: useful
right after changing GFS retention settings and wanting to see the effect
immediately, or to reclaim storage proactively instead of waiting
overnight. The operation itself isn't new or risky - it's the exact same
GFS policy that already runs automatically every night, just triggered on
demand.
Verified live
Triggered a real prune run against the production vault: a container's
snapshot count dropped from 41 to 27 immediately, matching exactly what
the retention figures added in v0.1.0-23 predicted it would.
Release nspawn-vault-v1.0.0-10
Release nspawn-vault-v1.0.0-10
nspawn-vault-web v0.1.0-23
nspawn-vault-web v0.1.0-23
Adds a per-container snapshot-retention figure to the HostDetail table:
the current snapshot count, plus how many would remain after the next
GFS prune run.
Why
Prompted by a real question: is 40 stored snapshots for one container too
many? It wasn't — 12 of them were already due for the next nightly prune,
just not cleaned up yet since nspawn-vault-prune.timer only runs once a
day. There was no way to see that in the UI before this without SSHing in
and doing the same check by hand.
How it works
vault_zfs.snapshot_retention() shells out to the exact same gfs.py
that the real prune timer calls, rather than reimplementing its bucket
logic. That matters: the naive GH+GD+GW+GM+GY sum is not the right
number here, since a recent snapshot can satisfy several retention
buckets (hour/day/week/...) at once — the real algorithm has to run to
get a correct answer, not just add up the config values.
The new "Snapshots" column shows a single number when a container is
already at its target count, or current / retained with a tooltip when
there's a difference — e.g. 40 / 28 for a container that's due for
pruning at the next run.