Feat: Automatische Timeshift Boot- und APT-Update-Snapshots sowie Retention-Limit konfiguriert
Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
@@ -138,7 +138,9 @@ Dieses Repository ist ein modulares, automatisiertes Setup- und Konfigurations-F
|
|||||||
- `is_root_subvolume_configured`: Prüft, ob Root bereits in einem Subvolume (`@`) läuft.
|
- `is_root_subvolume_configured`: Prüft, ob Root bereits in einem Subvolume (`@`) läuft.
|
||||||
- `update_btrfs_fstab "fstab_file" "root_id"`: Aktualisiert Mount-Optionen in `/etc/fstab` für `@` und `@home`.
|
- `update_btrfs_fstab "fstab_file" "root_id"`: Aktualisiert Mount-Optionen in `/etc/fstab` für `@` und `@home`.
|
||||||
- `check_and_setup_btrfs_subvolumes`: Erkennt flache Btrfs-Root-Volumes und migriert `/` und `/home` transparent in Subvolumes `@` und `@home`.
|
- `check_and_setup_btrfs_subvolumes`: Erkennt flache Btrfs-Root-Volumes und migriert `/` und `/home` transparent in Subvolumes `@` und `@home`.
|
||||||
- `ensure_timeshift_btrfs_config`: Erstellt bzw. initialisiert die Timeshift-Btrfs-Konfiguration (`/etc/timeshift/timeshift.json`) für die Root-UUID.
|
- `ensure_timeshift_btrfs_config`: Erstellt bzw. initialisiert die Timeshift-Btrfs-Konfiguration (`/etc/timeshift/timeshift.json`, automatische Boot-Snapshots, Retention auf 5 Snapshots) für die Root-UUID.
|
||||||
|
- `ensure_timeshift_boot_service`: Richtet den `timeshift-boot.service` und Cron-Einträge für automatische Boot-Snapshots ein.
|
||||||
|
- `ensure_timeshift_apt_hook`: Richtet einen DPkg/APT-Hook (`/etc/apt/apt.conf.d/80timeshift-auto-snapshot` und `/usr/local/bin/timeshift-apt-hook`) für automatische Snapshots vor System-Updates ein.
|
||||||
- `create_timeshift_snapshot "comment" [tags]`: Erstellt einen Timeshift-Btrfs-Snapshot an kritischen Setup-Meilensteinen (idempotent, steuerbar über `ENABLE_TIMESHIFT_SNAPSHOTS` in `config/setup.conf`).
|
- `create_timeshift_snapshot "comment" [tags]`: Erstellt einen Timeshift-Btrfs-Snapshot an kritischen Setup-Meilensteinen (idempotent, steuerbar über `ENABLE_TIMESHIFT_SNAPSHOTS` in `config/setup.conf`).
|
||||||
|
|
||||||
### `lib/tui.sh`
|
### `lib/tui.sh`
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ sudo ./setup.sh --stages 04,05
|
|||||||
3. **Idempotenz, Backups & Timeshift Btrfs-Snapshots**:
|
3. **Idempotenz, Backups & Timeshift Btrfs-Snapshots**:
|
||||||
- Alle Phasen können beliebig oft wiederholt werden.
|
- Alle Phasen können beliebig oft wiederholt werden.
|
||||||
- Vorhandene Dotfiles (`~/.zshrc`) und Konfigurationen (`/etc/default/grub`) werden vor Änderungen automatisch mit Zeitstempel (`.backup_YYYYMMDD_HHMMSS`) gesichert.
|
- Vorhandene Dotfiles (`~/.zshrc`) und Konfigurationen (`/etc/default/grub`) werden vor Änderungen automatisch mit Zeitstempel (`.backup_YYYYMMDD_HHMMSS`) gesichert.
|
||||||
- Auf Btrfs-Systemen werden mit Timeshift automatisch Rollback-Punkte vor und nach kritischen Operationen (Dist-Upgrade, Kernel-Installation, Paketinstallation, Desktop-Setup) erstellt.
|
- Auf Btrfs-Systemen werden mit Timeshift automatisch Rollback-Punkte vor und nach kritischen Operationen (Dist-Upgrade, Kernel-Installation, Paketinstallation, Desktop-Setup), bei jedem System-Update (automatischer APT/DPkg-Pre-Invoke-Hook) sowie bei jedem Systemstart (`timeshift-boot.service`) erstellt, wobei standardmäßig die letzten 5 Snapshots vorgehalten werden.
|
||||||
4. **Debian Unstable Absicherung**:
|
4. **Debian Unstable Absicherung**:
|
||||||
- Moderne Deb822-Quellen und dedizierte Keyrings in `/etc/apt/keyrings/`.
|
- Moderne Deb822-Quellen und dedizierte Keyrings in `/etc/apt/keyrings/`.
|
||||||
- Installation von `apt-listbugs` und `apt-listchanges` vor dem `dist-upgrade` schützt vor bekannten kritischen Paketproblemen.
|
- Installation von `apt-listbugs` und `apt-listchanges` vor dem `dist-upgrade` schützt vor bekannten kritischen Paketproblemen.
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ CPU_PSTATE_AUTO=1
|
|||||||
|
|
||||||
# Backup & System Snapshots (Timeshift Btrfs)
|
# Backup & System Snapshots (Timeshift Btrfs)
|
||||||
ENABLE_TIMESHIFT_SNAPSHOTS=1
|
ENABLE_TIMESHIFT_SNAPSHOTS=1
|
||||||
|
TIMESHIFT_COUNT_BOOT=5
|
||||||
|
TIMESHIFT_SCHEDULE_BOOT="true"
|
||||||
|
TIMESHIFT_SNAPSHOT_ON_UPDATE="true"
|
||||||
|
|
||||||
# Bootloader & Appearance
|
# Bootloader & Appearance
|
||||||
GRUB_THEME="vimix"
|
GRUB_THEME="vimix"
|
||||||
|
|||||||
+158
-6
@@ -262,14 +262,159 @@ check_and_setup_btrfs_subvolumes() {
|
|||||||
log_success "Btrfs subvolume setup and migration completed successfully."
|
log_success "Btrfs subvolume setup and migration completed successfully."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Ensure Timeshift APT hook is configured for automatic snapshots on system updates
|
||||||
|
ensure_timeshift_apt_hook() {
|
||||||
|
local root_prefix="${ROOT_PREFIX:-}"
|
||||||
|
local snapshot_on_update="${TIMESHIFT_SNAPSHOT_ON_UPDATE:-true}"
|
||||||
|
local apt_conf_file="${root_prefix}/etc/apt/apt.conf.d/80timeshift-auto-snapshot"
|
||||||
|
local hook_script="${root_prefix}/usr/local/bin/timeshift-apt-hook"
|
||||||
|
|
||||||
|
# If disabled in configuration, remove hook if present
|
||||||
|
if [[ "$snapshot_on_update" != "1" && "$snapshot_on_update" != "true" ]]; then
|
||||||
|
if [[ -f "$apt_conf_file" || -f "$hook_script" ]]; then
|
||||||
|
log_info "Disabling Timeshift APT update snapshot hook..."
|
||||||
|
rm -f "$apt_conf_file" "$hook_script"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${root_prefix}/usr/local/bin" "${root_prefix}/etc/apt/apt.conf.d"
|
||||||
|
|
||||||
|
# Create hook script
|
||||||
|
log_info "Configuring Timeshift APT update hook ($hook_script)..."
|
||||||
|
cat > "$hook_script" <<'EOF'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# ==============================================================================
|
||||||
|
# /usr/local/bin/timeshift-apt-hook - Automatic Timeshift Snapshot on APT updates
|
||||||
|
# ==============================================================================
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Check if timeshift binary is available
|
||||||
|
if ! command -v timeshift >/dev/null 2>&1; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if timeshift configuration exists
|
||||||
|
if [[ ! -f /etc/timeshift/timeshift.json && ! -f /etc/timeshift.json ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if root filesystem is Btrfs
|
||||||
|
if command -v findmnt >/dev/null 2>&1; then
|
||||||
|
if [[ "$(findmnt -n -o FSTYPE / 2>/dev/null || true)" != "btrfs" ]]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prevent duplicate snapshots within 60 seconds (rate limiting)
|
||||||
|
STAMP_FILE="/run/timeshift-apt-hook.stamp"
|
||||||
|
if [[ -f "$STAMP_FILE" ]]; then
|
||||||
|
LAST_RUN="$(stat -c %Y "$STAMP_FILE" 2>/dev/null || stat -f %m "$STAMP_FILE" 2>/dev/null || echo 0)"
|
||||||
|
CURRENT_TIME="$(date +%s)"
|
||||||
|
if (( CURRENT_TIME - LAST_RUN < 60 )); then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ">> [Timeshift] Creating automatic pre-update system snapshot..."
|
||||||
|
if timeshift --create --scripted --tags O --comments "Automatic snapshot before system update (APT)" 2>&1; then
|
||||||
|
touch "$STAMP_FILE" 2>/dev/null || true
|
||||||
|
echo ">> [Timeshift] Pre-update snapshot created successfully."
|
||||||
|
else
|
||||||
|
echo ">> [Timeshift] Warning: Automatic snapshot could not be created (continuing update)."
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
EOF
|
||||||
|
chmod 755 "$hook_script"
|
||||||
|
|
||||||
|
# Create APT configuration hook
|
||||||
|
cat > "$apt_conf_file" <<'EOF'
|
||||||
|
// Automatic Timeshift snapshot before APT package operations / updates
|
||||||
|
DPkg::Pre-Invoke { "[ -x /usr/local/bin/timeshift-apt-hook ] && /usr/local/bin/timeshift-apt-hook || true"; };
|
||||||
|
EOF
|
||||||
|
chmod 644 "$apt_conf_file"
|
||||||
|
|
||||||
|
log_success "Timeshift APT update hook configured: $apt_conf_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ensure Timeshift systemd boot service and cron jobs are configured and enabled
|
||||||
|
ensure_timeshift_boot_service() {
|
||||||
|
local root_prefix="${ROOT_PREFIX:-}"
|
||||||
|
local service_file="${root_prefix}/etc/systemd/system/timeshift-boot.service"
|
||||||
|
local timeshift_bin
|
||||||
|
timeshift_bin="$(command -v timeshift || echo "/usr/bin/timeshift")"
|
||||||
|
|
||||||
|
mkdir -p "${root_prefix}/etc/systemd/system"
|
||||||
|
|
||||||
|
local needs_service_update=0
|
||||||
|
if [[ ! -f "$service_file" ]]; then
|
||||||
|
needs_service_update=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$needs_service_update" -eq 1 ]]; then
|
||||||
|
log_info "Creating Timeshift boot snapshot service ($service_file)..."
|
||||||
|
cat > "$service_file" <<EOF
|
||||||
|
[Unit]
|
||||||
|
Description=Timeshift Boot Snapshot Service
|
||||||
|
Documentation=man:timeshift(1)
|
||||||
|
After=local-fs.target
|
||||||
|
ConditionPathExists=/etc/timeshift/timeshift.json
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=${timeshift_bin} --check --scripted
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
chmod 644 "$service_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$root_prefix" ]] && command_exists systemctl; then
|
||||||
|
systemctl daemon-reload 2>/dev/null || true
|
||||||
|
systemctl enable timeshift-boot.service 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Also install cron entries if cron directory exists
|
||||||
|
if [[ -d "${root_prefix}/etc/cron.d" ]]; then
|
||||||
|
local cron_boot="${root_prefix}/etc/cron.d/timeshift-boot"
|
||||||
|
local cron_hourly="${root_prefix}/etc/cron.d/timeshift-hourly"
|
||||||
|
|
||||||
|
if [[ ! -f "$cron_boot" ]]; then
|
||||||
|
cat > "$cron_boot" <<EOF
|
||||||
|
SHELL=/bin/bash
|
||||||
|
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||||
|
MAILTO=""
|
||||||
|
@reboot root sleep 10m && ${timeshift_bin} --create --scripted --tags B
|
||||||
|
EOF
|
||||||
|
chmod 644 "$cron_boot"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$cron_hourly" ]]; then
|
||||||
|
cat > "$cron_hourly" <<EOF
|
||||||
|
SHELL=/bin/bash
|
||||||
|
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||||
|
MAILTO=""
|
||||||
|
0 * * * * root ${timeshift_bin} --check --scripted
|
||||||
|
EOF
|
||||||
|
chmod 644 "$cron_hourly"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Ensure Timeshift is configured for Btrfs mode on the root filesystem
|
# Ensure Timeshift is configured for Btrfs mode on the root filesystem
|
||||||
ensure_timeshift_btrfs_config() {
|
ensure_timeshift_btrfs_config() {
|
||||||
|
local root_prefix="${ROOT_PREFIX:-}"
|
||||||
local root_uuid
|
local root_uuid
|
||||||
root_uuid="$(get_root_btrfs_uuid)"
|
root_uuid="$(get_root_btrfs_uuid)"
|
||||||
|
|
||||||
mkdir -p /etc/timeshift
|
mkdir -p "${root_prefix}/etc/timeshift"
|
||||||
|
|
||||||
local config_file="/etc/timeshift/timeshift.json"
|
local config_file="${root_prefix}/etc/timeshift/timeshift.json"
|
||||||
|
local count_boot="${TIMESHIFT_COUNT_BOOT:-5}"
|
||||||
|
local schedule_boot="${TIMESHIFT_SCHEDULE_BOOT:-true}"
|
||||||
local needs_update=0
|
local needs_update=0
|
||||||
|
|
||||||
if [[ ! -f "$config_file" ]]; then
|
if [[ ! -f "$config_file" ]]; then
|
||||||
@@ -278,6 +423,10 @@ ensure_timeshift_btrfs_config() {
|
|||||||
needs_update=1
|
needs_update=1
|
||||||
elif grep -q '"backup_device_uuid"[[:space:]]*:[[:space:]]*""' "$config_file" 2>/dev/null && [[ -n "$root_uuid" ]]; then
|
elif grep -q '"backup_device_uuid"[[:space:]]*:[[:space:]]*""' "$config_file" 2>/dev/null && [[ -n "$root_uuid" ]]; then
|
||||||
needs_update=1
|
needs_update=1
|
||||||
|
elif ! grep -q "\"schedule_boot\"[[:space:]]*:[[:space:]]*\"${schedule_boot}\"" "$config_file" 2>/dev/null; then
|
||||||
|
needs_update=1
|
||||||
|
elif ! grep -q "\"count_boot\"[[:space:]]*:[[:space:]]*\"${count_boot}\"" "$config_file" 2>/dev/null; then
|
||||||
|
needs_update=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$needs_update" -eq 1 ]]; then
|
if [[ "$needs_update" -eq 1 ]]; then
|
||||||
@@ -296,12 +445,12 @@ ensure_timeshift_btrfs_config() {
|
|||||||
"schedule_weekly" : "false",
|
"schedule_weekly" : "false",
|
||||||
"schedule_daily" : "false",
|
"schedule_daily" : "false",
|
||||||
"schedule_hourly" : "false",
|
"schedule_hourly" : "false",
|
||||||
"schedule_boot" : "false",
|
"schedule_boot" : "${schedule_boot}",
|
||||||
"count_monthly" : "2",
|
"count_monthly" : "2",
|
||||||
"count_weekly" : "3",
|
"count_weekly" : "3",
|
||||||
"count_daily" : "5",
|
"count_daily" : "5",
|
||||||
"count_hourly" : "6",
|
"count_hourly" : "6",
|
||||||
"count_boot" : "5",
|
"count_boot" : "${count_boot}",
|
||||||
"snapshot_size" : "0",
|
"snapshot_size" : "0",
|
||||||
"snapshot_count" : "0",
|
"snapshot_count" : "0",
|
||||||
"exclude" : [
|
"exclude" : [
|
||||||
@@ -311,10 +460,13 @@ ensure_timeshift_btrfs_config() {
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
chmod 644 "$config_file"
|
chmod 644 "$config_file"
|
||||||
if [[ ! -e /etc/timeshift.json ]]; then
|
if [[ ! -e "${root_prefix}/etc/timeshift.json" ]]; then
|
||||||
ln -sf /etc/timeshift/timeshift.json /etc/timeshift.json 2>/dev/null || true
|
ln -sf /etc/timeshift/timeshift.json "${root_prefix}/etc/timeshift.json" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
ensure_timeshift_boot_service
|
||||||
|
ensure_timeshift_apt_hook
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create a Btrfs snapshot using Timeshift
|
# Create a Btrfs snapshot using Timeshift
|
||||||
|
|||||||
+11
-1
@@ -8,6 +8,7 @@ set -euo pipefail
|
|||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
source "$SCRIPT_DIR/lib/utils.sh"
|
source "$SCRIPT_DIR/lib/utils.sh"
|
||||||
source "$SCRIPT_DIR/lib/apt.sh"
|
source "$SCRIPT_DIR/lib/apt.sh"
|
||||||
|
source "$SCRIPT_DIR/lib/btrfs.sh"
|
||||||
|
|
||||||
if [[ -f "$SCRIPT_DIR/config/setup.conf" ]]; then
|
if [[ -f "$SCRIPT_DIR/config/setup.conf" ]]; then
|
||||||
# shellcheck source=/dev/null
|
# shellcheck source=/dev/null
|
||||||
@@ -135,7 +136,16 @@ if command_exists systemctl; then
|
|||||||
log_success "Ollama systemd service configured and enabled."
|
log_success "Ollama systemd service configured and enabled."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 6. User Group Memberships
|
# 6. Timeshift Boot Snapshot Service & APT Update Hook (if on Btrfs)
|
||||||
|
log_substep "Configuring Timeshift Boot Snapshot Service and APT Update Hook..."
|
||||||
|
if command_exists timeshift && is_root_btrfs; then
|
||||||
|
ensure_timeshift_btrfs_config
|
||||||
|
log_success "Timeshift Boot Snapshot Service and APT Update Hook configured and enabled."
|
||||||
|
elif is_root_btrfs; then
|
||||||
|
log_info "Timeshift will be configured when installed."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 7. User Group Memberships
|
||||||
log_substep "Updating user group memberships for $TARGET_USER..."
|
log_substep "Updating user group memberships for $TARGET_USER..."
|
||||||
groupadd -f sudo
|
groupadd -f sudo
|
||||||
groupadd -f docker
|
groupadd -f docker
|
||||||
|
|||||||
Reference in New Issue
Block a user