feat: add managed NetBird front door - #26
Conversation
|
Thanks for this, it's careful work, and the Tailscale ownership tracking in it is a real improvement I want to keep. I'm declining the NetBird front door, and that's not about the quality of the patch. Collie manages exactly one front door because it's the one I actually run: You're not blocked, though. What the PR does point at fairly is that the README makes Tailscale look mandatory when it's only the default. I'm fixing that with a generic "any other mesh or tunnel" variant covering the proxy requirements, why Two bugs worth having either way. The ownership tracking bricks existing installs.
NetBird credentials land in world-readable argv. The runner passes Those credentials are the only thing between a public URL and a shell, so worth fixing wherever this lands. I'm keeping the ownership tracking. It fixes a real bug in main, where |
feat: own the tailscale serve mapping (supersedes #26)
|
Superseded by #36, which lands the Tailscale ownership tracking with you as commit author, plus the adopt-on-match fix so existing installs survive the upgrade, and Variant E for the bring-your-own-tunnel case. Shipped in 0.16.0. Thanks again for the work, and for the shell test harness in particular. |
`cmd_unserve` ran a blind `tailscale serve --https=443 off` (or `--http=$PORT off`) keyed only off COLLIE_SERVE_MODE. If anything else on the host owned that root mount, `unserve`/`uninstall` silently unpublished it. Publishing had the mirror problem: `tailscale serve --bg … /` REPLACES an existing root handler, so `start` could take over a mapping Collie never created. Record the one mapping we publish in `<config-dir>/tailscale-managed-handler` (`<mode>:<port>|<HostPort>|<proxy>`), and make both directions prove ownership: - publishing refuses when the target root is occupied by a handler we don't own, or when the listener already speaks the opposite protocol; - teardown removes the recorded mapping only when the live root still matches the record, clears the record when the root is already gone, and refuses (keeping the record) when it was replaced out from under us. Also adds scripts/collie-ctl.test.sh, the first test coverage the control script has had. It fakes `tailscale` and `systemctl` on a scratch PATH with a throwaway $HOME, so the lifecycle runs anywhere and touches nothing real. Extracted from AltanS#26, which wrapped this in a NetBird front door that isn't being taken. The NetBird track, COLLIE_FRONT_DOOR and their tests are omitted; COLLIE_SKIP_SERVE stays the proxy switch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The reasoning for declining a second managed front door lived in a PR thread, which is exactly where it would be lost. The next NetBird-shaped proposal — Cloudflare Tunnel, ZeroTier, Twingate — would have re-derived it or quietly reversed it. .adr/ is for decisions that close off an option someone will reasonably propose again: the ones where you find yourself explaining why NOT rather than how. Not for what the code, a test name or CLAUDE.md already says. ADR 0001 records the front-door decision with what was actually measured — the one-line Tailscale coupling in the bridge, the credential leak into argv that PR AltanS#26 demonstrated, and that COLLIE_SKIP_SERVE=1 already made every other tunnel a one-command integration. Also the reversal condition, so it can be superseded deliberately rather than ignored. CLAUDE.md keeps the rule and drops the argument, per the split the folder's README sets out: rules there, reasoning here. Doc-only, no version bump. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
COLLIE_FRONT_DOOR=tailscale|netbird|proxywhile retainingCOLLIE_SKIP_SERVE=1compatibilitynetbird exposemanagement with systemd supervision and a PID-backed fallbackTesting
bash scripts/check-version.shbun run typecheckbun run testcd web && bun run typecheckcd web && bun run testbash -n scripts/collie-ctl.sh scripts/collie-ctl.test.shNotes
0.14.2version/changelog state; this PR does not cut or tag a release