Part C: R-644, R-763, R-764 closed (wger's fixes proven on 9202), R-762/R-717 stopped with reasons; STATUS, CONTEXT, REPORT (142 -> 137; 0 opened, 5 closed)
gates / gates (push) Successful in 2m43s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-06 14:03:28 +02:00
parent a29ee9dd33
commit 01d5dbd3e0
10 changed files with 280 additions and 64 deletions
@@ -0,0 +1,45 @@
lifecycle on the box: None deployed=False
settings read by wger's own process:
before: NameError: name 'USERS' is not defined
stranger, straight at the app: GET registration: 302 http://172.18.0.6:8000/en/software/features
stranger, straight at the app: POST registration: 403
stranger, straight at the app: anonymous GET dashboard 1: 302 http://172.18.0.6:8000/user/login?next=/en/dashboard
stranger, straight at the app: anonymous GET dashboard 2: 302 http://172.18.0.6:8000/user/login?next=/en/dashboard
stranger, straight at the app: static css: 404
stranger, straight at the app: static root size: 4.0K /home/wger/static
after: NameError: name 'USERS' is not defined
stranger account exists: STRANGER False
restarts: 0 healthy
read 1: level=INFO ts=2026-10-06 13:56:58,292 module=apps path=/home/wger/.local/lib/python3.12/site-packages/axes/apps.py line=53 message=AXES: BEGIN version 8.3.1, blocking by username
SETTINGS ALLOW_REGISTRATION=False ALLOW_GUEST_USERS=False EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend ENABLE_EMAIL-env=False DEBUG=False
USERS 1 ['admin']
anonymous GET /en/dashboard 1: 302 http://172.18.0.6:8000/user/login?next=/en/dashboard
anonymous GET /en/dashboard 2: 302 http://172.18.0.6:8000/user/login?next=/en/dashboard
anonymous GET /en/dashboard 3: 302 http://172.18.0.6:8000/user/login?next=/en/dashboard
anonymous GET /en/user/demo-entries: 302 http://172.18.0.6:8000/en/software/features
read 2: level=INFO ts=2026-10-06 13:57:06,003 module=apps path=/home/wger/.local/lib/python3.12/site-packages/axes/apps.py line=53 message=AXES: BEGIN version 8.3.1, blocking by username
SETTINGS ALLOW_REGISTRATION=False ALLOW_GUEST_USERS=False EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend ENABLE_EMAIL-env=False DEBUG=False
USERS 1 ['admin']
GET login (for a CSRF cookie): 200
csrf cookie: yes
POST registration with a valid CSRF: 302 http://172.18.0.6:8000/en/software/features
CONTROL - POST login with the same CSRF and a wrong password: 200
USERS 1
settings loaded with the mail toggle's injection (ENABLE_EMAIL=True, EMAIL_HOST set), in the running wger:
/home/wger/src/settings/main.py:117: UserWarning: JWT_PRIVATE_KEY / JWT_PUBLIC_KEY are not set. JWT authentication will not work until you run `./manage.py generate-jwt-keys` and add the output to your environment.
warnings.warn(
MAIL-ON SETTINGS: ENABLE_EMAIL-env=True EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend EMAIL_HOST=felhom-relay.invalid EMAIL_PORT=2526 USE_TLS=False
rc=0
Traceback (most recent call last):
File "<stdin>", line 14, in <module>
File "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts/box_walk.py", line 502, in remove
c1, d1 = ctl("POST", f"/api/stacks/{name}/stop")
~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts/box_walk.py", line 88, in ctl
sess = open(f"{SC}/sess{os.getpid()}.txt").read().strip()
~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/claude-1000/-mnt-5-hdd-felhom-eu-git/da0e2df0-3072-4d3e-bf10-c475ac1e5ae4/scratchpad/sc890/sess4190727.txt'
13:58:17 [X] stop -> 200 {'ok': True, 'message': 'Stack wger stop completed'}
13:58:49 [X] remove (with drive data) -> 200 {'ok': True, 'data': {'removed': 'wger', 'volumes_removed': ['wger_wger_data', 'wger_wger_media'], 'hdd_paths_removed': [], 'hdd_paths_preserved': [], 'hdd_note
13:58:57 [X] after remove: deployed=False leftovers='/opt/docker/stacks/wger'
remove -> 200
@@ -21,3 +21,9 @@ harness); the bench has 0 containers and is stopped.
## Part C
- R-644: `C/R-644-9202-live.txt` — no gokapi on 9202 any more.
- R-763 / R-764 / R-762: `C/wger.txt` (`tools/wgerwalk.py`; wger un-hidden in the DRILL only, removed after).
## Teardown
`box/T1-repoint-live.txt` (9202 back on the live catalog, byte-identical `controller.yaml`; the same six containers),
`box/T2-drill-reset.txt` (drill = live).
@@ -0,0 +1,11 @@
26: repo_url: https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
3
RESTORED-IDENTICAL
0
filebrowser Up 5 hours (healthy)
felhom-controller Up 16 seconds (healthy)
paperless-webserver Up 11 hours (healthy)
paperless-postgres Up 11 hours (healthy)
paperless-redis Up 11 hours (healthy)
traefik Up 28 hours
@@ -0,0 +1 @@
drill=ecb8552 live=ecb8552
@@ -0,0 +1,62 @@
"""wgerwalk.py — R-763 / R-764 / R-762 on scratch 9202 (drill catalog = live + wger un-hidden, DRILL only).
Install wger through the product, then, STRAIGHT AT THE APP inside the box (a stranger who got past the box's own gate —
the strictest case; the family gate would stop him first): the sign-up page and form, two anonymous dashboard visits,
the user count before and after (wger's own ORM). The settings wger read (its own process). The static and media read
(R-762). Removed through the product at the end. Evidence: ../C/wger.txt."""
import os, sys
sys.path.insert(0, "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts")
import box_walk as w
HERE = os.path.dirname(os.path.abspath(__file__))
log = open(os.path.join(HERE, "..", "C", "wger.txt"), "a", buffering=1)
def say(*a):
w.say(*a); log.write(" ".join(map(str, a)) + "\n")
ORM = ("cd /home/wger/src && DJANGO_SETTINGS_MODULE=settings.main python3 -c "
"\"import django; django.setup(); from django.contrib.auth.models import User; print('USERS', User.objects.count())\"")
SETTINGS = ("cd /home/wger/src && DJANGO_SETTINGS_MODULE=settings.main python3 -c "
"\"import django; django.setup(); from django.conf import settings as s; "
"print('ALLOW_REGISTRATION', s.WGER_SETTINGS.get('ALLOW_REGISTRATION'), 'ALLOW_GUEST_USERS', s.WGER_SETTINGS.get('ALLOW_GUEST_USERS'), "
"'EMAIL_BACKEND', s.EMAIL_BACKEND, 'DEBUG', s.DEBUG)\"")
def users():
out = w.guest(f"docker exec wger sh -c '{ORM}' 2>&1 | tail -1")
return out.strip()
STRANGER = r"""set -u
ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}} {{end}}' wger | awk '{print $1}')
H="Host: fitness.enkisfelhom.hu"; P="X-Forwarded-Proto: https"
J=$(mktemp)
echo "GET registration: $(curl -s -o /dev/null -c $J -b $J -H "$H" -H "$P" -w '%{http_code} %{redirect_url}' http://$ip:8000/en/user/registration)"
tok=$(grep csrftoken $J | awk '{print $7}')
echo "POST registration: $(curl -s -o /dev/null -c $J -b $J -H "$H" -H "$P" -H "Referer: https://fitness.enkisfelhom.hu/en/user/registration" -w '%{http_code} %{redirect_url}' --data "csrfmiddlewaretoken=$tok&username=stranger1&email=stranger1@gate.invalid&password1=Str4nger-Pass-991&password2=Str4nger-Pass-991" http://$ip:8000/en/user/registration)"
rm -f $J
for i in 1 2; do echo "anonymous GET dashboard $i: $(curl -s -o /dev/null -H "$H" -H "$P" -w '%{http_code} %{redirect_url}' http://$ip:8000/en/dashboard)"; done
echo "static css: $(curl -s -o /dev/null -H "$H" -H "$P" -w '%{http_code}' http://$ip:8000/static/css/workout-manager.css)"
echo "static root size: $(docker exec wger du -sh /home/wger/static 2>&1 | tail -1)"
"""
w.login()
w.sync_rescan("wger")
st = w.stack("wger")
say(f"lifecycle on the box: {(st.get('metadata') or {}).get('lifecycle')} deployed={st.get('deployed')}")
if not w.deploy("wger", "fitness"):
sys.exit(say("RESULT install did not complete") or 1)
w.wait_app("fitness", "/", tries=60)
say("settings read by wger's own process:", w.guest(f"docker exec wger sh -c \"{SETTINGS}\" 2>&1 | tail -1").strip())
say("before:", users())
for line in w.guest(STRANGER).strip().splitlines():
say(" stranger, straight at the app:", line)
say("after:", users())
say("stranger account exists:", w.guest("docker exec wger sh -c \"cd /home/wger/src && DJANGO_SETTINGS_MODULE=settings.main python3 -c "
"\\\"import django; django.setup(); from django.contrib.auth.models import User; "
"print('STRANGER', User.objects.filter(username='stranger1').exists())\\\"\" 2>&1 | tail -1").strip())
say("restarts:", w.guest("docker inspect -f '{{.RestartCount}} {{.State.Health.Status}}' wger").strip())
if not os.environ.get("KEEP"):
say(f"remove -> {w.remove('wger')}")