De oude logica miste .kube quadlets volledig: het zocht alleen naar .container
bestanden op naam en gebruikte een fragiele pod-naam heuristiek als fallback.
Containers gestart via mediaserver.kube en bookstack.kube werden daardoor
als 'podman' geclassificeerd terwijl ze systemd-beheerd zijn.
PODMAN_SYSTEMD_UNIT label wordt door Podman/systemd automatisch gezet op elke
container gestart via een quadlet (.container, .kube, .pod). Dit is de enige
betrouwbare bron.
Verwijderd: _unit_is_active(), unit_active_cache, _map_pod_to_unit import.
Behouden: find_defined_containers() voor section C (offline containers) en
action routing (start/stop/restart via systemd unit).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Vervang kaart-stijl folder-rijen door compacte, platte rijen (2px padding, geen border)
- Verwijder badge-tellers (📁 N, 📄 N) uit folder-rijen
- Voeg .btn.tiny toe voor kleine actieknoppen (+/✕) in boom
- Alle mappen standaard ingeklapt; localStorage behoudt uitgeklapte staat
- file-entry hover highlight; verwijder bottom-border per rij
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
containers-dashboard geeft Mounts als strings (destination paden).
Volledige mount-info (Type + Name) zit alleen in /containers/inspect/{name}.
Fix: voor containers met niet-lege Mounts parallel inspect ophalen,
daarna filteren op Type === "volume" voor named volume koppeling.
Getest: postgresdb_data → postgres-db, n8n_data → n8n.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Beschrijf dat systemd_user.reachable afgeleid is van helper.ok,
dat de container zelf geen D-Bus/systemctl aanroepen doet, en dat
alle systemctl-acties (incl. daemon-reload) via de helper-socket lopen.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- podman-helper: voeg daemon-reload toe aan ALLOWED_ACTIONS; actions
in NO_UNIT_ACTIONS slaan unit-validatie over en bouwen cmd zonder
unit argument
- app_system: /daemon-reload endpoint gebruikt nu _helper_call in
plaats van directe subprocess; verwijder subprocess import
- app_system: health check legt systemd_reachable af van helper_ok
in plaats van systemctl --user list-units — de helper draait als
host-user en impliceert systemd bereikbaarheid
- CLAUDE.md: verwijder DBUS_SESSION_BUS_ADDRESS env var; D-Bus mount
is niet meer nodig
Deploy: kopieer podman-helper.py naar host, daemon-reload, restart
helper, rebuild backend image, herstart container zonder bus mount.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Vervangt file bind-mount door directory mount om stale inode probleem
op te lossen: bij file bind-mounts bindt Podman de inode op run-tijd;
als podman-helper stopt en de socket verwijdert, wijst de container
nog steeds naar de verwijderde inode. Een directory mount lost altijd
op naar de huidige mapinhoud inclusief nieuwe inodes.
Wijzigingen:
- podman-helper.py: SOCKET_PATH → XDG_RUNTIME_DIR/podman-mvp/podman-helper.sock
- common.py: HELPER_SOCKET → /run/podman-mvp/podman-helper.sock
- CLAUDE.md: run-commando gebruikt -v /run/user/1000/podman-mvp:/run/podman-mvp
Deploy: kopieer podman-helper.py naar host, daemon-reload, restart helper,
rebuild backend image, herstart container met nieuwe mount.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ExecStopPost=-/bin/rm -f ${XDG_RUNTIME_DIR}/podman-helper.sock verwijderde
het socketbestand bij stoppen. Hierdoor werd bij herstart een nieuw inode
aangemaakt, terwijl de container-bind-mount nog het oude inode vasthield
(stale mount). Gevolg: health check en _helper_call faalden na herstart
ook al was de helper running.
De cleanup is overbodig: podman-helper.py doet os.unlink() bij opstarten
(regel 153) en bij afsluiten via finally-block (regel 178).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend (/api/health):
- Importeer HELPER_SOCKET uit common.py
- Voeg helper-check toe: connect() op /run/podman-helper.sock, timeout=2s
- ok blijft true als alleen de helper ontbreekt (waarschuwing, geen fout)
- Nieuwe response key: "helper": {"ok": bool}
Frontend (pingApi / setApiState):
- pingApi() roept nu /api/health aan i.p.v. /pods-dashboard
- setApiState(state, msg) accepteert 'ok' / 'warn' / 'error'
- Gele dot met --warn kleur als helper.ok=false maar core OK
- refreshActive() delegeert statusupdate aan pingApi()
- Detailbericht bij fout: toont welk component (podman/systemd) faalt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Swagger UI v5.32.1 lokaal in assets/swagger-ui/ (geen CDN, offline bruikbaar)
- webui/html/docs/index.html: custom pagina die /api/openapi.json laadt
met requestInterceptor zodat Try it out via same-origin werkt
- Link toegevoegd aan dashboard "Snel acties": API docs ↗ (opent in nieuw tabblad)
- Docstrings toegevoegd aan destructieve endpoints (app_containers, app_images):
container stop/restart, image remove (batch + single), image prune
geven nu ⚠️-waarschuwingen in de Swagger UI beschrijving
- Backend rebuild nodig voor docstrings zichtbaar in spec
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Verwijder phase-3 hex-ID fallback (~160 regels): NetworkSettings.Networks
uit container inspect is de ground truth, niet netwerk-inspect + scannen
- Filter infra containers via IsInfra flag + naam-regex ^[0-9a-f]+-infra$
- Voeg IP en aliases toe aan byNetwork container entries (via inspect)
- Bridge containers krijgen altijd een inspect-call voor IP/aliases;
pasta/host/none containers worden overgeslagen
- D3 v7.9.0 lokaal gebundeld (assets/js/d3.min.js, CDN-afhankelijkheid weg)
- Nieuw webui/Containerfile voor reproduceerbare webui image builds
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
De frontend haalde CPU/mem stats op via het zware /containers-dashboard
endpoint (Podman call + os.walk + systemctl subprocesses per container).
Nu gaat de stats poll via een nieuw /api/stats endpoint dat alleen de
bestaande in-memory cache teruggeeft (<5ms vs ~400ms).
- app_containers.py: /api/stats endpoint toegevoegd (cache direct return)
- app_containers.py: _STATS_SHOWN_NAMES bijgehouden per dashboard call
(filtert infra/management containers eruit op basis van _dashboard_source)
- containers.js: pollContainersDashboardStatsOnce() gebruikt /api/stats
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
start/stop/restart van systemd units gaan nu via de host-helper
(/run/podman-helper.sock) in plaats van directe systemctl subprocess
vanuit de container. Hiermee wordt de user namespace isolatie omzeild
die D-Bus calls vanuit de container onbetrouwbaar maakt.
- common.py: _helper_call(action, unit) toegevoegd
- app_system.py: /{action}/{unit} route gebruikt helper voor start/stop/restart
- app_containers.py: container_action() gebruikt helper
- daemon-reload en is-active blijven subprocess (read-only, werkt al)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
run() stond identiek in app.py en app_system.py. Verplaatst naar
common.py als single source of truth; beide modules importeren
nu de centrale versie.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
De route @router.post("/api/<action>/<unit>") gebruikte Flask-syntaxis
die nooit matcht in FastAPI. Dead code verwijderd.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Drie endpoints gebruikten os.path.join zonder validatie, waardoor een
aanvaller buiten WORKLOADS_DIR kon lezen/schrijven. Vervangen door de
bestaande _files_safe_join() helper die al door alle /files/ endpoints
werd gebruikt.
Endpoints: /workloads/read/, /workloads/save-file, /workloads/deploy/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
/api/pods-dashboard genereerde onterecht 'pod<basename>' entries voor .container Quadlet-bestanden, wat leidde tot lege nep-pods zoals 'podn8n' in de WebUI.
Alleen echte pod-workloads (.pod, evt. .kube) mogen nog een Source:"systemd" pod-row opleveren.
Geen endpoint- of schemawijzigingen. Alleen filtering in control/app_pods.py aangepast.