try again

This commit is contained in:
RingOfStorms (Joshua Bell) 2025-12-16 15:45:00 -06:00
parent 2937e59e91
commit ebf2bc1540

View file

@ -256,132 +256,117 @@ lib.mkMerge [
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
KeyringMode = "shared"; KeyringMode = "shared";
# We need a path that includes standard tools (mkdir, mount, find, date, stat) Environment = "PATH=${
# and bcachefs tools.
# Environment = "PATH=${
# lib.makeBinPath [
# pkgs.coreutils
# pkgs.util-linux
# pkgs.findutils
# pkgs.gawk
# pkgs.bcachefs-tools
# pkgs.gnugrep
# ]
# }:/bin:/sbin";
};
script = ''
# This forces Nix to include these packages in the initrd closure
export PATH="${
lib.makeBinPath [ lib.makeBinPath [
pkgs.coreutils pkgs.coreutils
pkgs.util-linux pkgs.util-linux
pkgs.findutils # pkgs.findutils
pkgs.gawk # pkgs.gawk
pkgs.bcachefs-tools # pkgs.bcachefs-tools
pkgs.gnugrep
] ]
}:/bin:/sbin";
};
}:$PATH" script = ''
# 1. Enable Debugging # 1. Enable Debugging
set -x set -x
# 2. Define Cleanup Trap (Robust) # 2. Define Cleanup Trap (Robust)
cleanup() { cleanup() {
# If the script failed before creating the new root, make sure we create it # If the script failed before creating the new root, make sure we create it
if [[ ! -e /primary_tmp/@root ]]; then if [[ ! -e /primary_tmp/@root ]]; then
echo "Cleanup: Creating new @root" echo "Cleanup: Creating new @root"
bcachefs subvolume create /primary_tmp/@root bcachefs subvolume create /primary_tmp/@root
fi
# Robust replacement for 'mountpoint -q'
if grep -qs "/primary_tmp " /proc/mounts; then
echo "Cleanup: Unmounting /primary_tmp"
umount /primary_tmp
fi
}
trap cleanup EXIT
mkdir -p /primary_tmp
# If unlocked, mounts instantly. If locked, prompts for password on TTY.
echo "Mounting ${PRIMARY}..."
if ! mount "${PRIMARY}" /primary_tmp; then
echo "Mount failed. Cannot reset root."
exit 1
fi fi
# Robust replacement for 'mountpoint -q'
if ls /primary_tmp; then
echo "Cleanup: Unmounting /primary_tmp"
umount /primary_tmp
fi
}
trap cleanup EXIT
# 5. Snapshot & Prune Logic mkdir -p /primary_tmp
if [[ -e /primary_tmp/@root ]]; then
mkdir -p /primary_tmp/@snapshots/old_roots
# Use safe timestamp format (dashes instead of colons) # If unlocked, mounts instantly. If locked, prompts for password on TTY.
timestamp=$(date --date="@$(stat -c %Y /primary_tmp/@root)" "+%Y-%m-%d_%H-%M-%S") echo "Mounting ${PRIMARY}..."
if ! mount "${PRIMARY}" /primary_tmp; then
echo "Mount failed. Cannot reset root."
exit 1
fi
echo "Snapshotting @root to .../$timestamp" # 5. Snapshot & Prune Logic
bcachefs subvolume snapshot /primary_tmp/@root "/primary_tmp/@snapshots/old_roots/$timestamp" if [[ -e /primary_tmp/@root ]]; then
mkdir -p /primary_tmp/@snapshots/old_roots
echo "Deleting current @root" # Use safe timestamp format (dashes instead of colons)
bcachefs subvolume delete /primary_tmp/@root timestamp=$(date --date="@$(stat -c %Y /primary_tmp/@root)" "+%Y-%m-%d_%H-%M-%S")
# --- PRUNING LOGIC --- echo "Snapshotting @root to .../$timestamp"
echo "Pruning snapshots..." bcachefs subvolume snapshot /primary_tmp/@root "/primary_tmp/@snapshots/old_roots/$timestamp"
# Get list of snapshots sorted by name (which effectively sorts by date: YYYY-MM-DD...) echo "Deleting current @root"
# ls -r puts newest first bcachefs subvolume delete /primary_tmp/@root
snapshots=$(ls -1r /primary_tmp/@snapshots/old_roots | grep -E '^[0-9]{4}-[0-9]{2}-[0-9]{2}')
declare -A kept_weeks # --- PRUNING LOGIC ---
declare -A kept_months echo "Pruning snapshots..."
processed_count=0
for snap in $snapshots; do # Get list of snapshots sorted by name (which effectively sorts by date: YYYY-MM-DD...)
keep=false # ls -r puts newest first
snapshots=$(ls -1Ar /primary_tmp/@snapshots/old_roots)
# Parse date from filename (Replace _ with space for date command) declare -A kept_weeks
date_str=$(echo "$snap" | sed 's/_/ /') declare -A kept_months
processed_count=0
# Get metadata for snap in $snapshots; do
ts=$(date -d "$date_str" +%s) keep=false
week_id=$(date -d "$date_str" +%Y-W%U)
month_id=$(date -d "$date_str" +%Y-%m)
now=$(date +%s)
days_old=$(( (now - ts) / 86400 ))
# RULE 1: Keep 5 most recent (Always) # Parse date from filename (Replace _ with space for date command)
if [ $processed_count -lt 5 ]; then date_str=$(echo "$snap" | sed 's/_/ /')
# Get metadata
ts=$(date -d "$date_str" +%s)
week_id=$(date -d "$date_str" +%Y-W%U)
month_id=$(date -d "$date_str" +%Y-%m)
now=$(date +%s)
days_old=$(( (now - ts) / 86400 ))
# RULE 1: Keep 5 most recent (Always)
if [ $processed_count -lt 5 ]; then
keep=true
fi
# RULE 2: Weekly for last month (Age < 32 days)
# "at least 1 root from each week from the last month"
if [ $days_old -le 32 ]; then
if [ -z "''${kept_weeks[$week_id]}" ]; then
keep=true keep=true
kept_weeks[$week_id]=1
fi fi
fi
# RULE 2: Weekly for last month (Age < 32 days) # RULE 3: Monthly for older snapshots
# "at least 1 root from each week from the last month" # "at least 1 root from a month ago" (implies monthly retention indefinitely)
if [ $days_old -le 32 ]; then if [ $days_old -gt 32 ]; then
if [ -z "''${kept_weeks[$week_id]}" ]; then if [ -z "''${kept_months[$month_id]}" ]; then
keep=true keep=true
kept_weeks[$week_id]=1 kept_months[$month_id]=1
fi
fi fi
fi
# RULE 3: Monthly for older snapshots if [ "$keep" = true ]; then
# "at least 1 root from a month ago" (implies monthly retention indefinitely) echo "Keeping: $snap"
if [ $days_old -gt 32 ]; then else
if [ -z "''${kept_months[$month_id]}" ]; then echo "Deleting: $snap"
keep=true bcachefs subvolume delete "/primary_tmp/@snapshots/old_roots/$snap"
kept_months[$month_id]=1 fi
fi
fi
if [ "$keep" = true ]; then processed_count=$((processed_count + 1))
echo "Keeping: $snap" done
else fi
echo "Deleting: $snap"
bcachefs subvolume delete "/primary_tmp/@snapshots/old_roots/$snap"
fi
processed_count=$((processed_count + 1)) # Trap handles creating new root and unmount
done
fi
# Trap handles creating new root and unmount
''; '';
}; };
}) })