Date: 2026-02-25 Status: Completed Origin: MDF Webseiten session 0054
OPS_CLI path in run_job() — nsenter couldn't find the ops commandOPS_CLI bug in restore.py _stream_to_job()PYTHONUNBUFFERED=1 to _NSENTER_PREFIXstdin=asyncio.subprocess.DEVNULL to prevent docker run -i blockingschedule.py hard-coded /usr/local/bin/ops path — replaced with OPS_CLI constantrun_job() (command start, subprocess PID, exit code)docker exec missing -it flags — shell was exiting immediately with code 0gen-timers wasn't expanding {env} in custom command templates| Bug | Root Cause | Fix |
|-----|-----------|-----|
| nsenter: can't execute 'backup' | run_job() missing OPSCLI prefix | Added `[OPSCLI] to full_args` |
| Backup produces 0 lines | Python stdout buffered through pipe | Added PYTHONUNBUFFERED=1 to nsenter prefix |
| docker run -i hangs | stdin inherited from server process | stdin=asyncio.subprocess.DEVNULL |
| Terminal exits immediately (code 0) | docker exec missing -it flags | Added -it to exec command |
| MDF backups not running (2 nights) | gen-timers: {env} never expanded in custom command | Loop over envs + .replace("{env}", env) |
PYTHONUNBUFFERED=1 is essential whenever running Python via nsenter pipe — buffering silently swallows all outputstdin=asyncio.subprocess.DEVNULL is required for non-interactive subprocess calls from async context9e13f76 — feat: ops dashboard v15 — persistent jobs + container terminal (Webseiten repo)4e65e9e — fix: gen-timers expand {env} placeholder in custom backup commands (infrastructure repo)Tags: #Session #OpsDashboard #Debug #Deployment