Documentation
¶
Overview ¶
Package service installs and removes the flue login service: a launchd agent on darwin, a systemd user unit on linux. It is self-contained — cmd/flue consumes it and nothing else does — and every interaction with a real service manager goes through the Runner seam so tests never touch one.
Index ¶
Constants ¶
const LaunchdLabel = "sh.flue.daemon"
LaunchdLabel is the launchd service label and the plist's basename.
Variables ¶
var ErrNoUserManager = errors.New("service: systemd user services are not available here (no user manager — common on WSL)")
ErrNoUserManager reports that systemctl --user has nobody to talk to — the common WSL shape. The CLI turns this into a one-line pointer at `flue serve`; it is never a stack trace.
var ErrUnsupported = errors.New("service: no login-service support on this platform")
ErrUnsupported reports a platform with no login-service support. flue ships darwin and linux; WSL is linux with, usually, no user manager — which is ErrNoUserManager at Enable time, not this.
Functions ¶
func LaunchdPlist ¶
LaunchdPlist renders the launchd agent plist that runs `exe serve` at login. exe is the path os.Executable reports, symlinks left intact — for a brew cask install that is the stable /opt/homebrew/bin/flue symlink, not the version-pinned Caskroom target that `brew upgrade` deletes.
func SystemdUnit ¶
SystemdUnit renders the systemd user unit that runs `exe serve` at login. The path is double-quoted for systemd's ExecStart lexer, and % is doubled because ExecStart expands specifiers.
Types ¶
type Launchd ¶
type Launchd struct {
// contains filtered or unexported fields
}
Launchd manages the login service through launchctl on darwin.
func (*Launchd) Disable ¶
Disable boots the agent out and removes the plist. Both halves tolerate absence: a bootout of an unloaded label and a remove of a missing file are what "already disabled" looks like, and that is a success.
func (*Launchd) Enable ¶
Enable writes the plist and bootstraps it — the modern spelling, not `launchctl load`. When the label is already bootstrapped, bootstrap refuses; whether that is convergence depends on whether the plist just changed. launchd reads a plist only at bootstrap, so a loaded job keeps its old definition no matter what Enable writes to disk: when the render differs from what was there (a new binary path after an upgrade), Enable must bootout the stale job and bootstrap the fresh plist — restarting the daemon on purpose, because the old job would exec a path that may no longer exist. When the plist is byte-identical, the loaded job already matches, so Enable only verifies the label is loaded (print) and kickstarts it in case it is dead. kickstart without -k never restarts a running service, which is what keeps a no-op re-run of flue enable from killing live sessions.
type Manager ¶
Manager installs, removes, and inspects the flue login service.
- Enable converges: it rewrites the unit if it drifted, loads it if it is not loaded, and starts it if it is dead — without restarting a healthy daemon, whose sessions must survive a re-run of flue enable.
- Disable is idempotent: disabling what is not enabled is nil.
type Runner ¶
Runner executes one service-manager command and returns its combined output. It exists so the command flows are testable against a fake and so CI never touches a real launchd or systemd.
type Status ¶
type Status struct {
Installed bool // the unit file is on disk
Running bool // the service manager reports it alive
}
Status reports the login service's two independent facts.
type Systemd ¶
type Systemd struct {
// contains filtered or unexported fields
}
Systemd manages the login service through systemctl --user on linux.
func NewSystemd ¶
func (*Systemd) Disable ¶
Disable stops and disables the unit, removes the file, and reloads. Every systemctl failure is tolerated: on a machine with no user manager the file removal is the whole operation, and "already disabled" is a success.
Lingering is deliberately left as Enable set it. It is a per-user fact, not a per-service one — the user may linger for reasons that have nothing to do with flue — and disable-linger here would stop their other user services at logout. Removing the unit already means flue no longer runs.
type Warner ¶
type Warner interface {
Warnings() []string
}
Warner is optionally implemented by a Manager whose Enable can succeed while still owing the user a fact. Warnings reports advisories from the most recent Enable — true and unfortunate but not failures, like loginctl enable-linger being refused in a container, where the service works while logged in and dies at the last logout. Launchd never warns, so it does not implement this; the CLI upgrades with a type assertion.