|
1 | 1 | #!/bin/bash |
2 | 2 |
|
3 | 3 | # ================================================================= |
4 | | -# Restic Backup Script v0.21 - 2025.09.09 |
| 4 | +# Restic Backup Script v0.22 - 2025.09.09 |
5 | 5 | # ================================================================= |
6 | 6 |
|
7 | 7 | set -euo pipefail |
8 | 8 | umask 077 |
9 | 9 |
|
10 | 10 | # --- Script Constants --- |
11 | | -SCRIPT_VERSION="0.21" |
| 11 | +SCRIPT_VERSION="0.22" |
12 | 12 | SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) |
13 | 13 | CONFIG_FILE="${SCRIPT_DIR}/restic-backup.conf" |
14 | 14 | LOCK_FILE="/tmp/restic-backup.lock" |
@@ -475,38 +475,85 @@ cleanup() { |
475 | 475 |
|
476 | 476 | run_preflight_checks() { |
477 | 477 | local mode="${1:-backup}" |
| 478 | + echo -e "${C_BOLD}--- Running Pre-flight Checks ---${C_RESET}" |
478 | 479 |
|
479 | | - # Check required commands |
| 480 | + # System Dependencies |
| 481 | + echo -e "\n ${C_DIM}- Checking System Dependencies${C_RESET}" |
| 482 | + printf " %-65s" "Required commands (restic, curl, flock)..." |
480 | 483 | local required_cmds=(restic curl flock) |
481 | 484 | for cmd in "${required_cmds[@]}"; do |
482 | 485 | if ! command -v "$cmd" &>/dev/null; then |
| 486 | + echo -e "[${C_RED} FAIL ${C_RESET}]" |
483 | 487 | echo -e "${C_RED}ERROR: Required command '$cmd' not found${C_RESET}" >&2 |
484 | 488 | exit 10 |
485 | 489 | fi |
486 | 490 | done |
487 | | - |
488 | | - # Check password file |
489 | | - if [ ! -f "$RESTIC_PASSWORD_FILE" ]; then |
490 | | - echo -e "${C_RED}ERROR: Password file not found: $RESTIC_PASSWORD_FILE${C_RESET}" >&2 |
| 491 | + echo -e "[${C_GREEN} OK ${C_RESET}]" |
| 492 | + |
| 493 | + # Configuration Files |
| 494 | + echo -e "\n ${C_DIM}- Checking Configuration Files${C_RESET}" |
| 495 | + printf " %-65s" "Password file ('$RESTIC_PASSWORD_FILE')..." |
| 496 | + if [ ! -r "$RESTIC_PASSWORD_FILE" ]; then |
| 497 | + echo -e "[${C_RED} FAIL ${C_RESET}]" |
| 498 | + echo -e "${C_RED}ERROR: Password file not found or not readable: $RESTIC_PASSWORD_FILE${C_RESET}" >&2 |
491 | 499 | exit 11 |
492 | 500 | fi |
| 501 | + echo -e "[${C_GREEN} OK ${C_RESET}]" |
| 502 | + |
| 503 | + if [ -n "${EXCLUDE_FILE:-}" ]; then |
| 504 | + printf " %-65s" "Exclude file ('$EXCLUDE_FILE')..." |
| 505 | + if [ ! -r "$EXCLUDE_FILE" ]; then |
| 506 | + echo -e "[${C_RED} FAIL ${C_RESET}]" |
| 507 | + echo -e "${C_RED}ERROR: The specified EXCLUDE_FILE is not readable: ${EXCLUDE_FILE}${C_RESET}" >&2 |
| 508 | + exit 14 |
| 509 | + fi |
| 510 | + echo -e "[${C_GREEN} OK ${C_RESET}]" |
| 511 | + fi |
| 512 | + |
| 513 | + printf " %-65s" "Log file writability ('$LOG_FILE')..." |
| 514 | + if ! touch "$LOG_FILE" >/dev/null 2>&1; then |
| 515 | + echo -e "[${C_RED} FAIL ${C_RESET}]" |
| 516 | + echo -e "${C_RED}ERROR: The log file or its directory is not writable: ${LOG_FILE}${C_RESET}" >&2 |
| 517 | + exit 15 |
| 518 | + fi |
| 519 | + echo -e "[${C_GREEN} OK ${C_RESET}]" |
493 | 520 |
|
494 | | - # Check repository connectivity |
| 521 | + # Repository State |
| 522 | + echo -e "\n ${C_DIM}- Checking Repository State${C_RESET}" |
| 523 | + printf " %-65s" "Repository connectivity and credentials..." |
495 | 524 | if ! restic cat config >/dev/null 2>&1; then |
496 | 525 | if [[ "$mode" == "init" ]]; then |
497 | | - return 0 # OK for init mode |
| 526 | + echo -e "[${C_YELLOW} SKIP ${C_RESET}] (OK for --init mode)" |
| 527 | + return 0 |
498 | 528 | fi |
499 | | - echo -e "${C_RED}ERROR: Cannot access repository. Run with --init first${C_RESET}" >&2 |
| 529 | + echo -e "[${C_RED} FAIL ${C_RESET}]" |
| 530 | + echo -e "${C_RED}ERROR: Cannot access repository. Check credentials or run --init first.${C_RESET}" >&2 |
500 | 531 | exit 12 |
501 | 532 | fi |
| 533 | + echo -e "[${C_GREEN} OK ${C_RESET}]" |
| 534 | + |
| 535 | + printf " %-65s" "Stale repository locks..." |
| 536 | + local lock_info |
| 537 | + lock_info=$(restic list locks 2>/dev/null || true) |
| 538 | + if [ -n "$lock_info" ]; then |
| 539 | + echo -e "[${C_YELLOW} WARN ${C_RESET}]" |
| 540 | + echo -e "${C_YELLOW} ⚠️ Stale locks found! This may prevent backups from running.${C_RESET}" |
| 541 | + echo -e "${C_DIM} Run the --unlock command to remove them.${C_RESET}" |
| 542 | + else |
| 543 | + echo -e "[${C_GREEN} OK ${C_RESET}]" |
| 544 | + fi |
502 | 545 |
|
503 | | - # Check source directories (for backup mode) |
504 | | - if [[ "$mode" == "backup" ]]; then |
| 546 | + # Backup Sources |
| 547 | + if [[ "$mode" == "backup" || "$mode" == "diff" ]]; then |
| 548 | + echo -e "\n ${C_DIM}- Checking Backup Sources${C_RESET}" |
505 | 549 | for source in $BACKUP_SOURCES; do |
| 550 | + printf " %-65s" "Source directory ('$source')..." |
506 | 551 | if [ ! -d "$source" ] || [ ! -r "$source" ]; then |
507 | | - echo -e "${C_RED}ERROR: Source directory not accessible: $source${C_RESET}" >&2 |
| 552 | + echo -e "[${C_RED} FAIL ${C_RESET}]" |
| 553 | + echo -e "${C_RED}ERROR: Source directory not found or not readable: $source${C_RESET}" >&2 |
508 | 554 | exit 13 |
509 | 555 | fi |
| 556 | + echo -e "[${C_GREEN} OK ${C_RESET}]" |
510 | 557 | done |
511 | 558 | fi |
512 | 559 | } |
|
0 commit comments