186546d562
gates / gates (push) Successful in 27s
All 28 walked on scratch guest 9202 against the private drill catalog. 26 deployed, 6 proven, 5 inconclusive, 14 with no upstream edge, 1 failed honestly (outline 1.9.1->1.10.1, HELD with the right sentence), 2 undeployable - one (plant-it) by design, refused by the lifecycle gate, proven live for the first time. Each app also got the half the update night skipped: a restore from its own copy with the seed read back again - 21 restored, 2 correctly REFUSED per 07 6.2. R-630 RAISED TO P1 by measurement: a stack with NO probe container does not skip verifying - it waits out the full health timeout and HOLDS, stopping an app whose three containers read healthy. The controller's own words: "not healthy within 5m0s (last: no probe container)". R-633 opened: a remove sent during a restore reports success and leaves a container restarting with a live public route. The product already refuses that clash for update and for restore, naming the blocker; remove has no such guard. R-634 opened: an app can be running, healthy and serving while recorded as deployed=false, and is then unremovable. Reproducible alone on sparkyfitness; concurrency-linked on two others. R-631 and R-632 CLOSED. Register 321 -> 323. Seven interventions, six of them my own harness - named, with what each cost. No product code. The live catalog's image: lines are byte-identical to the start of the night. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
52 lines
1.8 KiB
Python
52 lines
1.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Point guest 9202 at the drill catalog, or back at the live one (09 §6.5, R-615).
|
|
|
|
`git.repo_url` alone is INERT: `Syncer.gitCloneOrPull` clones only when the cache has no `.git`,
|
|
otherwise it fetches from the remote the existing clone stores. The cache directory must be removed
|
|
too, or the box goes on following the live catalog AND REPORTS SUCCESS. That is R-615, and it is why
|
|
step 3 exists.
|
|
"""
|
|
import re, sys, io
|
|
sys.path.insert(0, '.')
|
|
import walk as w
|
|
|
|
VOL = "/var/lib/docker/volumes/felhom-controller-data/_data"
|
|
LIVE = "https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git"
|
|
DRILL_REPO = "https://gitea.dooplex.hu/admin/app-catalog-drill.git"
|
|
|
|
|
|
def creds():
|
|
for l in io.open("/home/kisfenyo/.git-credentials").read().strip().split("\n"):
|
|
m = re.match(r'https://(admin):([^@]+)@gitea\.dooplex\.hu', l)
|
|
if m:
|
|
return m.group(1), m.group(2)
|
|
raise SystemExit("no admin credential for gitea.dooplex.hu")
|
|
|
|
|
|
def repoint(to_drill):
|
|
u, t = creds() if to_drill else ("", "")
|
|
url = DRILL_REPO if to_drill else LIVE
|
|
script = f"""
|
|
set -e
|
|
test -f {VOL}/controller.yaml.pre-28 || cp {VOL}/controller.yaml {VOL}/controller.yaml.pre-28
|
|
python3 - <<'EOF'
|
|
import re
|
|
p = "{VOL}/controller.yaml"
|
|
s = open(p).read()
|
|
s = re.sub(r'(^\\s+repo_url: ).*$', r'\\g<1>{url}', s, count=1, flags=re.M)
|
|
s = re.sub(r'(^\\s+token: ).*$', r'\\g<1>"{t}"', s, count=1, flags=re.M)
|
|
s = re.sub(r'(^\\s+username: ).*$', r'\\g<1>"{u}"', s, count=1, flags=re.M)
|
|
open(p, "w").write(s)
|
|
EOF
|
|
# R-615: the cache is the thing that actually decides which remote is fetched.
|
|
rm -rf {VOL}/catalog-cache {VOL}/data/catalog-cache
|
|
docker restart felhom-controller >/dev/null
|
|
sleep 12
|
|
grep -A6 '^git:' {VOL}/controller.yaml | sed 's/token:.*/token: <redacted>/'
|
|
"""
|
|
print(w.guest(script))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
repoint(sys.argv[1] == "drill")
|