diff --git a/CHANGELOG.md b/CHANGELOG.md index f907edf..020b1b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ +# v0.7.99-beta — "Gekoppeld" zei niets + +`--doctor` meldde vrolijk dat `/opt/serverup` in de container gekoppeld was, +terwijl Server Up daar geen enkele app zag en er buiten de container drie +stonden. De controle keek of het pad in `/proc/self/mountinfo` voorkwam, en dat +is precies de verkeerde vraag. + +Een bind mount wijst naar een **inode**, niet naar een pad. Wordt de map op de +host vervangen nadat de container is aangemaakt — verwijderd en opnieuw +aangemaakt — dan blijft de container naar de oude, losgekoppelde map kijken. +Meestal is die leeg. Het pad staat dan nog gewoon in de mountlijst, dus +"gekoppeld" blijft er stralend staan terwijl je hele appslijst leeg is. + +`--doctor` telt nu aan beide kanten en vergelijkt: + +- bestaat de map binnen de container überhaupt? +- staan er buiten wél apps en binnen niet? Dan is de koppeling verouderd, en + staat erbij hoe je hem herstelt (`docker compose up -d --force-recreate`) +- is hij aan beide kanten leeg, dan is er simpelweg nog niets geïnstalleerd — + een waarschuwing, geen fout + # v0.7.98-beta — Het heet nu gewoon een app Je installeerde een **app** uit de **App Store** en kreeg een **stack**. Dat diff --git a/VERSION b/VERSION index 7052c3c..0c6793f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.98-beta +0.7.99-beta diff --git a/install.sh b/install.sh index 36d6fbb..33662d3 100755 --- a/install.sh +++ b/install.sh @@ -1172,16 +1172,32 @@ PYEOF log "Stacks: $_lib" log "Appdata: $_dat" if [ -n "$_lib" ]; then - _n="$($SUDO docker exec server-up sh -c \ - "ls -1 '$_lib' 2>/dev/null | wc -l" 2>/dev/null || echo 0)" - _n="$(printf '%s' "$_n" | tr -d '[:space:]')" - if [ "${_n:-0}" -gt 0 ] 2>/dev/null; then - dok_ok "$_n stack(s) zichtbaar voor Server Up" + # Bestaat de map daarbinnen überhaupt, en zo ja: staat er hetzelfde + # in als erbuiten? Dat laatste is de vraag die ertoe doet. Een bind + # mount wijst naar een inode, niet naar een pad: is de map op de + # host ná het aanmaken van de container vervangen, dan blijft de + # container naar de oude — meestal lege — map kijken. Het pad staat + # dan nog gewoon in /proc/self/mountinfo, dus "gekoppeld" zegt niets. + if ! $SUDO docker exec server-up test -d "$_lib" 2>/dev/null; then + dok_fout "De map $_lib bestaat niet binnen de container" + log " Hercreëer de container: $SUDO docker compose -f $DOEL/docker-compose.yml up -d --force-recreate" else - dok_fout "Server Up ziet geen enkele stack in $_lib" - [ "$_lib" != "$_basis/stacks" ] \ - && log " Je stacks staan waarschijnlijk in $_basis/stacks." \ - && log " Pas LIBRARY_DIR aan bij Instellingen → Paden." + _n="$($SUDO docker exec server-up sh -c \ + "ls -1A '$_lib' 2>/dev/null | wc -l" 2>/dev/null || echo 0)" + _n="$(printf '%s' "$_n" | tr -d '[:space:]')" + _h="$(ls -1A "$_lib" 2>/dev/null | wc -l)" + _h="$(printf '%s' "$_h" | tr -d '[:space:]')" + if [ "${_n:-0}" -gt 0 ] 2>/dev/null; then + dok_ok "$_n app(s) zichtbaar voor Server Up" + elif [ "${_h:-0}" -gt 0 ] 2>/dev/null; then + dok_fout "Buiten de container staan er $_h in $_lib, binnen de container geen" + log " De koppeling wijst naar een oudere map dan die er nu staat." + log " Dat gebeurt als $_basis op de host is vervangen nadat de" + log " container was aangemaakt. Hercreëren lost het op:" + log " $SUDO docker compose -f $DOEL/docker-compose.yml up -d --force-recreate" + else + dok_waar "Er staat nog geen enkele app in $_lib" + fi fi fi # De app store leest uit de git-cache; is die leeg, dan is de lijst leeg. diff --git a/tests/test_install_script.py b/tests/test_install_script.py index dd78ea7..5b021cb 100644 --- a/tests/test_install_script.py +++ b/tests/test_install_script.py @@ -1171,3 +1171,30 @@ def test_reconfigure_zonder_installatie_stopt(tmp_path): r = _draai("--reconfigure", "--dir", str(tmp_path / "bestaatniet")) assert r.returncode != 0 assert "Geen installatie gevonden" in r.stderr + + +# ── Een koppeling die er is maar niets laat zien ───────────────────────────── +# Een bind mount wijst naar een inode, niet naar een pad. Wordt de map op de +# host vervangen nadat de container is aangemaakt, dan kijkt de container naar +# de oude — meestal lege — map. Het pad staat dan nog gewoon in +# /proc/self/mountinfo, dus alleen daarop controleren zegt niets. + +def test_doctor_vergelijkt_beide_kanten_van_de_koppeling(): + tekst = SCRIPT.read_text(encoding="utf-8") + blok = tekst[tekst.index("Wat Server Up zelf ziet"):] + blok = blok[:blok.index("\n printf ")] + assert "ls -1A" in blok, "de inhoud wordt nergens geteld" + assert blok.count("ls -1A") >= 2, \ + "er wordt maar aan één kant geteld; juist het verschil is de diagnose" + assert "--force-recreate" in blok, "er staat geen uitweg bij" + + +def test_doctor_onderscheidt_ontbrekend_van_leeg(): + """"De map bestaat niet in de container" en "de map is leeg" hebben een + andere oorzaak en een andere oplossing.""" + tekst = SCRIPT.read_text(encoding="utf-8") + blok = tekst[tekst.index("Wat Server Up zelf ziet"):] + blok = blok[:blok.index("\n printf ")] + assert "test -d" in blok, "er wordt niet gekeken of de map er is" + assert "bestaat niet binnen de container" in blok + assert "nog geen enkele app" in blok