mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-24 19:24:16 +00:00
test/e2e: snapshot the appview DB per migration level
Wiping ui.db on every switch also wipes the OAuth sessions and the appview's
oauth_p256/jwt_rsa keys, so each batch cost an interactive
`docker-credential-atcr login`. There are only five distinct migration levels
across the stack (27 for batches 00-08, 28 for 09-11, 29 for 12-13, 32 for 14,
34 for 15), so the DB is snapshotted per level and restored instead of
re-migrated. One login now serves every batch sharing a level.
Also skip the compose pin from val/01 onward: a7c7db6 lands there, so the
branch's own compose already has the shared netns and pinning would drag in
later batches' changes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
5aefa85048
commit
50e77ac7a4
+59
-15
@@ -28,6 +28,8 @@ BRANCH="${1:?usage: val-switch.sh <branch>}"
|
||||
REPO=/home/data/atcr.io
|
||||
PROJECT=atcrio
|
||||
UI_VOLUME=${PROJECT}_atcr-ui
|
||||
SNAPDIR=${ATCR_VAL_SNAPDIR:-$HOME/.cache/atcr-val-snapshots}
|
||||
mkdir -p "$SNAPDIR"
|
||||
|
||||
cd "$REPO"
|
||||
|
||||
@@ -37,18 +39,49 @@ git checkout -- docker-compose.yml 2>/dev/null || true
|
||||
echo "==> checking out ${BRANCH}"
|
||||
git checkout "$BRANCH"
|
||||
|
||||
echo "==> pinning docker-compose.yml to main (dev topology only, do not commit)"
|
||||
git checkout main -- docker-compose.yml
|
||||
# `git checkout <ref> -- <path>` STAGES the file. Left staged, the next commit
|
||||
# on the batch branch silently swallows main's compose file. Unstage it so it
|
||||
# shows as an ordinary working-tree modification.
|
||||
git restore --staged docker-compose.yml
|
||||
# Only batch 00 predates a7c7db6, which is what puts the appview in the hold's
|
||||
# netns so did:web:localhost%3A8080 resolves. From val/01 onward the branch's
|
||||
# own compose already has it, and pinning would drag in later batches' changes.
|
||||
if grep -q 'network_mode: "service:atcr-hold"' docker-compose.yml; then
|
||||
echo "==> branch compose already has the shared netns; no pin needed"
|
||||
else
|
||||
echo "==> pinning docker-compose.yml to main (dev topology only, do not commit)"
|
||||
git checkout main -- docker-compose.yml
|
||||
# `git checkout <ref> -- <path>` STAGES the file. Left staged, the next commit
|
||||
# on the batch branch silently swallows main's compose file. Unstage it so it
|
||||
# shows as an ordinary working-tree modification.
|
||||
git restore --staged docker-compose.yml
|
||||
fi
|
||||
|
||||
echo "==> tearing down appview + its DB volume"
|
||||
# The appview DB only has to match the branch's MIGRATION LEVEL, not the
|
||||
# branch. Across the whole stack there are five distinct levels (27 for batches
|
||||
# 00-08, 28 for 09-11, 29 for 12-13, 32 for 14, 34 for 15), so a per-level
|
||||
# snapshot is reused instead of re-migrating from empty every time.
|
||||
#
|
||||
# This matters because ui.db holds the OAuth sessions AND the appview's
|
||||
# oauth_p256/jwt_rsa keys. Nuking it logs out the registry credential helper, so
|
||||
# a naive wipe-per-switch costs an interactive `docker-credential-atcr login` on
|
||||
# every batch. Restoring a snapshot keeps the session alive across every batch
|
||||
# that shares a level.
|
||||
LEVEL=$(ls pkg/appview/db/migrations/*.yaml 2>/dev/null \
|
||||
| sed -E 's|.*/([0-9]{4})_.*|\1|' | sort -n | tail -1)
|
||||
LEVEL=${LEVEL:-0000}
|
||||
SNAP="$SNAPDIR/ui.level-${LEVEL}.db"
|
||||
echo "==> branch migration level: ${LEVEL}"
|
||||
|
||||
echo "==> tearing down appview"
|
||||
docker compose rm -sf atcr-appview
|
||||
docker volume rm "$UI_VOLUME" 2>/dev/null || echo " (volume already gone)"
|
||||
|
||||
echo "==> starting appview on a fresh DB"
|
||||
if [ -f "$SNAP" ]; then
|
||||
echo "==> restoring DB snapshot for level ${LEVEL} (keeps OAuth sessions alive)"
|
||||
docker run --rm -v "${UI_VOLUME}:/v" -v "$SNAPDIR:/s:ro" alpine sh -c \
|
||||
'rm -f /v/ui.db /v/ui.db-wal /v/ui.db-shm && cp /s/'"$(basename "$SNAP")"' /v/ui.db'
|
||||
else
|
||||
echo "==> no snapshot for level ${LEVEL}; starting from an empty DB"
|
||||
docker volume rm "$UI_VOLUME" 2>/dev/null || echo " (volume already gone)"
|
||||
fi
|
||||
|
||||
echo "==> starting appview"
|
||||
docker compose up -d atcr-appview
|
||||
|
||||
echo "==> waiting for appview to answer on 127.0.0.1:5000"
|
||||
@@ -61,13 +94,24 @@ for i in $(seq 1 90); do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "==> migration level on the fresh DB"
|
||||
docker exec atcr-appview sh -c \
|
||||
'sqlite3 /var/lib/atcr/ui.db "select max(version) from schema_migrations"' 2>/dev/null \
|
||||
|| echo " (db not created yet — check: docker logs atcr-appview)"
|
||||
ACTUAL=$(docker exec atcr-appview sh -c \
|
||||
'sqlite3 /var/lib/atcr/ui.db "select max(version) from schema_migrations"' 2>/dev/null || true)
|
||||
echo "==> migration level on the running DB: ${ACTUAL:-unknown} (expected ${LEVEL#0})"
|
||||
|
||||
# Bank a snapshot for this level so the next batch at the same level restores
|
||||
# instead of re-migrating — and keeps its OAuth sessions.
|
||||
if [ ! -f "$SNAP" ] && [ -n "$ACTUAL" ]; then
|
||||
echo "==> banking a snapshot for level ${LEVEL}"
|
||||
docker exec atcr-appview sh -c \
|
||||
'sqlite3 /var/lib/atcr/ui.db ".backup /var/lib/atcr/ui.snap.db"' \
|
||||
&& docker run --rm -v "${UI_VOLUME}:/v" -v "$SNAPDIR:/s" alpine sh -c \
|
||||
"mv /v/ui.snap.db /s/$(basename "$SNAP")" \
|
||||
&& echo " saved $SNAP"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "branch: $(git log --oneline -1)"
|
||||
echo "compose: pinned to main (expect it to show as modified; leave it unstaged)"
|
||||
echo "migrations: level ${ACTUAL:-?}"
|
||||
echo "appview: http://127.0.0.1:5000 (NOT localhost — that 307s)"
|
||||
echo "hold admin: http://127.0.0.1:8080/admin (OAuth as did:plc:pddp4xt5lgnv2qsegbzzs4xg / evan.jarrett.net)"
|
||||
echo "hold admin: http://127.0.0.1:8080/admin (login again if the hold rebuilt)"
|
||||
echo "registry: docker-credential-atcr login (needed after an empty-DB start)"
|
||||
|
||||
Reference in New Issue
Block a user