Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions docs/ARCHITECTURE-ARTIFACTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ filling the rest of the disk. The differences are:

The BTRFS filesystem always carries two subvolumes: `@` mounted at `/`,
and `@postgres` mounted at `/var/lib/postgresql`. Both are quota'd via
BTRFS simple quotas and snapshotted by snapper (6 hourly + 10 numbered).
The runtime mode (`plain`, `luks-keyfile`, or `luks-tpm`) is recorded in
`/etc/bes/image-variant`, which the installer overwrites for non-Pi
variants.
BTRFS simple quotas. The runtime mode (`plain`, `luks-keyfile`, or
`luks-tpm`) is recorded in `/etc/bes/image-variant`, which the installer
overwrites for non-Pi variants.
3 changes: 0 additions & 3 deletions docs/GUIDE-IMAGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,5 @@ Simple quotas are enabled to track per-subvolume disk usage.

Transparent filesystem compression is enabled system-wide.

The Snapper snapshot manager is enabled by default, which takes hourly snapshots of the subvolumes and retains the last 6 hourly snapshots, plus up to 10 numbered (manual / pre-/post-) snapshots.
This provides a simple way to rollback a server or a file to an earlier configuration and protects against catastrophes.

The system partition can be grown or shrunk while online.
Shrinking is a manual process, but growing is performed automatically if more space is available at first boot.
1 change: 0 additions & 1 deletion docs/diagrams/disk-image-layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,5 @@ def variant(label: str, *, encrypted: bool, pi: bool):
with Cluster("Annotations"):
notes = Document(
"compress=zstd:6,\nxxhash, simple\nquotas, block-group-tree.\n"
"Snapper: 6 hourly +\n10 numbered\non / and /var/lib/postgresql.\n"
"/etc/bes/image-variant\nrecords runtime mode:\nplain | luks-keyfile |\nluks-tpm."
)
16 changes: 0 additions & 16 deletions docs/spec/disk-images.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,22 +367,6 @@ A weekly cron job must be present to run `apt install -y tailscale`.
> not require that service to succeed. The service must additionally be
> ordered after `network-online.target` and `local-fs.target`.

## Snapper

r[image.snapper.root]
Snapper must be configured for the root subvolume (`/`) with timeline
snapshots enabled and retention of 6 hourly snapshots, plus 10 numbered
(non-timeline) snapshots. Daily, weekly, monthly, and yearly timeline
retention must be disabled.

r[image.snapper.postgres]
Snapper must be configured for the PostgreSQL subvolume
(`/var/lib/postgresql`) with the same retention settings as the root config.

r[image.snapper.timers]
The `snapper-timeline.timer` and `snapper-cleanup.timer` systemd timers must
be enabled.

## Disk Growth

> r[image.growth.service+3]
Expand Down
8 changes: 1 addition & 7 deletions image/configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#
# It expects the following to be available under /tmp/:
# /tmp/packages.sh — package list (sourced as bash)
# /tmp/scripts/ — setup scripts (firewall, tailscale, snapper, etc.)
# /tmp/scripts/ — setup scripts (firewall, tailscale, etc.)
# /tmp/files/ — static files to install
set -euo pipefail

Expand Down Expand Up @@ -387,12 +387,6 @@ systemctl enable ssh
install -m 644 /tmp/files/systemd/bes-ssh-keygen.service /etc/systemd/system/bes-ssh-keygen.service
systemctl enable bes-ssh-keygen.service

# ============================================================
# Snapper
# ============================================================
# r[image.snapper.root] r[image.snapper.postgres] r[image.snapper.timers]
bash /tmp/scripts/setup-snapper.sh

# ============================================================
# Disk growth service
# ============================================================
Expand Down
1 change: 0 additions & 1 deletion image/packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ PACKAGES=(
# Filesystem and storage
btrfs-progs
cryptsetup
snapper
gdisk
mtools

Expand Down
37 changes: 0 additions & 37 deletions image/scripts/setup-snapper.sh

This file was deleted.

2 changes: 0 additions & 2 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -706,8 +706,6 @@ _make-test-cloud-init: _ensure-dirs
check "ufw is active" systemctl is-active ufw
# r[verify image.tailscale.service-enabled]
check "tailscaled is active" systemctl is-active tailscaled
# r[verify image.snapper.timers]
check "snapper-timeline.timer is active" systemctl is-active snapper-timeline.timer
# r[verify image.growth.service]
check "grow-root-filesystem ran" systemctl show -p ActiveState grow-root-filesystem.service | grep -q inactive

Expand Down
1 change: 0 additions & 1 deletion tests/test-e2e-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ runcmd:
check "sshd is active" systemctl is-active ssh
check "ufw is active" systemctl is-active ufw
check "tailscaled is active" systemctl is-active tailscaled
check "snapper-timeline.timer is active" systemctl is-active snapper-timeline.timer

check "root is btrfs" test "$(stat -f -c%T /)" = "btrfs"
check "compression active in /proc/mounts" grep -q 'compress=' /proc/mounts
Expand Down
40 changes: 0 additions & 40 deletions tests/test-image-structure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -501,42 +501,6 @@ check_not "installer network config absent" test -f "$MNT/etc/cloud/cloud.cfg.d/

check_not "unminimize prompt absent" test -f "$MNT/etc/update-motd.d/60-unminimize"

# ============================================================
# Snapper configuration
# ============================================================
echo ""
echo "--- Snapper ---"

# r[verify image.snapper.root]
SNAPPER_ROOT_CFG="$MNT/etc/snapper/configs/root"
check "snapper root config exists" test -f "$SNAPPER_ROOT_CFG"
if [ -f "$SNAPPER_ROOT_CFG" ]; then
check "snapper root: TIMELINE_CREATE=yes" grep -q '^TIMELINE_CREATE="yes"' "$SNAPPER_ROOT_CFG"
check "snapper root: TIMELINE_CLEANUP=yes" grep -q '^TIMELINE_CLEANUP="yes"' "$SNAPPER_ROOT_CFG"
check "snapper root: NUMBER_CLEANUP=yes" grep -q '^NUMBER_CLEANUP="yes"' "$SNAPPER_ROOT_CFG"
check "snapper root: NUMBER_LIMIT=10" grep -q '^NUMBER_LIMIT="10"' "$SNAPPER_ROOT_CFG"
check "snapper root: TIMELINE_LIMIT_HOURLY=6" grep -q '^TIMELINE_LIMIT_HOURLY="6"' "$SNAPPER_ROOT_CFG"
check "snapper root: TIMELINE_LIMIT_DAILY=0" grep -q '^TIMELINE_LIMIT_DAILY="0"' "$SNAPPER_ROOT_CFG"
check "snapper root: TIMELINE_LIMIT_WEEKLY=0" grep -q '^TIMELINE_LIMIT_WEEKLY="0"' "$SNAPPER_ROOT_CFG"
check "snapper root: TIMELINE_LIMIT_MONTHLY=0" grep -q '^TIMELINE_LIMIT_MONTHLY="0"' "$SNAPPER_ROOT_CFG"
check "snapper root: TIMELINE_LIMIT_YEARLY=0" grep -q '^TIMELINE_LIMIT_YEARLY="0"' "$SNAPPER_ROOT_CFG"
fi

# r[verify image.snapper.postgres]
SNAPPER_PG_CFG="$MNT/etc/snapper/configs/postgres"
check "snapper postgres config exists" test -f "$SNAPPER_PG_CFG"
if [ -f "$SNAPPER_PG_CFG" ]; then
check "snapper postgres: TIMELINE_CREATE=yes" grep -q '^TIMELINE_CREATE="yes"' "$SNAPPER_PG_CFG"
check "snapper postgres: TIMELINE_CLEANUP=yes" grep -q '^TIMELINE_CLEANUP="yes"' "$SNAPPER_PG_CFG"
check "snapper postgres: NUMBER_CLEANUP=yes" grep -q '^NUMBER_CLEANUP="yes"' "$SNAPPER_PG_CFG"
check "snapper postgres: NUMBER_LIMIT=10" grep -q '^NUMBER_LIMIT="10"' "$SNAPPER_PG_CFG"
check "snapper postgres: TIMELINE_LIMIT_HOURLY=6" grep -q '^TIMELINE_LIMIT_HOURLY="6"' "$SNAPPER_PG_CFG"
check "snapper postgres: TIMELINE_LIMIT_DAILY=0" grep -q '^TIMELINE_LIMIT_DAILY="0"' "$SNAPPER_PG_CFG"
check "snapper postgres: TIMELINE_LIMIT_WEEKLY=0" grep -q '^TIMELINE_LIMIT_WEEKLY="0"' "$SNAPPER_PG_CFG"
check "snapper postgres: TIMELINE_LIMIT_MONTHLY=0" grep -q '^TIMELINE_LIMIT_MONTHLY="0"' "$SNAPPER_PG_CFG"
check "snapper postgres: TIMELINE_LIMIT_YEARLY=0" grep -q '^TIMELINE_LIMIT_YEARLY="0"' "$SNAPPER_PG_CFG"
fi

# ============================================================
# UFW firewall rules
# ============================================================
Expand Down Expand Up @@ -721,10 +685,6 @@ check_service_enabled "bes-tailscale-firstboot-auth.service" "bes-tailscale-firs
# r[verify image.firstboot.script]
check_service_enabled "bes-firstboot-script.service" "bes-firstboot-script is enabled"

# r[verify image.snapper.timers]
check_service_enabled "snapper-timeline.timer" "snapper-timeline.timer is enabled"
check_service_enabled "snapper-cleanup.timer" "snapper-cleanup.timer is enabled"

# r[verify image.growth.service+3]
check_service_enabled "grow-root-filesystem.service" "grow-root-filesystem is enabled"

Expand Down
Loading