considering argocd for backups
Check scripts syntax / check-scripts-syntax (push) Successful in 13s
Test Kubernetes backup scripts / test-k3s-control-plane-config-backup (push) Successful in 14s
Test Kubernetes backup scripts / test-automated-nfs-backup (push) Successful in 14s

This commit is contained in:
2026-09-07 16:18:19 -03:00
parent 75e888806f
commit 65fc9b3b9e
5 changed files with 164 additions and 37 deletions
+80 -2
View File
@@ -168,6 +168,7 @@ if [[ "$get_kind" == "namespaces" ]]; then
fi
if [[ -n "$get_kind" && -n "$namespace" ]]; then
[[ "${FAIL_CAPTURE_NS:-}" != "$namespace" ]] || exit 1
replicas=""
while IFS=: read -r configured_namespace configured_replicas; do
if [[ "$configured_namespace" == "$namespace" ]]; then
@@ -193,10 +194,15 @@ for ((i = 1; i <= $#; i++)); do
done
printf '%s %s %s %s\n' "$namespace" "$kind" "$name" "$replicas_arg" >> "${TMPD}/scale_trace.log"
printf 'scale %s %s\n' "$namespace" "$replicas_arg" >> "${TMPD}/event_trace.log"
[[ "${FAIL_SCALE:-}" != "$namespace:$replicas_arg" ]] || exit 1
exit 0
fi
done
if [[ " $* " == *" wait "* ]]; then
printf 'wait %s\n' "$namespace" >> "${TMPD}/event_trace.log"
exit "${FAIL_WAIT:-0}"
fi
exit 0
EOF
@@ -215,7 +221,7 @@ if [[ "${1:-}" == "a" && "${2:-}" == "-t7z" ]]; then
if [[ -s "${TMPD}/fail_archive.txt" ]]; then
touch "$archive"
exit 2
exit "${ARCHIVE_FAILURE_CODE:-2}"
fi
for staged_folder in ./*; do
@@ -303,6 +309,8 @@ run_backup() {
SEVENZ_BIN="${TMPD}/bin/7z" \
RSYNC_BIN="${TMPD}/bin/rsync" \
SCALE_WAIT_SECONDS=0 \
SCALE_RETRY_COUNT=2 \
SCALE_RETRY_DELAY_SECONDS=0 \
TMP_STATE_DIR="$state_dir" \
PATH="${TMPD}/bin:${PATH}" \
TMPD="$TMPD" \
@@ -611,7 +619,77 @@ set -e
assert "abort scenario exits non-zero" is_nonzero "${abort_exit_code}"
assert "abort scenario scaled crash-ns down to 0" trace_has_scale "${TMPD}/scale_trace.log" "crash-ns" "0"
assert "abort scenario EXIT trap restored crash-ns to 5" trace_has_scale "${TMPD}/scale_trace.log" "crash-ns" "5"
assert "abort scenario cleaned its per-run state directory" directory_is_empty "$abort_state"
assert "abort scenario removed its replica state" file_lacks "${abort_dir}/abort.log" "saved state retained"
# ArgoCD is global, irrespective of folders, exclusions or workload overrides.
for scenario in normal no-folder scale-failure wait-failure capture-failure restore-failure warning; do
case_dir="${TMPD}/argocd-${scenario}"
mkdir -p "$case_dir/source/app-ns" "$case_dir/out"
[[ "$scenario" == no-folder ]] || mkdir -p "$case_dir/source/argocd"
printf 'argocd\napp-ns\n' > "${TMPD}/namespaces.txt"
printf 'argocd:2\napp-ns:3\n' > "${TMPD}/replicas.txt"
: > "${TMPD}/fail_folders.txt"
: > "${TMPD}/fail_archive.txt"
: > "${TMPD}/event_trace.log"
: > "${TMPD}/scale_trace.log"
overrides=(WORKLOAD_KINDS=deployment EXCLUDED_NAMESPACES=argocd)
case "$scenario" in
scale-failure) overrides+=(FAIL_SCALE=argocd:--replicas=0) ;;
wait-failure) overrides+=(FAIL_WAIT=1) ;;
capture-failure) overrides+=(FAIL_CAPTURE_NS=argocd) ;;
restore-failure) overrides+=(FAIL_SCALE=app-ns:--replicas=3) ;;
warning)
printf 'fail\n' > "${TMPD}/fail_archive.txt"
overrides+=(ARCHIVE_FAILURE_CODE=1)
;;
esac
set +e
run_backup "$case_dir/source" "$case_dir/out" "$case_dir/state" "$case_dir/run.log" "${overrides[@]}"
result=$?
set -e
case "$scenario" in
normal|no-folder)
assert "$scenario succeeds with ArgoCD present" is_zero "$result"
assert "$scenario stops ArgoCD before app and restores it after compression" events_are_ordered "${TMPD}/event_trace.log" \
'scale argocd --replicas=0' 'wait argocd' 'scale app-ns --replicas=0' 'scale app-ns --replicas=3' '7z staging' 'scale argocd --replicas=2'
assert "$scenario also stops ArgoCD StatefulSets" file_contains "${TMPD}/scale_trace.log" 'argocd statefulset web --replicas=0'
;;
scale-failure|wait-failure|capture-failure)
assert "$scenario aborts" is_nonzero "$result"
assert "$scenario never stops app workloads" file_lacks "${TMPD}/scale_trace.log" 'app-ns'
;;
restore-failure)
assert "restore failure exits nonzero" is_nonzero "$result"
assert "restore failure retains recovery state" file_contains "$case_dir/run.log" 'saved state retained'
assert "restore failure still restores ArgoCD last" events_are_ordered "${TMPD}/event_trace.log" 'scale app-ns --replicas=3' 'scale argocd --replicas=2'
;;
warning)
assert "7z warning fails backup" is_nonzero "$result"
assert "7z warning removes incomplete archive" archive_count_is "$case_dir/out" 0
;;
esac
done
# Collision and overlap guards must preserve existing backups and avoid scaling.
guard_dir="${TMPD}/guards"
mkdir -p "$guard_dir/source/app-ns" "$guard_dir/out" "$guard_dir/state"
: > "${TMPD}/namespaces.txt"
: > "${TMPD}/fail_archive.txt"
printf 'existing archive\n' > "$guard_dir/out/test_fixed.7z"
set +e
run_backup "$guard_dir/source" "$guard_dir/out" "$guard_dir/state" "$guard_dir/collision.log" ARCHIVE_TS_FORMAT=fixed
result=$?
set -e
assert "archive collision is rejected" is_nonzero "$result"
assert "archive collision preserves original content" file_contains "$guard_dir/out/test_fixed.7z" 'existing archive'
(
flock -n 9 || exit 1
set +e
run_backup "$guard_dir/source" "$guard_dir/out" "$guard_dir/state" "$guard_dir/locked.log"
[[ $? -ne 0 ]]
) 9>"$guard_dir/state/backup.lock"
assert "overlapping run is rejected by lock" file_contains "$guard_dir/locked.log" 'Another NFS backup is running'
printf 'TESTS PASSED: %s / %s\n' "$tests_passed" "$tests_total"
if [[ "$tests_failed" -gt 0 ]]; then