Documentation
¶
Overview ¶
Package service runs Ether as an operating-system service: systemd on Linux, launchd on macOS and the Service Control Manager on Windows, via github.com/kardianos/service.
The integrator in cmd/ether wires it roughly like this:
svc, err := service.New(app.Run, service.Options{
DataDir: config.DefaultDataDir(),
Logger: log,
})
if err != nil { return err }
// `ether service install|uninstall|start|stop|restart|status`
if handled, err := service.HandleCommand(os.Args[1:], svc, os.Stdout); handled {
return err
}
return svc.Run() // blocks; interactive runs also stop on SIGINT/SIGTERM
A nil RunFunc is allowed for control-only use (the tray app): Install, Start, Stop, Restart, Uninstall and Status work, Run returns ErrNoRunner.
Index ¶
- Constants
- Variables
- func HandleCommand(args []string, svc *Service, out io.Writer) (handled bool, err error)
- func Interactive() bool
- func PublishLocalURL(dataDir, baseURL string) error
- func ReadLocalURL(dataDir string) (string, error)
- type Options
- type RunFunc
- type Service
- func (s *Service) Config() *ksvc.Config
- func (s *Service) Install() error
- func (s *Service) InstallOrUpdate() (updated bool, err error)
- func (s *Service) Platform() string
- func (s *Service) Restart() error
- func (s *Service) Run() error
- func (s *Service) Start() error
- func (s *Service) Status() (Status, error)
- func (s *Service) Stop() error
- func (s *Service) Uninstall() error
- type Status
Constants ¶
const ExitCodeRestart = 3
ExitCodeRestart is the process exit code used for ErrRestartRequested.
Variables ¶
var Commands = []string{"install", "uninstall", "start", "stop", "restart", "status"}
Commands accepted after the "service" subcommand.
var ErrNoRunner = errors.New("service: no RunFunc configured (control-only service)")
ErrNoRunner is returned by Run on a control-only Service.
var ErrNotInstalled = ksvc.ErrNotInstalled
ErrNotInstalled reports a status query against an unregistered service.
var ErrRestartRequested = errors.New("service: restart requested")
ErrRestartRequested is returned by a RunFunc that wants the service manager to start a fresh process (e.g. after a self-update). Under a service manager the process exits with ExitCodeRestart; interactively Run returns it to the caller.
Functions ¶
func HandleCommand ¶
HandleCommand implements `ether service <cmd>` for cmd/ether. args is os.Args[1:]. It returns handled=false (and nil error) when args do not start with "service", so the caller can fall through to serving. Usage/help text goes to out; a bare `ether service` prints usage and is handled without error.
func Interactive ¶
func Interactive() bool
Interactive reports whether we are running in a terminal rather than under the service manager.
func PublishLocalURL ¶ added in v0.2.31
PublishLocalURL is unnecessary where the tray can read the server config.
func ReadLocalURL ¶ added in v0.2.31
ReadLocalURL falls back to read-only config discovery on these platforms.
Types ¶
type Options ¶
type Options struct {
// Name is the service-manager name. Default "ether".
Name string
// DisplayName is shown in service listings. Default "Ether".
DisplayName string
// Description for service listings.
Description string
// Executable registered with the service manager. Default: os.Executable.
Executable string
// Arguments passed to Executable when the service manager starts it.
// Default: ["serve"] is NOT assumed; empty means no arguments, so the
// binary's default action must be to serve (or to call Service.Run).
Arguments []string
// WorkingDirectory for the service process.
WorkingDirectory string
// DataDir, when set, is exported to the service as ETHER_DATA_DIR.
DataDir string
// KeepInstalledDataDir makes Install, when the service is already
// registered, keep the registered ETHER_DATA_DIR instead of DataDir
// (an upgrade that did not ask for a data directory must not move
// the owner's). Fresh installs always use DataDir.
KeepInstalledDataDir bool
// EnvVars are extra environment variables for the service process.
EnvVars map[string]string
// UserName runs the service as this user (systemd/Windows). On Linux
// packages this is the dedicated "ether" user.
UserName string
// UserService installs a per-user service (launchd LaunchAgent /
// systemd --user semantics where supported) instead of a system one.
// macOS installs are user services by default (see DefaultOptions).
UserService bool
// Dependencies are service-manager dependency lines (systemd [Unit]).
Dependencies []string
// StopTimeout bounds how long Stop waits for RunFunc to return before
// giving up (the process is exiting anyway). Default 30s.
StopTimeout time.Duration
Logger *slog.Logger
}
Options configures the Ether service. Zero values get Ether defaults.
func DefaultOptions ¶
func DefaultOptions() Options
DefaultOptions returns Options for a stock Ether install on this OS.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service is Ether's OS-service handle.
func (*Service) Install ¶
Install registers the service with the OS, or updates an existing registration in place (see InstallOrUpdate). May require elevation.
func (*Service) InstallOrUpdate ¶ added in v0.2.20
InstallOrUpdate registers the service or, when it is already registered and the platform supports it (Windows), updates the registration in place instead of deleting and recreating it: binary path, names, start type, restart policy and environment. An update keeps the registered ETHER_DATA_DIR, and leaves that directory's ACL alone, when Options.KeepInstalledDataDir is set. A running service keeps running the old binary until it is restarted. updated reports which path was taken.
func (*Service) Run ¶
Run blocks serving until the service manager stops us or, interactively, until SIGINT/SIGTERM. The RunFunc's context is cancelled on stop and Run returns its error (context cancellation is treated as a clean stop).
Under a service manager, a RunFunc that returns or panics without a stop request terminates the process (ExitCodeRestart for ErrRestartRequested, non-zero otherwise) so the manager's restart policy applies; Run does not return in that case. Interactively the error is returned to the caller.
func (*Service) Status ¶
Status reports whether the service is running, stopped, or unknown (not installed / undeterminable).