Documentation
¶
Overview ¶
Package service generates and manages an OS service definition (a launchd LaunchAgent on macOS, a systemd user unit on Linux) that keeps one Moltnet network's server running across reboots and restarts it on crash. It backs `moltnet service install|uninstall|start|stop|status` (PLAN.md phase 4, item 2).
Index ¶
- Variables
- func LaunchdLabel(networkID string) string
- func LaunchdPlistPath(networkID string) (string, error)
- func RenderLaunchdPlist(spec Spec) (string, error)
- func RenderSystemdUnit(spec Spec) (string, error)
- func SystemdUnitName(networkID string) string
- func SystemdUnitPath(networkID string) (string, error)
- type ErrUnsupportedOS
- type Manager
- func (m *Manager) Install(ctx context.Context, spec Spec) error
- func (m *Manager) InstalledNetworkIDs() ([]string, error)
- func (m *Manager) IsInstalled(networkID string) (bool, error)
- func (m *Manager) Restart(ctx context.Context, networkID string) error
- func (m *Manager) Start(ctx context.Context, networkID string) error
- func (m *Manager) Status(ctx context.Context, networkID string) (Status, error)
- func (m *Manager) Stop(ctx context.Context, networkID string) error
- func (m *Manager) Uninstall(ctx context.Context, networkID string) error
- func (m *Manager) UnitPath(networkID string) (string, error)
- type Runner
- type Spec
- type Status
Constants ¶
This section is empty.
Variables ¶
var ErrNotInstalled = errors.New("moltnet service is not installed for this network")
ErrNotInstalled is returned by Start, Stop, Restart, and Uninstall when no unit/plist has been installed for the network yet.
Functions ¶
func LaunchdLabel ¶
LaunchdLabel is the LaunchAgent label/filename stem used on darwin.
func LaunchdPlistPath ¶
LaunchdPlistPath returns ~/Library/LaunchAgents/dev.moltnet.<network-id>.plist.
func RenderLaunchdPlist ¶
RenderLaunchdPlist renders the LaunchAgent plist for spec. It is a pure function (no filesystem or launchctl access) so it can be golden-tested.
KeepAlive + RunAtLoad restart the server on crash and at login; stdout and stderr are redirected to fixed log files under spec.LogDir() so `moltnet service status` has somewhere to point operators at. Every path value is XML-escaped via plistString so an unusual (but valid) filesystem path never produces malformed XML.
func RenderSystemdUnit ¶
RenderSystemdUnit renders the systemd user unit for spec. It is a pure function (no filesystem or systemctl access) so it can be golden-tested.
Restart=always plus a short RestartSec keeps the server running across crashes, mirroring the launchd KeepAlive behavior; stdout/stderr go to fixed log files under spec.LogDir() rather than only the journal, so `moltnet service status` can point at the same kind of path on both OSes.
func SystemdUnitName ¶
SystemdUnitName is the user unit file name used on linux.
func SystemdUnitPath ¶
SystemdUnitPath returns ~/.config/systemd/user/moltnet-<network-id>.service.
Types ¶
type ErrUnsupportedOS ¶
type ErrUnsupportedOS struct {
GOOS string
}
ErrUnsupportedOS is returned by lifecycle operations on any GOOS other than darwin and linux.
func (ErrUnsupportedOS) Error ¶
func (e ErrUnsupportedOS) Error() string
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager installs, uninstalls, and controls the OS service for a Moltnet network. Use New for production code; NewForOS is the test seam that lets tests exercise the darwin and linux code paths regardless of the host they run on, without ever calling a real launchctl/systemctl.
func New ¶
func New() *Manager
New returns a Manager that dispatches on the real runtime.GOOS and runs real launchctl/systemctl commands.
func NewForOS ¶
NewForOS returns a Manager for goos ("darwin" or anything else, treated as linux-family for systemd), using runner instead of exec.Command. Tests use this to golden-test both platforms' lifecycle behavior from one host.
func (*Manager) Install ¶
Install renders and writes the platform unit file for spec, then loads (and, per KeepAlive/enable --now, starts) it. Re-running Install updates the file in place and reloads it, so editing a network's binary or config path just means re-running `moltnet service install`.
func (*Manager) InstalledNetworkIDs ¶
InstalledNetworkIDs lists network ids with an installed unit/plist file for this Manager's GOOS: dev.moltnet.<id>.plist under ~/Library/LaunchAgents on darwin, moltnet-<id>.service under ~/.config/systemd/user on linux. `moltnet uninstall` unions this with the ~/.moltnet/<id>/ directory listing so a dangling service (its network directory already removed by hand) still gets stopped and unloaded.
func (*Manager) IsInstalled ¶
IsInstalled reports whether a unit/plist file exists for networkID, independent of the current GOOS's support: `pair --restart` uses this to give a clear "no managed service for this network" error rather than an OS-support error when the operator simply never ran `service install`.
func (*Manager) Restart ¶
Restart restarts the network's installed service, propagating ErrNotInstalled when it is not (the `pair --restart` error case).
func (*Manager) Start ¶
Start starts (or restarts, if already running) the network's installed service.
func (*Manager) Uninstall ¶
Uninstall stops and unloads the network's service, then removes the unit file. It is not an error to uninstall a network that has no service installed; it is simply a no-op in that case.
func (*Manager) UnitPath ¶
UnitPath returns the platform-specific unit/plist file path for networkID: the plist under ~/Library/LaunchAgents on darwin, the unit file under ~/.config/systemd/user on linux. Callers (the CLI's `service` command) use this to tell the operator exactly what file was written.
type Runner ¶
Runner executes one external system command (launchctl or systemctl) and returns its combined output. Production code uses execRunner; tests inject a fake so they never touch the real service manager.
type Spec ¶
type Spec struct {
// NetworkID identifies the network and names the generated unit/label.
NetworkID string
// ConfigPath is the absolute path to the network's Moltnet config file,
// passed to `moltnet start --config`.
ConfigPath string
// BinaryPath is the absolute path to the moltnet executable to run.
BinaryPath string
// NetworkDir is the absolute network home directory; stdout/stderr logs
// are written under NetworkDir/.moltnet/.
NetworkDir string
}
Spec describes the managed Moltnet server process for one network. All paths must be absolute: both launchd and systemd run units outside any particular working directory, so a relative path would resolve differently (or not at all) once the agent/unit is actually loaded.
func (Spec) LogDir ¶
LogDir returns the directory service logs are written to: NetworkDir's .moltnet runtime-state directory, matching the convention used for relay.json and other per-network runtime files.
func (Spec) StderrLogPath ¶
func (Spec) StdoutLogPath ¶
StdoutLogPath and StderrLogPath name the fixed log files launchd/systemd redirect the managed process's output to.