Skip to content

Commit 4bed96f

Browse files
authored
Merge pull request #15 from buildplan/test_check
Implement test flag
2 parents 138a669 + 8d27fbe commit 4bed96f

File tree

2 files changed

+100
-40
lines changed

2 files changed

+100
-40
lines changed

README.md

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,13 @@ END_EXCLUDES
222222

223223
# =================================================================
224224
# SCRIPT INITIALIZATION & SETUP
225-
# v0.12 - 2025.08.10
225+
# v0.13 - 2025.08.10
226226
# =================================================================
227227
set -Euo pipefail
228228
umask 077
229229

230+
HOSTNAME=$(hostname -s)
231+
230232
# Check if the script is being run as root
231233
if (( EUID != 0 )); then
232234
echo "❌ This script must be run as root or with sudo." >&2
@@ -251,7 +253,7 @@ if [ -f "$CONFIG_FILE" ]; then
251253
fi
252254

253255
if $in_exclude_block; then
254-
[[ ! "$line" =~ ^\s*#|^\s*$ ]] && echo "$line" >> "$EXCLUDE_FILE_TMP"
256+
[[ ! "$line" =~ ^([[:space:]]*#|[[:space:]]*$) ]] && echo "$line" >> "$EXCLUDE_FILE_TMP"
255257
continue
256258
fi
257259

@@ -383,34 +385,54 @@ cleanup() {
383385
# PRE-FLIGHT CHECKS & SETUP
384386
# =================================================================
385387

388+
run_preflight_checks() {
389+
# This function runs all checks. If 'true' is passed as an argument,
390+
# it runs in a verbose test mode instead of sending notifications.
391+
local test_mode=${1:-false}
392+
local check_failed=false
393+
394+
# 1. Check for required commands
395+
if [[ "$test_mode" == "true" ]]; then echo "--- Checking required commands..."; fi
396+
for cmd in "${REQUIRED_CMDS[@]}"; do
397+
if ! command -v "$cmd" &>/dev/null; then
398+
echo "❌ FATAL: Required command '$cmd' not found. Please install it." >&2
399+
check_failed=true
400+
fi
401+
done
402+
if [[ "$check_failed" == "true" ]]; then exit 10; fi
403+
if [[ "$test_mode" == "true" ]]; then echo "✅ All required commands are present."; fi
404+
405+
# 2. Check SSH connectivity
406+
if [[ "$test_mode" == "true" ]]; then echo "--- Checking SSH connectivity..."; fi
407+
if ! ssh ${SSH_OPTS_STR:-} -o BatchMode=yes -o ConnectTimeout=10 "$HETZNER_BOX" 'exit' 2>/dev/null; then
408+
local err_msg="Unable to SSH into $HETZNER_BOX. Check keys and connectivity."
409+
if [[ "$test_mode" == "true" ]]; then echo "$err_msg"; else send_notification "❌ SSH FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "$err_msg"; fi
410+
exit 6
411+
fi
412+
if [[ "$test_mode" == "true" ]]; then echo "✅ SSH connectivity OK."; fi
413+
414+
# 3. Check backup directories
415+
if [[ "$test_mode" == "true" ]]; then echo "--- Checking backup directories..."; fi
416+
for dir in $BACKUP_DIRS; do
417+
if [[ ! -d "$dir" ]] || [[ "$dir" != */ ]]; then
418+
local err_msg="A directory in BACKUP_DIRS ('$dir') must exist and end with a trailing slash ('/')."
419+
if [[ "$test_mode" == "true" ]]; then echo "❌ FATAL: $err_msg"; else send_notification "❌ Backup FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "FATAL: $err_msg"; fi
420+
exit 2
421+
fi
422+
done
423+
if [[ "$test_mode" == "true" ]]; then echo "✅ All backup directories are valid."; fi
424+
}
425+
386426
trap cleanup EXIT
387427
trap 'send_notification "❌ Backup Crashed: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "Backup script terminated unexpectedly. Check log: ${LOG_FILE:-/dev/null}"' ERR
388428

389429
REQUIRED_CMDS=(rsync curl flock hostname date stat mv touch awk numfmt grep printf nice ionice sed mktemp basename)
390-
for cmd in "${REQUIRED_CMDS[@]}"; do
391-
if ! command -v "$cmd" &>/dev/null; then
392-
echo "FATAL: Required command '$cmd' not found. Please install it." >&2; trap - ERR; exit 10
393-
fi
394-
done
395-
396-
if ! ssh ${SSH_OPTS_STR:-} -o BatchMode=yes -o ConnectTimeout=10 "$HETZNER_BOX" 'exit' 2>/dev/null; then
397-
send_notification "❌ SSH FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "Unable to SSH into $HETZNER_BOX. Check keys and connectivity."
398-
trap - ERR; exit 6
399-
fi
400-
401-
for dir in $BACKUP_DIRS; do
402-
if [[ ! -d "$dir" ]] || [[ "$dir" != */ ]]; then
403-
send_notification "❌ Backup FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "FATAL: A directory in BACKUP_DIRS ('$dir') must exist and end with a trailing slash ('/')."
404-
trap - ERR; exit 2
405-
fi
406-
done
407430

408431

409432
# =================================================================
410433
# SCRIPT EXECUTION
411434
# =================================================================
412435

413-
HOSTNAME=$(hostname -s)
414436
VERBOSE_MODE=false
415437
if [[ "${1:-}" == "--verbose" ]]; then
416438
VERBOSE_MODE=true; shift
@@ -468,6 +490,14 @@ if [[ "${1:-}" ]]; then
468490
fi
469491
fi
470492
exit 0 ;;
493+
--test)
494+
echo "--- TEST MODE ACTIVATED ---"
495+
# Call the pre-flight checks in test mode
496+
run_preflight_checks true
497+
echo "---------------------------"
498+
echo "✅ All configuration checks passed."
499+
exit 0
500+
;;
471501
esac
472502
fi
473503

backup_script.sh

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
# =================================================================
44
# SCRIPT INITIALIZATION & SETUP
5-
# v0.12 - 2025.08.10
5+
# v0.13 - 2025.08.10
66
# =================================================================
77
set -Euo pipefail
88
umask 077
99

10+
HOSTNAME=$(hostname -s)
11+
1012
# Check if the script is being run as root
1113
if (( EUID != 0 )); then
1214
echo "❌ This script must be run as root or with sudo." >&2
@@ -31,7 +33,7 @@ if [ -f "$CONFIG_FILE" ]; then
3133
fi
3234

3335
if $in_exclude_block; then
34-
[[ ! "$line" =~ ^\s*#|^\s*$ ]] && echo "$line" >> "$EXCLUDE_FILE_TMP"
36+
[[ ! "$line" =~ ^([[:space:]]*#|[[:space:]]*$) ]] && echo "$line" >> "$EXCLUDE_FILE_TMP"
3537
continue
3638
fi
3739

@@ -163,34 +165,54 @@ cleanup() {
163165
# PRE-FLIGHT CHECKS & SETUP
164166
# =================================================================
165167

168+
run_preflight_checks() {
169+
# This function runs all checks. If 'true' is passed as an argument,
170+
# it runs in a verbose test mode instead of sending notifications.
171+
local test_mode=${1:-false}
172+
local check_failed=false
173+
174+
# 1. Check for required commands
175+
if [[ "$test_mode" == "true" ]]; then echo "--- Checking required commands..."; fi
176+
for cmd in "${REQUIRED_CMDS[@]}"; do
177+
if ! command -v "$cmd" &>/dev/null; then
178+
echo "❌ FATAL: Required command '$cmd' not found. Please install it." >&2
179+
check_failed=true
180+
fi
181+
done
182+
if [[ "$check_failed" == "true" ]]; then exit 10; fi
183+
if [[ "$test_mode" == "true" ]]; then echo "✅ All required commands are present."; fi
184+
185+
# 2. Check SSH connectivity
186+
if [[ "$test_mode" == "true" ]]; then echo "--- Checking SSH connectivity..."; fi
187+
if ! ssh ${SSH_OPTS_STR:-} -o BatchMode=yes -o ConnectTimeout=10 "$HETZNER_BOX" 'exit' 2>/dev/null; then
188+
local err_msg="Unable to SSH into $HETZNER_BOX. Check keys and connectivity."
189+
if [[ "$test_mode" == "true" ]]; then echo "$err_msg"; else send_notification "❌ SSH FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "$err_msg"; fi
190+
exit 6
191+
fi
192+
if [[ "$test_mode" == "true" ]]; then echo "✅ SSH connectivity OK."; fi
193+
194+
# 3. Check backup directories
195+
if [[ "$test_mode" == "true" ]]; then echo "--- Checking backup directories..."; fi
196+
for dir in $BACKUP_DIRS; do
197+
if [[ ! -d "$dir" ]] || [[ "$dir" != */ ]]; then
198+
local err_msg="A directory in BACKUP_DIRS ('$dir') must exist and end with a trailing slash ('/')."
199+
if [[ "$test_mode" == "true" ]]; then echo "❌ FATAL: $err_msg"; else send_notification "❌ Backup FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "FATAL: $err_msg"; fi
200+
exit 2
201+
fi
202+
done
203+
if [[ "$test_mode" == "true" ]]; then echo "✅ All backup directories are valid."; fi
204+
}
205+
166206
trap cleanup EXIT
167207
trap 'send_notification "❌ Backup Crashed: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "Backup script terminated unexpectedly. Check log: ${LOG_FILE:-/dev/null}"' ERR
168208

169209
REQUIRED_CMDS=(rsync curl flock hostname date stat mv touch awk numfmt grep printf nice ionice sed mktemp basename)
170-
for cmd in "${REQUIRED_CMDS[@]}"; do
171-
if ! command -v "$cmd" &>/dev/null; then
172-
echo "FATAL: Required command '$cmd' not found. Please install it." >&2; trap - ERR; exit 10
173-
fi
174-
done
175-
176-
if ! ssh ${SSH_OPTS_STR:-} -o BatchMode=yes -o ConnectTimeout=10 "$HETZNER_BOX" 'exit' 2>/dev/null; then
177-
send_notification "❌ SSH FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "Unable to SSH into $HETZNER_BOX. Check keys and connectivity."
178-
trap - ERR; exit 6
179-
fi
180-
181-
for dir in $BACKUP_DIRS; do
182-
if [[ ! -d "$dir" ]] || [[ "$dir" != */ ]]; then
183-
send_notification "❌ Backup FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "FATAL: A directory in BACKUP_DIRS ('$dir') must exist and end with a trailing slash ('/')."
184-
trap - ERR; exit 2
185-
fi
186-
done
187210

188211

189212
# =================================================================
190213
# SCRIPT EXECUTION
191214
# =================================================================
192215

193-
HOSTNAME=$(hostname -s)
194216
VERBOSE_MODE=false
195217
if [[ "${1:-}" == "--verbose" ]]; then
196218
VERBOSE_MODE=true; shift
@@ -248,6 +270,14 @@ if [[ "${1:-}" ]]; then
248270
fi
249271
fi
250272
exit 0 ;;
273+
--test)
274+
echo "--- TEST MODE ACTIVATED ---"
275+
# Call the pre-flight checks in test mode
276+
run_preflight_checks true
277+
echo "---------------------------"
278+
echo "✅ All configuration checks passed."
279+
exit 0
280+
;;
251281
esac
252282
fi
253283

0 commit comments

Comments
 (0)