Skip to content

Privileged daemon and autostart subcommands for a single binary installation - #8

Merged
pansen merged 7 commits into
mainfrom
feat/andi/daemon_installer
Jul 19, 2026
Merged

Privileged daemon and autostart subcommands for a single binary installation#8
pansen merged 7 commits into
mainfrom
feat/andi/daemon_installer

Conversation

@pansen

@pansen pansen commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Summary

Moves the last two pieces of daemon/agent lifecycle management out of the Makefile and into the tunmux binary itself, so a single-binary distribution (e.g. a Homebrew bottle) no longer depends on shell scripting for install/uninstall. Also fixes a few liveness/status consistency issues surfaced along the way.

New commands

tunmux launchd install|restart|uninstall

Registers, restarts, and unregisters the privileged system daemon (me.pansen.tunmux.privileged) as a macOS LaunchDaemon. install (run via sudo) creates the tunmux group, sets up the socket/log directories, renders and installs the daemon's plist, and bootstraps it into the system domain. restart kickstarts the running daemon; uninstall boots it out and removes the plist while leaving the binary, group, and logs in place.

tunmux autoconnect install|reload|uninstall|list (alias ls)

Registers, reloads, unregisters, and lists the per-user autoconnect LaunchAgent (me.pansen.tunmux.autoconnect), which keeps a chosen WireGuard profile connected at login. Runs unprivileged (never via sudo) in the user's GUI domain.

  • install --file <path> or install --profile <name> renders and installs the agent's plist, then bootstraps and kicks it. Fails if an agent is already installed, unless --force is given, in which case it overwrites the plist and reloads unconditionally — protecting an existing autoconnect profile from being silently clobbered.
  • reload kickstarts the currently installed agent.
  • uninstall boots it out and removes its plist.
  • list/ls shows every installed agent with its load state (🟢 active / 🔘 inactive) and the profile it connects.

tunmux status

Reworked to show connections from the privileged daemon, with liveness now checked consistently across all backends (not just userspace) so stale entries from a reboot/crash aren't reported as active.

Other fixes

  • The userspace liveness probe now retries only on genuine transport/cold-start errors, instead of any error, so it settles faster and doesn't mask authoritative failures.
  • status's direct-tunnel check now goes through the same cold-start-aware probe used elsewhere, instead of a raw client call, so a briefly-idle-exited daemon doesn't make a live tunnel look down.

Copilot AI review requested due to automatic review settings July 19, 2026 09:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds first-class launchd and autoconnect subcommands to manage a privileged on-demand daemon and a per-user LaunchAgent from the tunmux binary itself, reducing Makefile duplication and improving resilience around userspace tunnel state.

Changes:

  • Add tunmux launchd install|restart|uninstall with plist templating, binary-location validation, and setup of group/dirs/plist/bootstrapping.
  • Add tunmux autoconnect install|list|reload|uninstall with plist templating, atomic writes, and GUI-domain launchctl management.
  • Harden userspace liveness probing and add “adopt live wgconf0 without saved state” recovery for desync scenarios; update status output formatting.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/wireguard/userspace.rs Adds retrying userspace interface liveness probe via privileged daemon.
src/wgconf/handlers.rs Re-adopts a live wgconf0 interface by recreating missing saved state.
src/main.rs Adds top-level dispatch for new subcommands; improves status rendering and attempts to reconcile live wgconf0.
src/lib.rs Exposes new autoconnect, launchctl, and launchd modules from the library crate.
src/launchd.rs Implements privileged daemon launchd installer/uninstaller with template rendering and safety checks.
src/launchctl.rs Shared helpers for running launchctl, atomic file removal, and XML escaping.
src/cli.rs Adds launchd and autoconnect subcommands and parsing tests.
src/autoconnect.rs Implements per-user autoconnect LaunchAgent installer/list/reload/uninstall.
Makefile Delegates privileged/autostart install/reload/uninstall flows to the tunmux binary.
etc/me.pansen.tunmux.privileged.plist Switches to install-time placeholders for binary path and socket group.
etc/me.pansen.tunmux.autoconnect.plist Switches to install-time placeholders for binary path, HOME, and connect source.
doc/launchd-socket-activation.md Updates documentation to reflect Makefile delegation to tunmux launchd.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/wireguard/userspace.rs
Comment thread src/main.rs
Comment thread src/main.rs Outdated
@pansen
pansen merged commit 5efd8fc into main Jul 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants