#!/usr/bin/env bash set -Eeo pipefail trap 's=$?; echo >&2 "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $s' ERR declare -r PATH_TO_SNAPSHOT_DIRECTORY='/.snapshots' declare -r MAX_AGE_DAYS=14 declare -r SECONDS_IN_DAY=$((24 * 60 * 60)) function update { local snapshot_name snapshot_name=$(date --iso-8601=seconds) local path_to_snapshot="${PATH_TO_SNAPSHOT_DIRECTORY}/${snapshot_name}" btrfs subvolume snapshot -r / "${path_to_snapshot}" su --shell /bin/sh --command 'paru -Syu --noconfirm --noprogressbar' system-updater } function cleanup_snapshots { function get_file_age_days { local file_name=$1 local current_date_epoch current_date_epoch=$(date +%s) local file_creation_date_epoch file_creation_date_epoch=$(date --date="${file_name}" +%s) local file_age_days=$(( (current_date_epoch - file_creation_date_epoch) / SECONDS_IN_DAY )) printf '%u' "${file_age_days}" } for path_to_snapshot in $(find ${PATH_TO_SNAPSHOT_DIRECTORY}/* -prune -print | sort -r); do local snapshot_name snapshot_name=$(basename "${path_to_snapshot}") local age_days age_days=$(get_file_age_days "${snapshot_name}") if [ "${age_days}" -lt ${MAX_AGE_DAYS} ]; then printf "Skipping '%s'. Age in days is %u\n" "${path_to_snapshot}" "${age_days}" else btrfs subvolume delete "${path_to_snapshot}" fi done } if [ "${EUID}" -ne 0 ]; then printf 'You must run the script with root privileges\n' exit 1 fi case "${1}" in '--update') update cleanup_snapshots ;; '--cleanup') cleanup_snapshots ;; *) printf 'Usage: system-update options\n' printf '\n' printf 'Options:\n' printf ' --update Create btrfs snapshot of root subvolume, update system using paru, cleanup snapshots\n' printf ' --cleanup Cleanup snapshots\n\n' printf '\n' ;; esac