86 lines
4.4 KiB
Python
86 lines
4.4 KiB
Python
#!/usr/bin/env python3
|
|
"""repoint.py drill|live|status — (release 2026-10-26 copy: TARGET=9202, Homepage family_gate expected) point the box's controller at the drill catalog, or put the saved
|
|
controller.yaml back byte for byte.
|
|
|
|
The drill repo on Gitea is PRIVATE (R-992) and the box holds no catalog credential, so the drill is MIRRORED onto the
|
|
box: a bare git repository in the controller's own data volume, loaded from a git bundle, and
|
|
`git.repo_url: file:///opt/docker/felhom-controller/drill-catalog.git` — the method of
|
|
`audits/burndown-3-2026-10-17/tools/repoint.py`. The first version of this file set repo_url to the Gitea URL and
|
|
believed the repo public; the box's clone then failed („could not read Username", 21:18:11) and the controller ran on
|
|
the templates it already had — the first drill pass proved nothing (README, „Drill fixes").
|
|
|
|
`drill` ends with a POSITIVE check, not the absence of an error: the box's catalog cache must be at the drill's main
|
|
commit, and every `EXPECT` line must be in the box's copy of that template. Prints repo_url, never a token."""
|
|
import os, subprocess, sys, time
|
|
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../catalog-sweep-2026-10-24/tools"))
|
|
os.environ.setdefault("TARGET", "9202")
|
|
import box_walk as w
|
|
|
|
DRILL = "/mnt/5_hdd/felhom.eu/drill/app-catalog-drill"
|
|
VOL = "/var/lib/docker/volumes/felhom-controller-data/_data" # guest path of the controller's data volume
|
|
CVOL = "/opt/docker/felhom-controller" # the same, inside the controller container
|
|
SAVE = f"{VOL}/controller.yaml.pre-release1026-drill"
|
|
MIRROR_URL = f"file://{CVOL}/drill-catalog.git"
|
|
EXPECT = [("n8n/docker-compose.yml", "N8N_DIAGNOSTICS_ENABLED=false"), ("opengist/docker-compose.yml", "256M"), ("homepage/.felhom.yml", "family_gate: true")]
|
|
|
|
|
|
def status():
|
|
print(w.guest(f"""grep -n 'repo_url' {VOL}/controller.yaml; ls -l {SAVE} 2>&1 | tail -1
|
|
docker exec felhom-controller sh -c 'git -C {CVOL}/drill-catalog.git log -1 --format="mirror main %h" main 2>&1;
|
|
git -C {CVOL}/data/catalog-cache log -1 --format="cache HEAD %h" 2>&1; git -C {CVOL}/data/catalog-cache remote get-url origin'"""))
|
|
|
|
|
|
def mirror():
|
|
b = f"/tmp/drill-rel1026-{os.getpid()}.bundle"
|
|
subprocess.run(["git", "-C", DRILL, "bundle", "create", b, "main"], check=True, capture_output=True)
|
|
subprocess.run(["scp", "-q", "-o", "StrictHostKeyChecking=accept-new", b, f"{w._T['ssh']}:{b}"], check=True)
|
|
subprocess.run(w.ssh_args() + [f"pct push {w.GUEST} {b} {VOL}/{os.path.basename(b)} && rm -f {b}"], check=True)
|
|
print(w.guest(f"""set -e
|
|
docker exec felhom-controller sh -c 'test -d {CVOL}/drill-catalog.git || git init -q --bare -b main {CVOL}/drill-catalog.git
|
|
git -C {CVOL}/drill-catalog.git fetch -q {CVOL}/{os.path.basename(b)} +main:main && rm -f {CVOL}/{os.path.basename(b)}
|
|
git -C {CVOL}/drill-catalog.git log -1 --format="mirror main %h" main'"""))
|
|
os.remove(b)
|
|
|
|
|
|
def restart_sync():
|
|
w.guest("docker restart felhom-controller >/dev/null")
|
|
for _ in range(60):
|
|
time.sleep(3)
|
|
try:
|
|
w.login()
|
|
break
|
|
except SystemExit:
|
|
continue
|
|
w.sync_rescan()
|
|
time.sleep(5)
|
|
print(w.guest("docker logs --since 3m felhom-controller 2>&1 | grep -E '\\[sync\\]' | grep -v DEBUG | tail -6 | cut -c1-200"))
|
|
|
|
|
|
def drill():
|
|
head = subprocess.run(["git", "-C", DRILL, "rev-parse", "--short=7", "main"], capture_output=True, text=True).stdout.strip()
|
|
mirror()
|
|
print(w.guest(f"""set -e
|
|
test -f {SAVE} || cp -p {VOL}/controller.yaml {SAVE}
|
|
sed -i -E 's#^(\\s+repo_url: ).*$#\\1{MIRROR_URL}#' {VOL}/controller.yaml
|
|
grep -n 'repo_url' {VOL}/controller.yaml"""))
|
|
restart_sync()
|
|
cache = w.guest(f"docker exec felhom-controller git -C {CVOL}/data/catalog-cache log -1 --format=%h").strip()
|
|
ok = cache.startswith(head)
|
|
for f, want in EXPECT:
|
|
got = w.guest(f"docker exec felhom-controller grep -c -- '{want}' {CVOL}/data/catalog-cache/templates/{f} || true").strip()
|
|
print(f" expect {f} ∋ {want}: {got}")
|
|
ok = ok and got not in ("", "0")
|
|
print(f"drill main {head}, box cache {cache}: " + ("DRILL-CONFIRMED" if ok else "DRILL-NOT-CONFIRMED"))
|
|
sys.exit(0 if ok else 1)
|
|
|
|
|
|
def live():
|
|
print(w.guest(f"""set -e
|
|
cp -p {SAVE} {VOL}/controller.yaml
|
|
cmp {SAVE} {VOL}/controller.yaml && echo RESTORED-IDENTICAL; grep -n 'repo_url' {VOL}/controller.yaml"""))
|
|
restart_sync()
|
|
status()
|
|
|
|
|
|
{"drill": drill, "live": live, "status": status}[sys.argv[1]]()
|