v0.8.04-beta - doctor vraagt het de app in plaats van het af te leiden
Some checks failed
Deploy server-up (dev) / deploy (push) Has been cancelled

Drie keer op rij de verkeerde oorzaak aangewezen voor een lege appslijst, omdat
doctor niet genoeg vertelde om ertussen te kiezen: hij telde regels met ls.

Hij vraagt het nu aan de app zelf en toont het pad letterlijk (repr, dus met
een spatie of regeleinde zichtbaar), of de app die map vindt, en per map of hij
als app meetelt en zo niet waarom.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
This commit is contained in:
Ramon 2026-08-03 22:14:07 +02:00
parent 3300d513a6
commit 2ce42f507d
3 changed files with 64 additions and 3 deletions

View file

@ -1,3 +1,24 @@
# v0.8.04-beta — `--doctor` vraagt het de app in plaats van het af te leiden
Drie keer op rij heb ik de verkeerde oorzaak aangewezen voor een lege
appslijst — een verouderde koppeling, submounts, ontbrekende compose-bestanden —
omdat `--doctor` niet genoeg vertelde om ertussen te kiezen. Hij telde regels
met `ls`, en dat zegt niets over wat de app zelf ziet.
Nu vraagt hij het de app, en toont:
- het pad **letterlijk** (`repr`), dus met een spatie of regeleinde er zichtbaar
in. Zo'n onzichtbaar teken maakt een pad onvindbaar terwijl het er in een log
volkomen normaal uitziet
- of de app die map ook echt vindt — zo niet, dan is dat een fout met de
aanwijzing waar je moet kijken
- **per map of hij als app meetelt**, en zo niet: waarom. Een map zonder
compose-bestand telt niet mee, verdwijnt uit de lijst, en laat zijn containers
onder "handmatig gestart" belanden
Dat is het verschil tussen "Server Up ziet geen enkele stack" en weten wélke map
om welke reden afvalt.
# v0.8.03-beta — Mappen zonder compose-bestand verdwenen geruisloos # v0.8.03-beta — Mappen zonder compose-bestand verdwenen geruisloos
`GET /api/stacks` sloeg elke map zonder compose-bestand over met een kale `GET /api/stacks` sloeg elke map zonder compose-bestand over met een kale

View file

@ -1 +1 @@
0.8.03-beta 0.8.04-beta

View file

@ -1152,14 +1152,31 @@ doorlichten() {
# config wint van de standaard — en dan zie je een lege stacklijst zonder # config wint van de standaard — en dan zie je een lege stacklijst zonder
# dat ergens staat waarom. # dat ergens staat waarom.
stap "Wat Server Up zelf ziet" stap "Wat Server Up zelf ziet"
# Niet zelf redeneren over wat de app ziet, maar het hem vragen. Het pad
# letterlijk (repr, dus mét eventuele spatie of regeleinde erin), of het
# bestaat, en per map of hij als app meetelt. Dat laatste is de vraag die
# ertoe doet: een map die er staat maar niet meetelt, verdwijnt uit de
# lijst én laat zijn containers onder "handmatig gestart" belanden.
_eigen="$($SUDO docker exec -i server-up python - 2>/dev/null <<'PYEOF' || true _eigen="$($SUDO docker exec -i server-up python - 2>/dev/null <<'PYEOF' || true
import json, sys import json, sys
sys.path.insert(0, "/app") sys.path.insert(0, "/app")
try: try:
import core import core
from pathlib import Path
from core import docker
c = core.load() c = core.load()
print(json.dumps({k: c.get(k, "") for k in ruw = str(c.get("LIBRARY_DIR", ""))
("BASE_DIR", "LIBRARY_DIR", "DATA_DIR", "BACKUP_DIR")})) pad = Path(ruw)
uit = {k: c.get(k, "") for k in
("BASE_DIR", "LIBRARY_DIR", "DATA_DIR", "BACKUP_DIR")}
uit["lib_repr"] = repr(ruw)
uit["lib_bestaat"] = pad.is_dir()
uit["mappen"] = []
if pad.is_dir():
for d in sorted(pad.iterdir()):
if d.is_dir() and not d.name.startswith("."):
uit["mappen"].append([d.name, bool(docker.has_compose(d))])
print(json.dumps(uit))
except Exception as e: except Exception as e:
print(json.dumps({"fout": str(e)[:200]})) print(json.dumps({"fout": str(e)[:200]}))
PYEOF PYEOF
@ -1169,8 +1186,31 @@ PYEOF
else else
_lib="$(printf '%s' "$_eigen" | sed -n 's/.*"LIBRARY_DIR": *"\([^"]*\)".*/\1/p')" _lib="$(printf '%s' "$_eigen" | sed -n 's/.*"LIBRARY_DIR": *"\([^"]*\)".*/\1/p')"
_dat="$(printf '%s' "$_eigen" | sed -n 's/.*"DATA_DIR": *"\([^"]*\)".*/\1/p')" _dat="$(printf '%s' "$_eigen" | sed -n 's/.*"DATA_DIR": *"\([^"]*\)".*/\1/p')"
_repr="$(printf '%s' "$_eigen" | sed -n 's/.*"lib_repr": *"\([^"]*\)".*/\1/p')"
log "Stacks: $_lib" log "Stacks: $_lib"
log "Appdata: $_dat" log "Appdata: $_dat"
# Letterlijk, dus met een spatie of regeleinde er zichtbaar in. Zo'n
# onzichtbaar teken maakt het pad onvindbaar terwijl het er goed uitziet.
[ -n "$_repr" ] && log "Letterlijk: $_repr"
case "$_eigen" in
*'"lib_bestaat": false'*)
dok_fout "De app vindt die map niet, ook al staat hij er"
log " Kijk naar 'Letterlijk' hierboven: staat er een spatie of"
log " een regeleinde in het pad? Pas het aan bij Instellingen → Paden." ;;
esac
# Per map: telt hij mee als app? Een map zonder compose-bestand telt niet
# en verdwijnt daarmee uit de lijst.
printf '%s' "$_eigen" \
| sed -n 's/.*"mappen": \[\(.*\)\].*/\1/p' \
| tr ']' '\n' \
| while IFS= read -r _rij; do
_naam="$(printf '%s' "$_rij" | sed -n 's/.*\["\([^"]*\)".*/\1/p')"
[ -n "$_naam" ] || continue
case "$_rij" in
*true*) log " $_naam — telt mee" ;;
*) log " $_naam — GEEN compose-bestand, telt niet mee" ;;
esac
done
if [ -n "$_lib" ]; then if [ -n "$_lib" ]; then
# Bestaat de map daarbinnen überhaupt, en zo ja: staat er hetzelfde # Bestaat de map daarbinnen überhaupt, en zo ja: staat er hetzelfde
# in als erbuiten? Dat laatste is de vraag die ertoe doet. Een bind # in als erbuiten? Dat laatste is de vraag die ertoe doet. Een bind