feat(base): Add snapper setup stack

Creates separate snapper services for root and home directories. Does
_not_ yet set up any btrfs mounts or ensure that they are mounted at the
locations.
This commit is contained in:
Marty Oehme 2025-02-26 14:47:49 +01:00
parent 1691e0402c
commit e112bb3078
Signed by: Marty
GPG key ID: 4E535BC19C61886E
4 changed files with 182 additions and 0 deletions
books
templates/snapper-configurations
void_base.yaml
inventory_local.yaml

View file

@ -0,0 +1,55 @@
# subvolume to snapshot
SUBVOLUME="/home"
# filesystem type
FSTYPE="btrfs"
# btrfs qgroup for space aware cleanup algorithms
QGROUP=""
# fraction or absolute size of the filesystems space the snapshots may use
SPACE_LIMIT="0.5"
# fraction or absolute size of the filesystems space that should be free
FREE_LIMIT="0.2"
# users and groups allowed to work with config
ALLOW_USERS="{{ user_name }}"
ALLOW_GROUPS=""
# sync users and groups from ALLOW_USERS and ALLOW_GROUPS to .snapshots
# directory
SYNC_ACL="no"
# start comparing pre- and post-snapshot in background after creating
# post-snapshot
BACKGROUND_COMPARISON="yes"
# run daily number cleanup
NUMBER_CLEANUP="yes"
# limit for number cleanup
NUMBER_MIN_AGE="1800"
NUMBER_LIMIT="4"
NUMBER_LIMIT_IMPORTANT="2"
# create hourly snapshots
TIMELINE_CREATE="yes"
# cleanup hourly snapshots after some time
TIMELINE_CLEANUP="yes"
# limits for timeline cleanup
TIMELINE_MIN_AGE="1800"
TIMELINE_LIMIT_HOURLY="10"
TIMELINE_LIMIT_DAILY="2"
TIMELINE_LIMIT_WEEKLY="1"
TIMELINE_LIMIT_MONTHLY="1"
TIMELINE_LIMIT_QUARTERLY="0"
TIMELINE_LIMIT_YEARLY="0"
# cleanup empty pre-post-pairs
EMPTY_PRE_POST_CLEANUP="yes"
# limits for empty pre-post-pair cleanup
EMPTY_PRE_POST_MIN_AGE="1800"

View file

@ -0,0 +1,55 @@
# subvolume to snapshot
SUBVOLUME="/"
# filesystem type
FSTYPE="btrfs"
# btrfs qgroup for space aware cleanup algorithms
QGROUP=""
# fraction or absolute size of the filesystems space the snapshots may use
SPACE_LIMIT="0.5"
# fraction or absolute size of the filesystems space that should be free
FREE_LIMIT="0.2"
# users and groups allowed to work with config
ALLOW_USERS="{{ user_name }}"
ALLOW_GROUPS=""
# sync users and groups from ALLOW_USERS and ALLOW_GROUPS to .snapshots
# directory
SYNC_ACL="no"
# start comparing pre- and post-snapshot in background after creating
# post-snapshot
BACKGROUND_COMPARISON="yes"
# run daily number cleanup
NUMBER_CLEANUP="yes"
# limit for number cleanup
NUMBER_MIN_AGE="1800"
NUMBER_LIMIT="6"
NUMBER_LIMIT_IMPORTANT="4"
# create hourly snapshots
TIMELINE_CREATE="yes"
# cleanup hourly snapshots after some time
TIMELINE_CLEANUP="yes"
# limits for timeline cleanup
TIMELINE_MIN_AGE="1800"
TIMELINE_LIMIT_HOURLY="6"
TIMELINE_LIMIT_DAILY="5"
TIMELINE_LIMIT_WEEKLY="2"
TIMELINE_LIMIT_MONTHLY="1"
TIMELINE_LIMIT_QUARTERLY="1"
TIMELINE_LIMIT_YEARLY="0"
# cleanup empty pre-post-pairs
EMPTY_PRE_POST_CLEANUP="yes"
# limits for empty pre-post-pair cleanup
EMPTY_PRE_POST_MIN_AGE="1800"

View file

@ -131,3 +131,74 @@
state: link
with_items: [chronyd]
listen: installed-chrony
- name: Set up snapper backups
hosts: target_system
become: true
tags:
- btrfs
- snapshots
tasks:
- name: Install snapper
community.general.xbps:
name:
- snapper
state: present
notify: installed-snapper
# https://wiki.archlinux.org/title/Snapper#updatedb
- name: Disable updatedb indexing for snapshot directories
ansible.builtin.copy:
content: 'PRUNENAMES = ".snapshots"'
dest: "/etc/updatedb.conf"
owner: root
group: root
mode: 0644
force: true
- name: Ensure snapper configs directory exists
ansible.builtin.file:
dest: "/etc/snapper/configs"
state: directory
recurse: true
- name: Ensure root /.snapshots directory exists
ansible.builtin.file:
dest: "/.snapshots"
state: directory
mode: 0755
- name: Create root backup configuration
ansible.builtin.template:
src: snapper-configurations/root.j2
dest: "/etc/snapper/configs/root"
mode: 0640
force: true # ensure contents are always exact
- name: Ensure home /.snapshots directory exists
ansible.builtin.file:
dest: "/home/.snapshots"
state: directory
mode: 0755
- name: Create homedir backup configuration
ansible.builtin.template:
src: snapper-configurations/home.j2
dest: "/etc/snapper/configs/home"
mode: 0640
force: true
handlers:
# # Do NOT activate the snapperd service -
# # on systems without elogind I guess? Unsure
# - name: Activate snapper service
# ansible.builtin.file:
# force: "yes"
# src: "/etc/sv/snapperd"
# dest: "/etc/runit/runsvdir/default/snapperd"
# state: link
# listen: installed-snapper
- name: Snapper handler stub
ansible.builtin.debug:
msg: ""
listen: installed-snapper

View file

@ -116,6 +116,7 @@ terminal:
- restic
- ripgrep
- sc-im
- snooze
- starship
- swaybg
- swayidle