mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
fix(backup): pass quality-high for the swarm writer-quiesce drill
Follow-up corrections to b449f8157 (swarm DR drill): - export test.env in 06/07 via set -a so the child db restore/probe scripts inherit BKP_TEST_DATABASES_CSV and BKP_TEST_RESTORE_BIN instead of aborting at their :? guards before any restore runs - move db_probe.sh/db_restore.sh into a db/ subfolder (probe.sh, restore.sh) and update all callers, so they stop tripping the prefix-grouped-files structure lint - define TEST_E2E_SWARM_DRILL in group_vars/all and drop the now redundant default() from test.env.j2 (satisfies the undefined-var and spot-default lints together) - fix a mermaid parse error in the drill README: a ; in a sequenceDiagram note was read as a statement separator make quality-high green (test + lint phases, 15 targets, 0 failures). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
985ec7eab9
commit
5c2c8f531f
9 files changed
+33
-29
No files matched your search
@@ -50,6 +50,7 @@ BUILDKIT_ENABLED: true # When falsy the compose wrapper forces the legacy builde
|
||||
ASYNC_ENABLED: "{{ not MODE_DEBUG | bool }}" # Activate async, deactivated for debugging
|
||||
ASYNC_TIME: "{{ 300 if ASYNC_ENABLED | bool else omit }}" # Run for max 5min
|
||||
ASYNC_POLL: "{{ 0 if ASYNC_ENABLED | bool else 10 }}" # Don't wait for task
|
||||
TEST_E2E_SWARM_DRILL: false # Gate for the orchestrated swarm CI DR drill; only it may replay database dumps on a live swarm
|
||||
|
||||
APPLICATIONS_WHITELIST: [] # nocheck: unused-var
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ set -euo pipefail
|
||||
|
||||
: "${BKP_TEST_DATABASES_CSV:?}"
|
||||
|
||||
MODE="${1:?usage: db_probe.sh seed TOKEN | verify PRE_TOKEN POST_TOKEN MANIFEST}"
|
||||
MODE="${1:?usage: probe.sh seed TOKEN | verify PRE_TOKEN POST_TOKEN MANIFEST}"
|
||||
PROBE_TABLE="infinito_backup_restore_probe"
|
||||
|
||||
validate_token() {
|
||||
File renamed without changes.
@@ -68,7 +68,7 @@ if [[ "${ASYNC_ENABLED}" != "true" ]] && [[ "${SWARM_ACTIVE}" == "true" ]]; then
|
||||
PROBE_BASE="infinito_${MACHINE_HASH:0:12}_$(date +%s)_${BASHPID}"
|
||||
PROBE_PRE_TOKEN="${PROBE_BASE}_pre"
|
||||
PROBE_POST_TOKEN="${PROBE_BASE}_post"
|
||||
bash "${DIR}/db_probe.sh" seed "${PROBE_PRE_TOKEN}"
|
||||
bash "${DIR}/db/probe.sh" seed "${PROBE_PRE_TOKEN}"
|
||||
fi
|
||||
|
||||
echo "Forcing a post-deploy backup run (the service-loader pre-state backup can predate the app volumes and be empty)"
|
||||
@@ -132,7 +132,7 @@ if [[ "${SWARM_ACTIVE}" == "true" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
bash "${DIR}/db_probe.sh" seed "${PROBE_POST_TOKEN}"
|
||||
bash "${DIR}/db/probe.sh" seed "${PROBE_POST_TOKEN}"
|
||||
umask 077
|
||||
{
|
||||
printf 'MACHINE_HASH=%q\n' "${MACHINE_HASH}"
|
||||
@@ -147,5 +147,5 @@ if [[ "${SWARM_ACTIVE}" == "true" ]]; then
|
||||
fi
|
||||
|
||||
bash "${DIR}/restore_cycle.sh"
|
||||
bash "${DIR}/db_restore.sh"
|
||||
bash "${DIR}/db/restore.sh"
|
||||
echo "SYNC PASS COMPLETE: backup verified and restore cycle succeeded"
|
||||
@@ -5,4 +5,4 @@ BKP_TEST_HEALTH_TIMEOUT={{ lookup('timeout', 1200) | int }}
|
||||
BKP_TEST_IS_STACK_HOST={{ IS_STACK_HOST | bool | lower }}
|
||||
BKP_TEST_RESTORE_BIN=baudolo-restore
|
||||
BKP_TEST_SERVICE={{ SYS_SERVICE_BACKUP_VOLUME_2_LOCAL }}
|
||||
BKP_TEST_SWARM_DRILL={{ TEST_E2E_SWARM_DRILL | default(false) | bool | lower }}
|
||||
BKP_TEST_SWARM_DRILL={{ TEST_E2E_SWARM_DRILL | bool | lower }}
|
||||
@@ -11,8 +11,10 @@ if [[ ! -f "${PENDING}" ]]; then
|
||||
echo "FAIL: database restore handoff missing at ${PENDING}"
|
||||
exit 1
|
||||
fi
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
. "${TEST_DIR}/test.env"
|
||||
set +a
|
||||
# shellcheck disable=SC1090
|
||||
. "${PENDING}"
|
||||
|
||||
@@ -32,7 +34,7 @@ if [[ ! -d "${REPO_DIR}/${NEWEST_GENERATION}" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
bash "${TEST_DIR}/db_restore.sh"
|
||||
bash "${TEST_DIR}/db/restore.sh"
|
||||
if [[ ! -s "${MANIFEST}" ]]; then
|
||||
echo "FAIL: database restore completed without a restored-database manifest"
|
||||
exit 1
|
||||
|
||||
@@ -9,8 +9,10 @@ if [[ ! -f "${COMPLETE}" ]]; then
|
||||
echo "FAIL: completed database restore handoff missing at ${COMPLETE}"
|
||||
exit 1
|
||||
fi
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
. "${TEST_DIR}/test.env"
|
||||
set +a
|
||||
# shellcheck disable=SC1090
|
||||
. "${COMPLETE}"
|
||||
|
||||
@@ -19,5 +21,5 @@ if [[ "${BKP_TEST_SWARM_DRILL}" != "true" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
bash "${TEST_DIR}/db_probe.sh" verify \
|
||||
bash "${TEST_DIR}/db/probe.sh" verify \
|
||||
"${PROBE_PRE_TOKEN}" "${PROBE_POST_TOKEN}" "${MANIFEST}"
|
||||
@@ -82,7 +82,7 @@ sequenceDiagram
|
||||
B-->>M: device-recovered volume backup repository
|
||||
M->>D: replay dumps while all writers remain stopped
|
||||
|
||||
Note over M,N: matrix update redeploys; health, Playwright, file markers and DB before/after probes must pass
|
||||
Note over M,N: matrix update redeploys, then health, Playwright, file markers and DB before/after probes must pass
|
||||
```
|
||||
|
||||
## Data flow (what is proven)
|
||||
|
||||
@@ -8,7 +8,6 @@ from pathlib import Path
|
||||
|
||||
from utils import PROJECT_ROOT
|
||||
|
||||
|
||||
BACKUP_SCRIPTS = PROJECT_ROOT / "scripts/tests/deploy/swarm/routine/backup"
|
||||
ROLE_TEST_SCRIPTS = PROJECT_ROOT / "roles/svc-bkp-volume-2-local/files/test"
|
||||
|
||||
@@ -20,6 +19,7 @@ class TestDatabaseRestoreHandoff(unittest.TestCase):
|
||||
self.root = Path(self.tmp.name)
|
||||
self.test_dir = self.root / "role-test"
|
||||
self.test_dir.mkdir()
|
||||
(self.test_dir / "db").mkdir()
|
||||
(self.test_dir / "test.env").write_text(
|
||||
"BKP_TEST_SWARM_DRILL=true\nBKP_TEST_DATABASES_CSV=/unused\n"
|
||||
)
|
||||
@@ -34,11 +34,11 @@ class TestDatabaseRestoreHandoff(unittest.TestCase):
|
||||
"PROBE_PRE_TOKEN=before\n"
|
||||
"PROBE_POST_TOKEN=after\n"
|
||||
)
|
||||
restore = self.test_dir / "db_restore.sh"
|
||||
restore = self.test_dir / "db" / "restore.sh"
|
||||
restore.write_text(
|
||||
"#!/usr/bin/env bash\n"
|
||||
"set -euo pipefail\n"
|
||||
": \"${BKP_TEST_BACKUPS_DIR:?}\" \"${REPO_DIR:?}\"\n"
|
||||
': "${BKP_TEST_BACKUPS_DIR:?}" "${REPO_DIR:?}"\n'
|
||||
"printf 'postgres;postgres_data;app\\n' >\"${BKP_TEST_RESTORED_DATABASES_FILE}\"\n"
|
||||
)
|
||||
restore.chmod(0o755)
|
||||
@@ -66,15 +66,15 @@ class TestDatabaseRestoreHandoff(unittest.TestCase):
|
||||
manifest = self.test_dir / "swarm-restore.manifest"
|
||||
manifest.write_text("postgres;postgres_data;app\n")
|
||||
verified = self.root / "probe-verified"
|
||||
probe = self.test_dir / "db_probe.sh"
|
||||
probe = self.test_dir / "db" / "probe.sh"
|
||||
probe.write_text(
|
||||
"#!/usr/bin/env bash\n"
|
||||
"set -euo pipefail\n"
|
||||
"test \"$1\" = verify\n"
|
||||
"test \"$2\" = before\n"
|
||||
"test \"$3\" = after\n"
|
||||
f"test \"$4\" = {manifest}\n"
|
||||
"touch \"${PROBE_VERIFIED:?}\"\n"
|
||||
'test "$1" = verify\n'
|
||||
'test "$2" = before\n'
|
||||
'test "$3" = after\n'
|
||||
f'test "$4" = {manifest}\n'
|
||||
'touch "${PROBE_VERIFIED:?}"\n'
|
||||
)
|
||||
probe.chmod(0o755)
|
||||
env = os.environ.copy()
|
||||
@@ -107,8 +107,7 @@ class TestDatabaseRestoreProbe(unittest.TestCase):
|
||||
)
|
||||
manifest = root / "manifest"
|
||||
manifest.write_text(
|
||||
"postgres;postgres_data;app_pg\n"
|
||||
"mariadb;mariadb_data;app_my\n"
|
||||
"postgres;postgres_data;app_pg\nmariadb;mariadb_data;app_my\n"
|
||||
)
|
||||
fake_bin = root / "bin"
|
||||
fake_bin.mkdir()
|
||||
@@ -116,26 +115,26 @@ class TestDatabaseRestoreProbe(unittest.TestCase):
|
||||
container.write_text(
|
||||
"#!/usr/bin/env bash\n"
|
||||
"set -euo pipefail\n"
|
||||
"case \"$1\" in\n"
|
||||
'case "$1" in\n'
|
||||
" ps)\n"
|
||||
" case \"$*\" in\n"
|
||||
' case "$*" in\n'
|
||||
" *postgres_data*) printf 'postgres.1\\n' ;;\n"
|
||||
" *mariadb_data*) printf 'mariadb.1\\n' ;;\n"
|
||||
" esac\n"
|
||||
" ;;\n"
|
||||
" inspect)\n"
|
||||
" case \"${*: -1}\" in\n"
|
||||
' case "${*: -1}" in\n'
|
||||
" postgres.1) printf 'postgres_custom\\n' ;;\n"
|
||||
" mariadb.1) printf 'mariadb_custom\\n' ;;\n"
|
||||
" esac\n"
|
||||
" ;;\n"
|
||||
" exec)\n"
|
||||
" case \"$*\" in\n"
|
||||
' case "$*" in\n'
|
||||
" *SELECT*before*)\n"
|
||||
" test -f \"${DB_STATE:?}/seeded-${4}\" && printf '1\\n' || printf '0\\n'\n"
|
||||
" ;;\n"
|
||||
" *SELECT*after*) printf '0\\n' ;;\n"
|
||||
" *) touch \"${DB_STATE:?}/seeded-${4}\" ;;\n"
|
||||
' *) touch "${DB_STATE:?}/seeded-${4}" ;;\n'
|
||||
" esac\n"
|
||||
" ;;\n"
|
||||
"esac\n"
|
||||
@@ -147,7 +146,7 @@ class TestDatabaseRestoreProbe(unittest.TestCase):
|
||||
env["DB_STATE"] = str(root)
|
||||
|
||||
subprocess.run(
|
||||
["bash", str(ROLE_TEST_SCRIPTS / "db_probe.sh"), "seed", "before"],
|
||||
["bash", str(ROLE_TEST_SCRIPTS / "db" / "probe.sh"), "seed", "before"],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
@@ -159,7 +158,7 @@ class TestDatabaseRestoreProbe(unittest.TestCase):
|
||||
subprocess.run(
|
||||
[
|
||||
"bash",
|
||||
str(ROLE_TEST_SCRIPTS / "db_probe.sh"),
|
||||
str(ROLE_TEST_SCRIPTS / "db" / "probe.sh"),
|
||||
"verify",
|
||||
"before",
|
||||
"after",
|
||||
@@ -182,10 +181,10 @@ class TestDatabaseWriterQuiesce(unittest.TestCase):
|
||||
docker.write_text(
|
||||
"#!/usr/bin/env bash\n"
|
||||
"set -euo pipefail\n"
|
||||
"case \"$1 $2\" in\n"
|
||||
'case "$1 $2" in\n'
|
||||
" 'stack ls') printf 'docker\\npostgres\\nwordpress\\n' ;;\n"
|
||||
" 'stack services')\n"
|
||||
" case \"$3\" in\n"
|
||||
' case "$3" in\n'
|
||||
" docker) printf 'registry:2\\n' ;;\n"
|
||||
" postgres) printf 'localhost:5000/postgres_custom:17\\n' ;;\n"
|
||||
" wordpress) printf 'wordpress:latest\\n' ;;\n"
|
||||
@@ -200,7 +199,7 @@ class TestDatabaseWriterQuiesce(unittest.TestCase):
|
||||
" printf 'wordpress-task\\twordpress:latest\\n'\n"
|
||||
" ;;\n"
|
||||
" 'stop discourse')\n"
|
||||
" touch \"${DOCKER_STATE:?}/stopped-$2\" \"${DOCKER_STATE:?}/stopped-$3\"\n"
|
||||
' touch "${DOCKER_STATE:?}/stopped-$2" "${DOCKER_STATE:?}/stopped-$3"\n'
|
||||
" ;;\n"
|
||||
" *) printf 'unexpected docker call: %s\\n' \"$*\" >&2; exit 1 ;;\n"
|
||||
"esac\n"
|
||||
|
||||
Reference in new issue
Block a user