fix(ci): restore backups through remote Docker API
quality / changes (push) Successful in 7s
quality / commitlint (push) Skipped
quality / openapi (push) Successful in 27s
quality / web (push) Successful in 48s
quality / api (push) Successful in 1m13s
quality / linux-agent-smoke (push) Successful in 22s
quality / docker-check (push) Successful in 4m43s
CD / quality (push) Successful in 7m42s
CD / publish (push) Successful in 5m17s
quality / changes (push) Successful in 7s
quality / commitlint (push) Skipped
quality / openapi (push) Successful in 27s
quality / web (push) Successful in 48s
quality / api (push) Successful in 1m13s
quality / linux-agent-smoke (push) Successful in 22s
quality / docker-check (push) Successful in 4m43s
CD / quality (push) Successful in 7m42s
CD / publish (push) Successful in 5m17s
This commit is contained in:
1 parent
57b7652d4d
commit
ce90fa9701
6 files changed
+85
-7
No files matched your search
@@ -18,7 +18,7 @@ marker_name="$id-persistence"
|
||||
tmp="$(mktemp -d)"
|
||||
cleanup() {
|
||||
result=$?
|
||||
docker logs "$container" >>"$tmp/container.log" 2>&1 || true
|
||||
if docker inspect "$container" >/dev/null 2>&1; then docker logs "$container" >>"$tmp/container.log" 2>&1 || true; fi
|
||||
if [ "$result" -ne 0 ]; then cat "$tmp/container.log" >&2; fi
|
||||
docker rm -f "$container" >/dev/null 2>&1 || true
|
||||
docker volume rm "$volume" "$restore_volume" >/dev/null 2>&1 || true
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env sh
|
||||
# No Docker daemon: verify actual restore transport, guards and exit propagation.
|
||||
set -eu
|
||||
wrapper="$(pwd)/deploy/docker/restore.sh"
|
||||
tmp="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp"' EXIT HUP INT TERM
|
||||
mkdir "$tmp/bin"
|
||||
backup="$tmp/input backup.db"
|
||||
printf 'synthetic backup' >"$backup"
|
||||
cat >"$tmp/bin/docker" <<'DOCKER'
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
printf '%s\n' "$*" >>"$FAKE_LOG"
|
||||
case "$1" in
|
||||
volume) [ "$2" = inspect ]; exit 0 ;;
|
||||
ps)
|
||||
count=0; [ ! -f "$FAKE_COUNT" ] || count="$(cat "$FAKE_COUNT")"
|
||||
count=$((count + 1)); printf '%s' "$count" >"$FAKE_COUNT"
|
||||
if [ "$FAKE_CASE" = ps-initial-failure ] || { [ "$FAKE_CASE" = ps-later-failure ] && [ "$count" = 2 ]; }; then exit 29; fi
|
||||
if [ "$FAKE_CASE" = live-initial ] || { [ "$FAKE_CASE" = live-later ] && [ "$count" = 2 ]; }; then printf 'other-writer\n'; fi ;;
|
||||
create) printf 'helper-id\n' ;;
|
||||
cp) [ "$2" = "$FAKE_BACKUP" ]; [ "$FAKE_CASE" != cp-failure ] || exit 17 ;;
|
||||
start) [ "$FAKE_CASE" != start-failure ] || exit 19 ;;
|
||||
wait) if [ "$FAKE_CASE" = restore-failure ]; then printf '23\n'; else printf '0\n'; fi ;;
|
||||
rm) exit 0 ;;
|
||||
*) echo 'Unexpected Docker operation in restore' >&2; exit 98 ;;
|
||||
esac
|
||||
DOCKER
|
||||
chmod +x "$tmp/bin/docker"
|
||||
for scenario in success cp-failure start-failure restore-failure live-initial live-later ps-initial-failure ps-later-failure; do
|
||||
log="$tmp/$scenario.log"
|
||||
if PATH="$tmp/bin:$PATH" FAKE_LOG="$log" FAKE_COUNT="$tmp/$scenario.count" FAKE_CASE="$scenario" FAKE_BACKUP="$backup" sh "$wrapper" image:immutable target-named-volume "$backup"; then actual=0; else actual=$?; fi
|
||||
case "$scenario" in success) expected=0;; cp-failure) expected=17;; start-failure) expected=19;; restore-failure) expected=23;; ps-*-failure) expected=29;; *) expected=1;; esac
|
||||
[ "$actual" = "$expected" ] || { echo "Unexpected status for $scenario: $actual" >&2; exit 1; }
|
||||
grep -F 'volume inspect target-named-volume' "$log" >/dev/null
|
||||
if grep -E -- '(type=bind|--privileged|--network host|docker.sock|^volume rm)' "$log" >/dev/null; then echo 'Restore must not use a host bind or remove the target volume' >&2; exit 1; fi
|
||||
if [ "$scenario" = live-initial ] || [ "$scenario" = ps-initial-failure ]; then
|
||||
if grep -E '^(create|cp|start) ' "$log" >/dev/null; then echo 'Active target must fail before helper creation' >&2; exit 1; fi
|
||||
continue
|
||||
fi
|
||||
grep -E '^create --name evofw-restore-[^ ]+ --network none --cap-drop ALL --security-opt no-new-privileges:true --mount type=volume,src=target-named-volume,dst=/data --entrypoint node image:immutable tools/sqlite-backup.mjs restore /tmp/evofw-restore-input.db /data/app.db --offline$' "$log" >/dev/null
|
||||
grep -E '^cp .*input backup.db evofw-restore-[^ ]+:/tmp/evofw-restore-input.db$' "$log" >/dev/null
|
||||
grep -E '^rm -fv evofw-restore-' "$log" >/dev/null
|
||||
if [ "$scenario" = cp-failure ] || [ "$scenario" = live-later ] || [ "$scenario" = ps-later-failure ]; then
|
||||
if grep -E '^start ' "$log" >/dev/null; then echo 'Incomplete input or newly active target must never start restore' >&2; exit 1; fi
|
||||
elif [ "$scenario" != start-failure ]; then
|
||||
grep -E '^wait evofw-restore-' "$log" >/dev/null
|
||||
[ "$(cat "$tmp/$scenario.count")" = 2 ]
|
||||
fi
|
||||
done
|
||||
echo 'Restore wrapper regression passed (remote copy, offline guards, failures, cleanup)'
|
||||
Reference in new issue
Block a user