prisma vpn: teardown dies before droplet destroy; fetch leaks its tunnel #664
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Two lifecycle bugs observed 2026-08-19 → 2026-08-21 (droplet idled ~2 days before manual teardown):
vpn downordering:down()runsdetach_zotero_proxy()BEFOREclient.droplets.destroy()._restore_zotero_prefs()raisesPermissionErroron the container-owned (uid 100999)prefs.js, so the droplet destroy + key delete + state wipe never execute. Fix: destroy the droplet first (it is the billable resource), wrap prefs restoration in try/except, and copy via a root-capable path (docker exec into zotero, or sudo) when the direct write fails.fetchleaks its SSH tunnel: the auto-opened port-forward (ssh -fN -L 1080:...) survived the fetch run by ~2 days —-fNdaemonizes, so the CLI's close-on-exit never sees the real PID. Track the daemonized PID (or use-o ControlMaster/ControlPathwith an explicit exit) and kill it in a finally.Manual remediation already done: tunnel killed, droplet 565110236 + ssh key 55643846 deleted via API (204/204),
.state/prisma-vpn/wiped, prefs verified proxy-free.Fixed in
2b71d41. (1) vpn down now destroys the droplet and deletes the account key FIRST, then stops the tunnel, then detaches the Zotero proxy inside try/except (a PermissionError on the container-owned prefs.js is logged, never allowed to skip the destroy or the state wipe); _restore_zotero_prefs falls back to sudo cp/chown the way _rewrite_prefs already wrote. (2) The SSH tunnel is now a Popen child Python owns (ssh -N in a new session, no -f): the PID is recorded before the listener appears, an early exit or a never-ready start kills the child and clears the pid file, so a fetch can no longer leak a daemonized port-forward. Tests: down ordering (destroy → tunnel → detach) and detach-failure resilience, Popen args/early-exit/never-ready, sudo fallback.