Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

0006 — Snapshot naming convention, autosnapshot tool, and TZ surfacing

Status: accepted (2026-06-22) — ratified by maintainer; proposed 2026-06-04

Context

keyboot’s pre-boot rollback UI (ADR 0007) needs snapshots that it can (a) read unambiguously during recovery, (b) sort chronologically for retention, (c) group into a consistent point-in-time across the recursive dataset set, and (d) show to a human. A cross-distro userland tool (Debian/Alpine/Gentoo) creates them; the name is an interface contract between that tool and keyboot.

Decision

Name: <dataset>@<YYYY-MM-DD-HHMM>Z-<LABEL>UTC, with an explicit Z, 24-hour. LABEL ∈ {FREQUENT, HOURLY, DAILY, WEEKLY, MONTHLY} (the zfs-auto-snapshot model). Example: rpool/ROOT/gentoo@2026-06-04-1600Z-DAILY.

  • UTC, not local. Local time is non-monotonic across DST (the fall-back hour repeats), which breaks lexical-sort retention and “keep newest N”, and is ambiguous exactly when you’re recovering. UTC names sort lexically == chronologically, making retention a trivial correct sort | head -n -N | xargs zfs destroy. The Z removes the “is 1600 UTC?” ambiguity at a glance.

Recursive + lockstep. Snapshots are taken zfs snapshot -r over the BE subtree so every dataset shares the name atomically (same txg) — a point-in-time is always complete. Retention/purge is recursive on matching names so no per-child snapshot is orphaned (which would leave a rollback with a hole). Per-LABEL retention counts (--keep=N), cron- or timer-driven.

The tool. A cross-distro POSIX-sh utility ships snap/list/purge verbs, driven by cron (Alpine busybox-crond / Gentoo cronie / Debian) or systemd timers where present. Installed by the install-os plugins (or a keyboot package). It is the blessed snapshot path. The zfs binary is not shimmed to force naming (that would break zfs send/sanoid/replication, ADR 0004); at most a warn-only hint on non-conforming manual snaps.

TZ surfacing (UTC on disk, local at display). Names stay UTC (source of truth, always shown); keyboot additionally renders operator-local time. Chain:

  1. The BE carries a configured timezone (zone name, e.g. America/Chicago). → Requirement: install-os sets/captures a TZ on the BE.
  2. install-os records the zone into keyboot’s /etc/keyboot/host.conf on the ESP (timezone=America/Chicago).
  3. keyboot bundles tzdata (zoneinfo) in its initramfs.
  4. The menu renders 2026-06-04 16:00Z (11:00 America/Chicago).

DST-correct local display needs the zone name + tzdata, not a fixed offset (a fixed offset is wrong half the year — the very confusion we’re removing).

Contract. The naming scheme is a versioned interface between the snapshotter and keyboot; changing it requires a superseding ADR.

Alternatives considered

  • Local-time names: friendlier in isolation, but DST-ambiguous + non-monotonic → breaks retention and recovery reading. Rejected; local is a display-time convenience only.
  • Fixed UTC-offset display (no tzdata): avoids bundling zoneinfo but is wrong across DST. Rejected; bundle tzdata.
  • Shim zfs snapshot to enforce the convention: breaks replication / sanoid / zfs send / our own tool. Rejected (warn-only at most).

Consequences

  • keyboot’s initramfs grows by tzdata (small, version-matched to the zoneinfo release).
  • host.conf gains a timezone= field; install-os must write it; the BE must have a timezone set (a new install step / profile field).
  • Non-conforming snapshots (replication, manual) still display by UTC mtime fallback; only conforming names group into the DAILY/WEEKLY point-in-time tiers in the menu.
  • The recursive-set naming is what ADR 0007’s clone/rollback verbs key off — this ADR is load-bearing for those.