diff --git a/update_arch.sh b/update_arch.sh index dab8879..1ebe7de 100755 --- a/update_arch.sh +++ b/update_arch.sh @@ -4,26 +4,87 @@ sudo -v ACTION="${1:-update}" +KERNEL_PACKAGES=(linux linux-lts linux-zen linux-hardened linux-rt linux-rt-lts linux-rt-bfq linux-xanmod linux-xanmod-lts linux-xanmod-tt) + +create_timeshift_snapshot() { + local comment=${1:-"Update script"} + + if ! pacman -Qs timeshift >/dev/null; then + printf -- '\033[33m Timeshift not installed; skipping snapshot\n\033[37m' + return 0 + fi + + printf -- '\033[33m Creating Timeshift snapshot\n\033[37m' + sudo timeshift --create --comments "$comment" +} + +backup_boot_archive() { + local mode=${1:-auto} + + if [ "$mode" = "auto" ]; then + sudo pacman -Sy --noconfirm >/dev/null + local pending=() + for kernel_pkg in "${KERNEL_PACKAGES[@]}"; do + if pacman -Qi "$kernel_pkg" >/dev/null 2>&1 && pacman -Qu "$kernel_pkg" >/dev/null 2>&1; then + pending+=("$kernel_pkg") + fi + done + + if [ "${#pending[@]}" -eq 0 ]; then + printf -- '\033[33m No kernel update detected; skipping /boot backup\n\033[37m' + return 0 + fi + + printf -- '\033[33m Kernel update detected; backing up /boot\n\033[37m' + else + printf -- '\033[33m Forcing /boot backup\n\033[37m' + fi + + local boot_backup_dir="${HOME}/boot-backups" + mkdir -p "$boot_backup_dir" + local backup_file="${boot_backup_dir}/boot-$(date +%Y%m%d-%H%M%S).tar.gz" + sudo tar -C /boot -acf "$backup_file" . + sudo chown "$USER":"$USER" "$backup_file" + printf -- '\033[32m Saved /boot backup to %s\n\033[37m' "$backup_file" +} + restore_latest_state() { printf -- '\033[33m Gathering restore options\n\033[37m' BOOT_BACKUP_DIR="${HOME}/boot-backups" TIMESLICE_INFO="" - SNAPSHOT_CREATED="" + TIMESLICE_META="" TIMESLICE_LABEL="" if pacman -Qs timeshift >/dev/null; then - TIMESLICE_INFO=$(sudo timeshift --list | awk -F': +' ' - /^Snapshot/ {snap=$2} - /^Created on/ {created=$2} - END { if (snap != "") { print snap "|" created } } + TIMESHIFT_LIST=$(sudo timeshift --list) + TIMESLICE_INFO=$(printf '%s\n' "$TIMESHIFT_LIST" | awk ' + $1 ~ /^[0-9]+$/ { + idx=2 + if ($2 == ">") { idx=3 } + snap=$idx + desc="" + for (i=idx+2; i<=NF; i++) { + desc = desc ? desc " " $i : $i + } + } + END { + if (snap != "") { + printf "%s|%s", snap, desc + } + } ') + if [ -z "$TIMESLICE_INFO" ]; then + TIMESLICE_INFO=$(printf '%s\n' "$TIMESHIFT_LIST" | awk -F': +' ' + /^Snapshot/ {snap=$2} + /^Created on/ {created=$2} + END { if (snap != "") { printf "%s|%s", snap, created } } + ') + fi if [ -n "$TIMESLICE_INFO" ]; then TIMESLICE_LABEL=${TIMESLICE_INFO%%|*} - SNAPSHOT_CREATED=${TIMESLICE_INFO##*|} - if [ "$SNAPSHOT_CREATED" = "$TIMESLICE_LABEL" ]; then - SNAPSHOT_CREATED="" - fi + TIMESLICE_META=${TIMESLICE_INFO#*|} + [ "$TIMESLICE_META" = "$TIMESLICE_LABEL" ] && TIMESLICE_META="" fi fi @@ -33,10 +94,9 @@ restore_latest_state() { fi if [ -n "$TIMESLICE_LABEL" ]; then - if [ -n "$SNAPSHOT_CREATED" ]; then - printf -- '\033[33m Latest Timeshift snapshot: %s (created %s)\n\033[37m' "$TIMESLICE_LABEL" "$SNAPSHOT_CREATED" - else - printf -- '\033[33m Latest Timeshift snapshot: %s\n\033[37m' "$TIMESLICE_LABEL" + printf -- '\033[33m Latest Timeshift snapshot: %s\n\033[37m' "$TIMESLICE_LABEL" + if [ -n "$TIMESLICE_META" ]; then + printf -- ' Details: %s\n' "$TIMESLICE_META" fi else printf -- '\033[33m No Timeshift snapshots available\n\033[37m' @@ -89,6 +149,10 @@ restore_latest_state() { if [ "$ACTION" == "restore" ]; then restore_latest_state exit 0 +elif [ "$ACTION" == "backup" ]; then + create_timeshift_snapshot "Manual backup (update_arch.sh)" + backup_boot_archive force + exit 0 fi if ! pacman -Qs inetutils >/dev/null; then @@ -163,10 +227,7 @@ printf -- '\n\n\033[37m' sleep 1 # Create backup/snapshot -if pacman -Qs timeshift >/dev/null; then - printf -- '\033[33m Creating backup/snapshot\n\033[37m' - sudo timeshift --create --comments "Update script" -fi +create_timeshift_snapshot "Update script" # Enable multilib (if applicable) if [ "${ROLES[GAME]}" == "yes" ]; then @@ -181,28 +242,7 @@ EOT fi # Back up /boot ahead of kernel upgrades so it aligns with Timeshift snapshots -sudo pacman -Sy --noconfirm >/dev/null -KERNEL_PACKAGES=(linux linux-lts linux-zen linux-hardened linux-rt linux-rt-lts linux-rt-bfq linux-xanmod linux-xanmod-lts linux-xanmod-tt) -PENDING_KERNELS=() -for kernel_pkg in "${KERNEL_PACKAGES[@]}"; do - if pacman -Qi "$kernel_pkg" >/dev/null 2>&1; then - if pacman -Qu "$kernel_pkg" >/dev/null 2>&1; then - PENDING_KERNELS+=("$kernel_pkg") - fi - fi -done - -if [ "${#PENDING_KERNELS[@]}" -gt 0 ]; then - printf -- '\\033[33m Kernel update detected; backing up /boot\\n\\033[37m' - BOOT_BACKUP_DIR="${HOME}/boot-backups" - mkdir -p "$BOOT_BACKUP_DIR" - BACKUP_FILE="${BOOT_BACKUP_DIR}/boot-$(date +%Y%m%d-%H%M%S).tar.gz" - sudo tar -C /boot -acf "$BACKUP_FILE" . - sudo chown "$USER":"$USER" "$BACKUP_FILE" - printf -- '\\033[32m Saved /boot backup to %s\\n\\033[37m' "$BACKUP_FILE" -else - printf -- '\\033[33m No kernel update detected; skipping /boot backup\\n\\033[37m' -fi +backup_boot_archive auto # Update all pacman packages printf -- '\033[33m Updating pacman packages\n\033[37m'