Documentation
¶
Overview ¶
Package svcmgr provides a native Go library for controlling process supervisors including runit, s6, daemontools, and systemd without shelling out to external commands.
The core functionality centers around the Client type, which provides direct control and status operations for a single runit service:
client, err := svcmgr.New("/etc/service/myapp")
if err != nil {
log.Fatal(err)
}
// Start the service
err = client.Up(context.Background())
// Get status
status, err := client.Status(context.Background())
fmt.Printf("Service state: %v, PID: %d\n", status.State, status.PID)
Manager for Bulk Operations ¶
The Manager type is provided as a convenience for applications that need to control multiple services concurrently. It's particularly useful for:
- System initialization/shutdown sequences
- Health monitoring dashboards
- Service orchestration tools
- Testing frameworks that manage multiple services
If your application already has its own concurrency framework or only manages single services, you may not need the Manager. It's designed to be optional - the Client type provides all core functionality.
manager := svcmgr.NewManager(
svcmgr.WithConcurrency(5),
svcmgr.WithTimeout(10 * time.Second),
)
// Start multiple services concurrently
err = manager.Up(ctx, "/etc/service/web", "/etc/service/db", "/etc/service/cache")
Design Philosophy ¶
This library prioritizes:
- Zero external process spawning (no exec of sv/runsv)
- Direct communication with supervise control/status endpoints
- Zero allocations on hot paths (status decode, state strings)
- Context-aware operations with proper timeouts
- Type safety (no string-based operation codes)
The Manager is included because many supervisor deployments involve coordinating multiple services, and having a tested, concurrent implementation prevents users from reimplementing the same patterns. However, it remains optional - all its functionality can be replicated using Client instances directly.
Index ¶
- Constants
- Variables
- func CheckAllToolsAvailable(tools ...string) bool
- func CheckAnyToolAvailable(tools ...string) bool
- func CheckToolAvailable(tool string) bool
- func FormatDiagnostics(diag *DiagnosticInfo) string
- func RequireDaemontools(t *testing.T)
- func RequireLinux(t *testing.T)
- func RequireNotShort(t *testing.T)
- func RequireRoot(t *testing.T)
- func RequireRunit(t *testing.T)
- func RequireS6(t *testing.T)
- func RequireSystemd(t *testing.T)
- func RequireTool(t *testing.T, toolName string)
- func RequireTools(t *testing.T, tools ...string)
- func SkipIfShort(t *testing.T, reason string)
- func WaitForRunning(t *testing.T, client ServiceClient, timeout time.Duration) error
- func WaitForRunningWithDiagnostics(t *testing.T, client ServiceClient, serviceDir string, serviceType ServiceType, ...) error
- func WaitForState(t *testing.T, client ServiceClient, expectedState State, timeout time.Duration) error
- func WaitForStatusFile(serviceDir string, serviceType ServiceType, timeout time.Duration) error
- func WaitForSupervise(serviceDir string, timeout time.Duration) error
- type BuilderSystemd
- func (b *BuilderSystemd) Build() error
- func (b *BuilderSystemd) BuildSystemdUnit() (string, error)
- func (b *BuilderSystemd) BuildWithContext(ctx context.Context) error
- func (b *BuilderSystemd) Enable(ctx context.Context) error
- func (b *BuilderSystemd) Remove(ctx context.Context) error
- func (b *BuilderSystemd) WithSudo(use bool, command string) *BuilderSystemd
- func (b *BuilderSystemd) WithUnitDir(dir string) *BuilderSystemd
- type ChpstConfig
- type ClientDaemontools
- func (cd *ClientDaemontools) Alarm(ctx context.Context) error
- func (cd *ClientDaemontools) Continue(ctx context.Context) error
- func (cd *ClientDaemontools) Down(ctx context.Context) error
- func (cd *ClientDaemontools) ExitSupervise(ctx context.Context) error
- func (cd *ClientDaemontools) HUP(ctx context.Context) error
- func (cd *ClientDaemontools) Interrupt(ctx context.Context) error
- func (cd *ClientDaemontools) Kill(ctx context.Context) error
- func (cd *ClientDaemontools) Once(ctx context.Context) error
- func (cd *ClientDaemontools) Pause(ctx context.Context) error
- func (cd *ClientDaemontools) Quit(_ context.Context) error
- func (cd *ClientDaemontools) Restart(ctx context.Context) error
- func (cd *ClientDaemontools) Start(ctx context.Context) error
- func (cd *ClientDaemontools) Status(_ context.Context) (Status, error)
- func (cd *ClientDaemontools) Stop(ctx context.Context) error
- func (cd *ClientDaemontools) Term(ctx context.Context) error
- func (cd *ClientDaemontools) USR1(ctx context.Context) error
- func (cd *ClientDaemontools) USR2(ctx context.Context) error
- func (cd *ClientDaemontools) Up(ctx context.Context) error
- func (c *ClientDaemontools) Wait(ctx context.Context, states []State) (Status, error)
- func (c *ClientDaemontools) Watch(ctx context.Context) (<-chan WatchEvent, WatchCleanupFunc, error)
- type ClientRunit
- func (rc *ClientRunit) Alarm(ctx context.Context) error
- func (rc *ClientRunit) Continue(ctx context.Context) error
- func (rc *ClientRunit) Down(ctx context.Context) error
- func (rc *ClientRunit) ExitSupervise(ctx context.Context) error
- func (rc *ClientRunit) HUP(ctx context.Context) error
- func (rc *ClientRunit) Interrupt(ctx context.Context) error
- func (rc *ClientRunit) Kill(ctx context.Context) error
- func (rc *ClientRunit) Once(ctx context.Context) error
- func (rc *ClientRunit) Pause(ctx context.Context) error
- func (rc *ClientRunit) Quit(ctx context.Context) error
- func (rc *ClientRunit) Restart(ctx context.Context) error
- func (rc *ClientRunit) Start(ctx context.Context) error
- func (rc *ClientRunit) Status(_ context.Context) (Status, error)
- func (rc *ClientRunit) Stop(ctx context.Context) error
- func (rc *ClientRunit) Term(ctx context.Context) error
- func (rc *ClientRunit) USR1(ctx context.Context) error
- func (rc *ClientRunit) USR2(ctx context.Context) error
- func (rc *ClientRunit) Up(ctx context.Context) error
- func (c *ClientRunit) Wait(ctx context.Context, states []State) (Status, error)
- func (c *ClientRunit) Watch(ctx context.Context) (<-chan WatchEvent, WatchCleanupFunc, error)
- type ClientS6
- func (cs *ClientS6) Alarm(ctx context.Context) error
- func (cs *ClientS6) Continue(_ context.Context) error
- func (cs *ClientS6) Down(ctx context.Context) error
- func (cs *ClientS6) ExitSupervise(ctx context.Context) error
- func (cs *ClientS6) HUP(ctx context.Context) error
- func (cs *ClientS6) Interrupt(ctx context.Context) error
- func (cs *ClientS6) Kill(ctx context.Context) error
- func (cs *ClientS6) Once(ctx context.Context) error
- func (cs *ClientS6) Pause(_ context.Context) error
- func (cs *ClientS6) Quit(ctx context.Context) error
- func (cs *ClientS6) Restart(ctx context.Context) error
- func (cs *ClientS6) Start(ctx context.Context) error
- func (cs *ClientS6) Status(_ context.Context) (Status, error)
- func (cs *ClientS6) Stop(ctx context.Context) error
- func (cs *ClientS6) Term(ctx context.Context) error
- func (cs *ClientS6) USR1(ctx context.Context) error
- func (cs *ClientS6) USR2(ctx context.Context) error
- func (cs *ClientS6) Up(ctx context.Context) error
- func (c *ClientS6) Wait(ctx context.Context, states []State) (Status, error)
- func (c *ClientS6) Watch(ctx context.Context) (<-chan WatchEvent, WatchCleanupFunc, error)
- type ClientSystemd
- func (c *ClientSystemd) Alarm(ctx context.Context) error
- func (c *ClientSystemd) Continue(ctx context.Context) error
- func (c *ClientSystemd) Disable(ctx context.Context) error
- func (c *ClientSystemd) Down(ctx context.Context) error
- func (c *ClientSystemd) Enable(ctx context.Context) error
- func (c *ClientSystemd) ExitSupervise(ctx context.Context) error
- func (c *ClientSystemd) HUP(ctx context.Context) error
- func (c *ClientSystemd) Interrupt(ctx context.Context) error
- func (c *ClientSystemd) IsRunning(ctx context.Context) (bool, error)
- func (c *ClientSystemd) Kill(ctx context.Context) error
- func (c *ClientSystemd) Once(ctx context.Context) error
- func (c *ClientSystemd) Pause(ctx context.Context) error
- func (c *ClientSystemd) Quit(ctx context.Context) error
- func (c *ClientSystemd) Reload(ctx context.Context) error
- func (c *ClientSystemd) Restart(ctx context.Context) error
- func (c *ClientSystemd) SendOperation(ctx context.Context, op Operation) error
- func (c *ClientSystemd) Signal(ctx context.Context, sig string) error
- func (c *ClientSystemd) Start(ctx context.Context) error
- func (c *ClientSystemd) Status(ctx context.Context) (Status, error)
- func (c *ClientSystemd) StatusSystemd(ctx context.Context) (*StatusSystemd, error)
- func (c *ClientSystemd) Stop(ctx context.Context) error
- func (c *ClientSystemd) Term(ctx context.Context) error
- func (c *ClientSystemd) USR1(ctx context.Context) error
- func (c *ClientSystemd) USR2(ctx context.Context) error
- func (c *ClientSystemd) Up(ctx context.Context) error
- func (c *ClientSystemd) Wait(ctx context.Context, states []State) (Status, error)
- func (c *ClientSystemd) WaitForState(ctx context.Context, targetState string, timeout time.Duration) error
- func (c *ClientSystemd) Watch(ctx context.Context) (<-chan WatchEvent, WatchCleanupFunc, error)
- func (c *ClientSystemd) WithSudo(use bool, command string) *ClientSystemd
- func (c *ClientSystemd) WithTimeout(d time.Duration) *ClientSystemd
- type ConfigSvlogd
- type DaemontoolsStateParser
- type DevTree
- func (d *DevTree) DisableService(_ string) error
- func (d *DevTree) EnableService(_ string) error
- func (d *DevTree) EnabledDir() string
- func (d *DevTree) Ensure() error
- func (d *DevTree) EnsureRunsvdir() error
- func (d *DevTree) LogDir() string
- func (d *DevTree) PIDFile() string
- func (d *DevTree) ServicesDir() string
- func (d *DevTree) StopRunsvdir() error
- type DiagnosticInfo
- type Flags
- type Manager
- func (m *Manager) Down(ctx context.Context, services ...string) error
- func (m *Manager) Kill(ctx context.Context, services ...string) error
- func (m *Manager) Status(ctx context.Context, services ...string) (map[string]Status, error)
- func (m *Manager) Term(ctx context.Context, services ...string) error
- func (m *Manager) Up(ctx context.Context, services ...string) error
- type ManagerOption
- type MockSupervisor
- func CreateMockService(serviceName string, config *ServiceConfig) (serviceDir string, mock *MockSupervisor, cleanup func(), err error)
- func NewMockSupervisor(serviceDir string) (*MockSupervisor, error)
- func NewMockSupervisorWithType(serviceDir string, serviceType ServiceType) (*MockSupervisor, error)
- type MultiError
- type OpError
- type Operation
- type RunitStateParser
- type S6FormatVersion
- type S6StateParserCurrent
- type S6StateParserPre220
- type ServiceBuilder
- func NewServiceBuilder(name, dir string) *ServiceBuilder
- func NewServiceBuilderWithConfig(name, dir string, config *ServiceConfig) *ServiceBuilder
- func ServiceBuilderDaemontools(name, dir string) *ServiceBuilder
- func ServiceBuilderRunit(name, dir string) *ServiceBuilder
- func ServiceBuilderS6(name, dir string) *ServiceBuilder
- func (b *ServiceBuilder) Build() error
- func (b *ServiceBuilder) Config() *ServiceBuilderConfig
- func (b *ServiceBuilder) WithChpst(fn func(*ChpstConfig)) *ServiceBuilder
- func (b *ServiceBuilder) WithChpstPath(path string) *ServiceBuilder
- func (b *ServiceBuilder) WithCmd(cmd []string) *ServiceBuilder
- func (b *ServiceBuilder) WithCwd(cwd string) *ServiceBuilder
- func (b *ServiceBuilder) WithEnv(key, value string) *ServiceBuilder
- func (b *ServiceBuilder) WithEnvMap(env map[string]string) *ServiceBuilder
- func (b *ServiceBuilder) WithFinish(cmd []string) *ServiceBuilder
- func (b *ServiceBuilder) WithStderrPath(path string) *ServiceBuilder
- func (b *ServiceBuilder) WithSvlogd(fn func(*ConfigSvlogd)) *ServiceBuilder
- func (b *ServiceBuilder) WithSvlogdPath(path string) *ServiceBuilder
- func (b *ServiceBuilder) WithUmask(umask fs.FileMode) *ServiceBuilder
- type ServiceBuilderConfig
- type ServiceClient
- type ServiceConfig
- type ServiceType
- type State
- type StateParser
- type Status
- type StatusSystemd
- type SupervisionSystem
- type SupervisorProcess
- func CreateTestServiceWithSupervisor(ctx context.Context, sys SupervisionSystem, serviceName string, _ *TestLogger) (client interface{}, supervisor *SupervisorProcess, cleanup func() error, ...)
- func StartSupervisor(ctx context.Context, serviceType ServiceType, serviceDir string) (*SupervisorProcess, error)
- type TestLogger
- type VersionInfo
- type WatchCleanupFunc
- type WatchEvent
Constants ¶
const ( // SuperviseDir is the subdirectory containing runit control files SuperviseDir = "supervise" // ControlFile is the control socket/FIFO file name ControlFile = "control" // StatusFile is the binary status file name StatusFile = "status" // StatusFileSize is the exact size of the binary status record in bytes // Reference: https://github.com/g-pape/runit/blob/master/src/sv.c#L53 // char svstatus[20]; StatusFileSize = 20 // DefaultWatchDebounce is the default debounce time for status file watching DefaultWatchDebounce = 25 * time.Millisecond // DefaultDialTimeout is the default timeout for control socket connections DefaultDialTimeout = 2 * time.Second // DefaultWriteTimeout is the default timeout for control write operations DefaultWriteTimeout = 1 * time.Second // DefaultReadTimeout is the default timeout for status read operations DefaultReadTimeout = 1 * time.Second // DefaultBackoffMin is the minimum backoff duration for retries DefaultBackoffMin = 10 * time.Millisecond // DefaultBackoffMax is the maximum backoff duration for retries DefaultBackoffMax = 1 * time.Second // DefaultMaxAttempts is the default maximum number of retry attempts DefaultMaxAttempts = 10 )
Runit directory and file constants
const ( // DefaultChpstPath is the default path to the chpst binary DefaultChpstPath = "chpst" // DefaultSvlogdPath is the default path to the svlogd binary DefaultSvlogdPath = "svlogd" // DefaultRunsvdirPath is the default path to the runsvdir binary DefaultRunsvdirPath = "runsvdir" // DefaultSvPath is the default path to the sv binary (for fallback mode) DefaultSvPath = "sv" )
Binary paths with defaults that can be overridden
const ( // DirMode is the default mode for created directories DirMode = 0o755 // FileMode is the default mode for created files FileMode = 0o644 // ExecMode is the default mode for executable scripts ExecMode = 0o755 )
File modes
const ( // OpStart is an alias for OpUp OpStart = OpUp // OpStop is an alias for OpDown OpStop = OpDown // OpRestart represents a restart operation (handled at client level) OpRestart Operation = iota + 100 )
Operation aliases for common commands
const ( S6FlagUp = 1 << 0 // bit 0: service is up S6FlagNormallyUp = 1 << 1 // bit 1: service normally up S6FlagWantUp = 1 << 2 // bit 2: admin wants service up S6FlagReady = 1 << 3 // bit 3: service sent readiness notification S6FlagPaused = 1 << 4 // bit 4: service is paused S6FlagFinishing = 1 << 5 // bit 5: finish script is running )
S6 status flag bits (byte 0 of S6 status file)
const ( RunitStatusSize = 20 // Byte positions RunitTAI64Start = 0 // TAI64 seconds (8 bytes, big-endian) RunitTAI64End = 8 RunitNanoStart = 8 // Nanoseconds (4 bytes, big-endian) RunitNanoEnd = 12 RunitPIDStart = 12 // PID (4 bytes, little-endian) RunitPIDEnd = 16 RunitPausedFlag = 16 // Paused flag RunitWantFlag = 17 // Want flag ('u' or 'd') RunitTermFlag = 18 // Term flag RunitRunFlag = 19 // Run flag (service has process) )
Runit status file format (20 bytes)
const ( DaemontoolsStatusSize = 18 // Byte positions DaemontoolsTAI64Start = 0 // TAI64 seconds (8 bytes, big-endian) DaemontoolsTAI64End = 8 DaemontoolsNanoStart = 8 // Nanoseconds (4 bytes, big-endian) DaemontoolsNanoEnd = 12 DaemontoolsPIDStart = 12 // PID (4 bytes, little-endian) DaemontoolsPIDEnd = 16 DaemontoolsStatusFlag = 16 // Status/reserved byte DaemontoolsWantFlag = 17 // Want flag ('u' or 'd') )
Daemontools status file format (18 bytes) Based on actual observation: uses TAI64N (12 bytes) + PID (4 bytes) + flags (2 bytes)
const ( S6StatusSizePre220 = 35 // Pre-2.20.0 format size S6StatusSizeCurrent = 43 // Current format size (>= 2.20.0) // S6MaxStatusSize is the maximum size of any S6 status format. // We use this when allocating buffers to ensure we can read any S6 status file version. // This allows us to read the actual file size and then determine which format to use for decoding. S6MaxStatusSize = S6StatusSizeCurrent // Pre-2.20.0 S6 format (35 bytes) // bytes 0-11: TAI64N timestamp // bytes 12-23: TAI64N ready timestamp // bytes 24-27: reserved/zeros // bytes 28-31: PID (big-endian uint32) // bytes 32-34: flags/status S6TimestampStartPre220 = 0 // TAI64N timestamp start S6TimestampEndPre220 = 12 // TAI64N timestamp end S6ReadyStartPre220 = 12 // TAI64N ready timestamp start S6ReadyEndPre220 = 24 // TAI64N ready timestamp end S6PIDStartPre220 = 28 // PID start (big-endian uint32) S6PIDEndPre220 = 32 // PID end S6FlagsBytePre220 = 34 // Flags byte // Current S6 format (43 bytes, S6 >= 2.20.0) // bytes 0-11: tain timestamp // bytes 12-23: tain readystamp // bytes 24-31: PID (big-endian uint64) // bytes 32-39: PGID (big-endian uint64) // bytes 40-41: wstat (big-endian uint16) // byte 42: flags S6TimestampStartCurrent = 0 // tain timestamp start S6TimestampEndCurrent = 12 // tain timestamp end S6ReadyStartCurrent = 12 // tain readystamp start S6ReadyEndCurrent = 24 // tain readystamp end S6PIDStartCurrent = 24 // PID start (big-endian uint64) S6PIDEndCurrent = 32 // PID end S6PGIDStartCurrent = 32 // PGID start (big-endian uint64) S6PGIDEndCurrent = 40 // PGID end S6WstatStartCurrent = 40 // wstat start (big-endian uint16) S6WstatEndCurrent = 42 // wstat end S6FlagsByteCurrent = 42 // Flags byte )
S6 status file formats S6 has two incompatible formats: - Old format (35 bytes): Older S6 versions (exact cutoff unclear, but suspect < 2.20.0 as 2.12.0.x uses this) - New format (43 bytes): Newer S6 versions (current upstream uses this, >= 2.20.0)
const ( // TAI64Base is the TAI64 epoch offset from Unix epoch (1970-01-01 00:00:10 TAI) // Reference: https://github.com/g-pape/runit/blob/master/src/tai.h#L12 // #define tai_unix(t,u) ((void) ((t)->x = 4611686018427387914ULL + (uint64) (u))) // This value is 2^62 + 10 seconds (TAI is 10 seconds ahead of UTC at Unix epoch) // Calculated as: (1 << 62) + 10 TAI64Base = uint64(1<<62) + 10 // 4611686018427387914 )
TAI64N constants for timestamp decoding
const ( // TAI64Offset is the TAI64 epoch offset (2^62) // TAI64 stores seconds since 1970-01-01 00:00:00 TAI TAI64Offset = uint64(1) << 62 )
TAI64 constants
const Version = "1.0.0"
Version is the current version of the go-runit library
Variables ¶
var ( // ErrNotSupervised indicates the service directory lacks a supervise subdirectory ErrNotSupervised = errors.New("runit: supervise dir missing") // ErrControlNotReady indicates the control socket/FIFO is not accepting connections ErrControlNotReady = errors.New("runit: control not accepting connections") // ErrTimeout indicates an operation exceeded its timeout ErrTimeout = errors.New("runit: timeout") // ErrDecode indicates the status file could not be decoded ErrDecode = errors.New("runit: status decode") )
Common errors returned by runit operations
var DefaultUmask fs.FileMode = 0o022
DefaultUmask is the default umask for created files
Functions ¶
func CheckAllToolsAvailable ¶
CheckAllToolsAvailable returns true only if all tools are available
func CheckAnyToolAvailable ¶
CheckAnyToolAvailable returns true if any of the tools are available
func CheckToolAvailable ¶
CheckToolAvailable returns true if a tool is available in PATH. This is a non-skipping version for conditional logic.
func FormatDiagnostics ¶
func FormatDiagnostics(diag *DiagnosticInfo) string
FormatDiagnostics formats diagnostic information for display
func RequireDaemontools ¶
RequireDaemontools ensures all daemontools tools are available
func RequireLinux ¶
RequireLinux skips the test if not running on Linux. Use this for Linux-specific functionality like systemd.
func RequireNotShort ¶
RequireNotShort skips the test if running in short mode. Use this for integration tests that take longer to run.
func RequireRoot ¶
RequireRoot skips the test if not running as root. Use this for tests that need system-level privileges.
func RequireRunit ¶
RequireRunit ensures all runit tools are available
func RequireSystemd ¶
RequireSystemd ensures systemd is available (Linux only)
func RequireTool ¶
RequireTool skips the test if the tool is not available in PATH. This should be used for any test that depends on external binaries.
func RequireTools ¶
RequireTools skips the test if any of the tools are not available in PATH. This is useful for tests that need multiple tools (e.g., both runsv and sv).
func SkipIfShort ¶
SkipIfShort skips the test if running in short mode
func WaitForRunning ¶
WaitForRunning waits for a service to reach the running state
func WaitForRunningWithDiagnostics ¶
func WaitForRunningWithDiagnostics(t *testing.T, client ServiceClient, serviceDir string, serviceType ServiceType, timeout time.Duration) error
WaitForRunningWithDiagnostics is an enhanced version that provides detailed diagnostics on failure
func WaitForState ¶
func WaitForState(t *testing.T, client ServiceClient, expectedState State, timeout time.Duration) error
WaitForState waits for a service to reach a specific state
func WaitForStatusFile ¶
func WaitForStatusFile(serviceDir string, serviceType ServiceType, timeout time.Duration) error
WaitForStatusFile waits for a valid status file to be created
Types ¶
type BuilderSystemd ¶
type BuilderSystemd struct {
*ServiceBuilder
// UseSudo indicates whether to use sudo for privileged operations
UseSudo bool
// SudoCommand is the sudo command to use (default: "sudo")
SudoCommand string
// UnitDir is the directory where unit files are written (default: /etc/systemd/system)
UnitDir string
// SystemctlPath is the path to systemctl binary
SystemctlPath string
}
BuilderSystemd extends ServiceBuilder to generate systemd unit files
func NewBuilderSystemd ¶
func NewBuilderSystemd(sb *ServiceBuilder) *BuilderSystemd
NewBuilderSystemd creates a new BuilderSystemd from a ServiceBuilder
func ServiceBuilderSystemd ¶
func ServiceBuilderSystemd(name, dir string) *BuilderSystemd
ServiceBuilderSystemd creates a service builder configured for systemd
func (*BuilderSystemd) Build ¶
func (b *BuilderSystemd) Build() error
Build creates and installs the systemd unit file
func (*BuilderSystemd) BuildSystemdUnit ¶
func (b *BuilderSystemd) BuildSystemdUnit() (string, error)
BuildSystemdUnit generates the systemd unit file content
func (*BuilderSystemd) BuildWithContext ¶
func (b *BuilderSystemd) BuildWithContext(ctx context.Context) error
BuildWithContext creates and installs the systemd unit file with context
func (*BuilderSystemd) Enable ¶
func (b *BuilderSystemd) Enable(ctx context.Context) error
Enable enables the systemd service to start on boot
func (*BuilderSystemd) Remove ¶
func (b *BuilderSystemd) Remove(ctx context.Context) error
Remove removes the systemd unit file
func (*BuilderSystemd) WithSudo ¶
func (b *BuilderSystemd) WithSudo(use bool, command string) *BuilderSystemd
WithSudo configures sudo usage
func (*BuilderSystemd) WithUnitDir ¶
func (b *BuilderSystemd) WithUnitDir(dir string) *BuilderSystemd
WithUnitDir sets the systemd unit directory
type ChpstConfig ¶
type ChpstConfig struct {
// User to run the process as
User string
// Group to run the process as
Group string
// Nice value for process priority
Nice int
// IONice value for I/O priority
IONice int
// LimitMem sets memory limit in bytes
LimitMem int64
// LimitFiles sets maximum number of open files
LimitFiles int
// LimitProcs sets maximum number of processes
LimitProcs int
// LimitCPU sets CPU time limit in seconds
LimitCPU int
// Root changes the root directory
Root string
}
ChpstConfig configures chpst options for process control
type ClientDaemontools ¶
type ClientDaemontools struct {
// ServiceDir is the canonical path to the service directory
ServiceDir string
// DialTimeout is the timeout for establishing control socket connections
DialTimeout time.Duration
// WriteTimeout is the timeout for writing control commands
WriteTimeout time.Duration
// ReadTimeout is the timeout for reading status information
ReadTimeout time.Duration
// BackoffMin is the minimum duration between retry attempts
BackoffMin time.Duration
// BackoffMax is the maximum duration between retry attempts
BackoffMax time.Duration
// MaxAttempts is the maximum number of retry attempts for control operations
MaxAttempts int
// WatchDebounce is the debounce duration for watch events to coalesce rapid changes
WatchDebounce time.Duration
// contains filtered or unexported fields
}
ClientDaemontools provides control and status operations for a daemontools service. It communicates directly with the service's supervise process through control sockets/FIFOs and status files.
func NewClientDaemontools ¶
func NewClientDaemontools(serviceDir string) (*ClientDaemontools, error)
NewClientDaemontools creates a new ClientDaemontools for the specified service directory. It verifies the service has a supervise directory.
func (*ClientDaemontools) Alarm ¶
func (cd *ClientDaemontools) Alarm(ctx context.Context) error
Alarm sends SIGALRM to the service process
func (*ClientDaemontools) Continue ¶
func (cd *ClientDaemontools) Continue(ctx context.Context) error
Continue sends SIGCONT to the service process
func (*ClientDaemontools) Down ¶
func (cd *ClientDaemontools) Down(ctx context.Context) error
Down stops the service (sets want down)
func (*ClientDaemontools) ExitSupervise ¶
func (cd *ClientDaemontools) ExitSupervise(ctx context.Context) error
ExitSupervise terminates the supervise process for this service
func (*ClientDaemontools) HUP ¶
func (cd *ClientDaemontools) HUP(ctx context.Context) error
HUP sends SIGHUP to the service process
func (*ClientDaemontools) Interrupt ¶
func (cd *ClientDaemontools) Interrupt(ctx context.Context) error
Interrupt sends SIGINT to the service process
func (*ClientDaemontools) Kill ¶
func (cd *ClientDaemontools) Kill(ctx context.Context) error
Kill sends SIGKILL to the service process
func (*ClientDaemontools) Once ¶
func (cd *ClientDaemontools) Once(ctx context.Context) error
Once starts the service once (does not restart if it exits)
func (*ClientDaemontools) Pause ¶
func (cd *ClientDaemontools) Pause(ctx context.Context) error
Pause sends SIGSTOP to the service process
func (*ClientDaemontools) Quit ¶
func (cd *ClientDaemontools) Quit(_ context.Context) error
Quit sends SIGQUIT to the service process
func (*ClientDaemontools) Restart ¶
func (cd *ClientDaemontools) Restart(ctx context.Context) error
Restart restarts the service by sending Down then Up
func (*ClientDaemontools) Start ¶
func (cd *ClientDaemontools) Start(ctx context.Context) error
Start is an alias for Up
func (*ClientDaemontools) Status ¶
func (cd *ClientDaemontools) Status(_ context.Context) (Status, error)
Status reads and decodes the service's binary status file. It returns typed Status information.
func (*ClientDaemontools) Stop ¶
func (cd *ClientDaemontools) Stop(ctx context.Context) error
Stop is an alias for Down
func (*ClientDaemontools) Term ¶
func (cd *ClientDaemontools) Term(ctx context.Context) error
Term sends SIGTERM to the service process
func (*ClientDaemontools) USR1 ¶
func (cd *ClientDaemontools) USR1(ctx context.Context) error
USR1 sends SIGUSR1 to the service process
func (*ClientDaemontools) USR2 ¶
func (cd *ClientDaemontools) USR2(ctx context.Context) error
USR2 sends SIGUSR2 to the service process
func (*ClientDaemontools) Up ¶
func (cd *ClientDaemontools) Up(ctx context.Context) error
Up starts the service (sets want up)
func (*ClientDaemontools) Watch ¶
func (c *ClientDaemontools) Watch(ctx context.Context) (<-chan WatchEvent, WatchCleanupFunc, error)
Watch for ClientDaemontools monitors the service's status file for changes
type ClientRunit ¶
type ClientRunit struct {
// ServiceDir is the canonical path to the service directory
ServiceDir string
// DialTimeout is the timeout for establishing control socket connections
DialTimeout time.Duration
// WriteTimeout is the timeout for writing control commands
WriteTimeout time.Duration
// ReadTimeout is the timeout for reading status information
ReadTimeout time.Duration
// BackoffMin is the minimum duration between retry attempts
BackoffMin time.Duration
// BackoffMax is the maximum duration between retry attempts
BackoffMax time.Duration
// MaxAttempts is the maximum number of retry attempts for control operations
MaxAttempts int
// WatchDebounce is the debounce duration for watch events to coalesce rapid changes
WatchDebounce time.Duration
// contains filtered or unexported fields
}
ClientRunit provides control and status operations for a runit service. It communicates directly with the service's supervise process through control sockets/FIFOs and status files, without shelling out to sv.
func NewClientRunit ¶
func NewClientRunit(serviceDir string) (*ClientRunit, error)
NewClientRunit creates a new ClientRunit for the specified service directory. It verifies the service has a supervise directory.
func (*ClientRunit) Alarm ¶
func (rc *ClientRunit) Alarm(ctx context.Context) error
Alarm sends SIGALRM to the service process
func (*ClientRunit) Continue ¶
func (rc *ClientRunit) Continue(ctx context.Context) error
Continue sends SIGCONT to the service process
func (*ClientRunit) Down ¶
func (rc *ClientRunit) Down(ctx context.Context) error
Down stops the service (sets want down)
func (*ClientRunit) ExitSupervise ¶
func (rc *ClientRunit) ExitSupervise(ctx context.Context) error
ExitSupervise terminates the supervise process for this service
func (*ClientRunit) HUP ¶
func (rc *ClientRunit) HUP(ctx context.Context) error
HUP sends SIGHUP to the service process
func (*ClientRunit) Interrupt ¶
func (rc *ClientRunit) Interrupt(ctx context.Context) error
Interrupt sends SIGINT to the service process
func (*ClientRunit) Kill ¶
func (rc *ClientRunit) Kill(ctx context.Context) error
Kill sends SIGKILL to the service process
func (*ClientRunit) Once ¶
func (rc *ClientRunit) Once(ctx context.Context) error
Once starts the service once (does not restart if it exits)
func (*ClientRunit) Pause ¶
func (rc *ClientRunit) Pause(ctx context.Context) error
Pause sends SIGSTOP to the service process
func (*ClientRunit) Quit ¶
func (rc *ClientRunit) Quit(ctx context.Context) error
Quit sends SIGQUIT to the service process
func (*ClientRunit) Restart ¶
func (rc *ClientRunit) Restart(ctx context.Context) error
Restart restarts the service by sending Down then Up
func (*ClientRunit) Start ¶
func (rc *ClientRunit) Start(ctx context.Context) error
Start is an alias for Up
func (*ClientRunit) Status ¶
func (rc *ClientRunit) Status(_ context.Context) (Status, error)
Status reads and decodes the service's binary status file. It returns typed Status information without shelling out to sv.
func (*ClientRunit) Stop ¶
func (rc *ClientRunit) Stop(ctx context.Context) error
Stop is an alias for Down
func (*ClientRunit) Term ¶
func (rc *ClientRunit) Term(ctx context.Context) error
Term sends SIGTERM to the service process
func (*ClientRunit) USR1 ¶
func (rc *ClientRunit) USR1(ctx context.Context) error
USR1 sends SIGUSR1 to the service process
func (*ClientRunit) USR2 ¶
func (rc *ClientRunit) USR2(ctx context.Context) error
USR2 sends SIGUSR2 to the service process
func (*ClientRunit) Up ¶
func (rc *ClientRunit) Up(ctx context.Context) error
Up starts the service (sets want up)
func (*ClientRunit) Wait ¶
Wait blocks until the service reaches one of the specified states or context is cancelled. Returns the status when one of the states is reached, or an error if one occurred. If states is nil or empty, waits for any state change.
Example:
// Wait for any change
status, err := client.Wait(ctx, nil)
// Wait for specific states
status, err := client.Wait(ctx, []State{StateRunning, StateDown})
func (*ClientRunit) Watch ¶
func (c *ClientRunit) Watch(ctx context.Context) (<-chan WatchEvent, WatchCleanupFunc, error)
Watch for ClientRunit monitors the service's status file for changes
type ClientS6 ¶
type ClientS6 struct {
// ServiceDir is the canonical path to the service directory
ServiceDir string
// DialTimeout is the timeout for establishing control socket connections
DialTimeout time.Duration
// WriteTimeout is the timeout for writing control commands
WriteTimeout time.Duration
// ReadTimeout is the timeout for reading status information
ReadTimeout time.Duration
// BackoffMin is the minimum duration between retry attempts
BackoffMin time.Duration
// BackoffMax is the maximum duration between retry attempts
BackoffMax time.Duration
// MaxAttempts is the maximum number of retry attempts for control operations
MaxAttempts int
// WatchDebounce is the debounce duration for watch events to coalesce rapid changes
WatchDebounce time.Duration
// contains filtered or unexported fields
}
ClientS6 provides control and status operations for an s6 service. It communicates directly with the service's s6-supervise process through control sockets/FIFOs and status files.
func NewClientS6 ¶
NewClientS6 creates a new ClientS6 for the specified service directory. It verifies the service has a supervise directory.
func (*ClientS6) ExitSupervise ¶
ExitSupervise terminates the supervise process for this service
func (*ClientS6) Status ¶
Status reads and decodes the service's binary status file. It returns typed Status information.
func (*ClientS6) Watch ¶
func (c *ClientS6) Watch(ctx context.Context) (<-chan WatchEvent, WatchCleanupFunc, error)
Watch for ClientS6 monitors the service's status file for changes
type ClientSystemd ¶
type ClientSystemd struct {
// ServiceName is the name of the systemd service (without .service suffix)
ServiceName string
// UseSudo indicates whether to use sudo for systemctl commands
UseSudo bool
// SudoCommand is the sudo command to use (default: "sudo")
SudoCommand string
// SystemctlPath is the path to systemctl binary
SystemctlPath string
// Timeout for systemctl operations
Timeout time.Duration
// WatchInterval is the polling interval for Watch when other methods unavailable
WatchInterval time.Duration
}
ClientSystemd provides control operations for systemd services It implements a similar interface to the runit Client but uses systemctl
func NewClientSystemd ¶
func NewClientSystemd(serviceName string) *ClientSystemd
NewClientSystemd creates a new ClientSystemd for the specified service
func NewClientSystemdWithConfig ¶
func NewClientSystemdWithConfig(serviceName string, config *ServiceConfig) *ClientSystemd
NewClientSystemdWithConfig creates a new systemd client with the specified configuration
func (*ClientSystemd) Alarm ¶
func (c *ClientSystemd) Alarm(ctx context.Context) error
Alarm sends SIGALRM to the service process
func (*ClientSystemd) Continue ¶
func (c *ClientSystemd) Continue(ctx context.Context) error
Continue sends SIGCONT to the service process
func (*ClientSystemd) Disable ¶
func (c *ClientSystemd) Disable(ctx context.Context) error
Disable disables the service from starting on boot
func (*ClientSystemd) Down ¶
func (c *ClientSystemd) Down(ctx context.Context) error
Down stops the service (sets want down)
func (*ClientSystemd) Enable ¶
func (c *ClientSystemd) Enable(ctx context.Context) error
Enable enables the service to start on boot
func (*ClientSystemd) ExitSupervise ¶
func (c *ClientSystemd) ExitSupervise(ctx context.Context) error
ExitSupervise stops and disables the service (no direct systemd equivalent)
func (*ClientSystemd) HUP ¶
func (c *ClientSystemd) HUP(ctx context.Context) error
HUP sends SIGHUP directly to the service's main process. This bypasses systemd's reload mechanism and sends the signal directly. For services with ExecReload= configured, consider using Reload() instead.
func (*ClientSystemd) Interrupt ¶
func (c *ClientSystemd) Interrupt(ctx context.Context) error
Interrupt sends SIGINT to the service process
func (*ClientSystemd) IsRunning ¶
func (c *ClientSystemd) IsRunning(ctx context.Context) (bool, error)
IsRunning checks if the service is currently running
func (*ClientSystemd) Kill ¶
func (c *ClientSystemd) Kill(ctx context.Context) error
Kill sends SIGKILL to the service's main process
func (*ClientSystemd) Once ¶
func (c *ClientSystemd) Once(ctx context.Context) error
Once starts the service once (does not restart if it exits)
func (*ClientSystemd) Pause ¶
func (c *ClientSystemd) Pause(ctx context.Context) error
Pause sends SIGSTOP to the service process
func (*ClientSystemd) Quit ¶
func (c *ClientSystemd) Quit(ctx context.Context) error
Quit sends SIGQUIT to the service process
func (*ClientSystemd) Reload ¶
func (c *ClientSystemd) Reload(ctx context.Context) error
Reload attempts to reload the service using systemctl reload. This uses the service's ExecReload= configuration if defined. If the service doesn't support reload, this will return an error. Note: This is NOT the same as sending SIGHUP - use HUP() for that.
func (*ClientSystemd) Restart ¶
func (c *ClientSystemd) Restart(ctx context.Context) error
Restart restarts the service
func (*ClientSystemd) SendOperation ¶
func (c *ClientSystemd) SendOperation(ctx context.Context, op Operation) error
SendOperation maps runit operations to systemd commands
func (*ClientSystemd) Signal ¶
func (c *ClientSystemd) Signal(ctx context.Context, sig string) error
Signal sends a custom signal to the service's main process
func (*ClientSystemd) Start ¶
func (c *ClientSystemd) Start(ctx context.Context) error
Start starts the service (alias for Up)
func (*ClientSystemd) Status ¶
func (c *ClientSystemd) Status(ctx context.Context) (Status, error)
Status returns the status of the service in runit format for interface compatibility
func (*ClientSystemd) StatusSystemd ¶
func (c *ClientSystemd) StatusSystemd(ctx context.Context) (*StatusSystemd, error)
StatusSystemd returns the systemd-specific status of the service
func (*ClientSystemd) Stop ¶
func (c *ClientSystemd) Stop(ctx context.Context) error
Stop stops the service (alias for Down)
func (*ClientSystemd) Term ¶
func (c *ClientSystemd) Term(ctx context.Context) error
Term sends SIGTERM to the service's main process
func (*ClientSystemd) USR1 ¶
func (c *ClientSystemd) USR1(ctx context.Context) error
USR1 sends SIGUSR1 to the service
func (*ClientSystemd) USR2 ¶
func (c *ClientSystemd) USR2(ctx context.Context) error
USR2 sends SIGUSR2 to the service
func (*ClientSystemd) Up ¶
func (c *ClientSystemd) Up(ctx context.Context) error
Up starts the service (sets want up)
func (*ClientSystemd) WaitForState ¶
func (c *ClientSystemd) WaitForState(ctx context.Context, targetState string, timeout time.Duration) error
WaitForState waits for the service to reach a specific state
func (*ClientSystemd) Watch ¶
func (c *ClientSystemd) Watch(ctx context.Context) (<-chan WatchEvent, WatchCleanupFunc, error)
Watch monitors the systemd service for state changes
func (*ClientSystemd) WithSudo ¶
func (c *ClientSystemd) WithSudo(use bool, command string) *ClientSystemd
WithSudo configures sudo usage
func (*ClientSystemd) WithTimeout ¶
func (c *ClientSystemd) WithTimeout(d time.Duration) *ClientSystemd
WithTimeout sets the timeout for operations
type ConfigSvlogd ¶
type ConfigSvlogd struct {
// Size is the maximum size of current log file in bytes
Size int64
// Num is the number of old log files to keep
Num int
// Timeout is the maximum age of current log file in seconds
Timeout int
// Processor is an optional processor script for log files
Processor string
// Config contains additional svlogd configuration lines
Config []string
// Timestamp adds timestamps to log lines
Timestamp bool
// Replace replaces non-printable characters
Replace bool
// Prefix adds a prefix to each log line
Prefix string
}
ConfigSvlogd configures svlogd logging options
type DaemontoolsStateParser ¶
type DaemontoolsStateParser struct{}
DaemontoolsStateParser parses Daemontools status files (18 bytes)
func (*DaemontoolsStateParser) Name ¶
func (p *DaemontoolsStateParser) Name() string
Name returns the parser name
func (*DaemontoolsStateParser) Parse ¶
func (p *DaemontoolsStateParser) Parse(data []byte) (Status, error)
Parse parses the status data and returns a Status
func (*DaemontoolsStateParser) ValidateSize ¶
func (p *DaemontoolsStateParser) ValidateSize(size int) bool
ValidateSize checks if the status file size is valid
type DevTree ¶
type DevTree struct {
Base string
}
DevTree represents a development runit service tree (stub implementation)
func NewDevTree ¶
NewDevTree creates a new DevTree (stub implementation)
func (*DevTree) DisableService ¶
DisableService disables a service in the dev tree
func (*DevTree) EnableService ¶
EnableService enables a service in the dev tree
func (*DevTree) EnabledDir ¶
EnabledDir returns the enabled services directory path
func (*DevTree) EnsureRunsvdir ¶
EnsureRunsvdir ensures runsvdir is running for the dev tree
func (*DevTree) ServicesDir ¶
ServicesDir returns the services directory path
func (*DevTree) StopRunsvdir ¶
StopRunsvdir stops the runsvdir process for the dev tree
type DiagnosticInfo ¶
type DiagnosticInfo struct {
ServiceDir string
ServiceType ServiceType
StatusFile string
RunScript string
LogScript string
StatusHex string
StatusError error
RunContent string
LogContent string
ProcessInfo string
LastLogLines []string
}
DiagnosticInfo contains detailed diagnostic information about a service failure
func CollectServiceDiagnostics ¶
func CollectServiceDiagnostics(serviceDir string, serviceType ServiceType) (*DiagnosticInfo, error)
CollectServiceDiagnostics gathers comprehensive diagnostic information for debugging
type Flags ¶
type Flags struct {
// WantUp indicates the service is configured to be up
WantUp bool
// WantDown indicates the service is configured to be down
WantDown bool
// NormallyUp indicates the service should be started on boot
NormallyUp bool
}
Flags represents service configuration flags from the status file
type Manager ¶
type Manager struct {
// Concurrency is the maximum number of concurrent operations
Concurrency int
// Timeout is the per-operation timeout
Timeout time.Duration
}
Manager handles operations on multiple runit services concurrently. It provides bulk operations with configurable concurrency and timeouts.
func NewManager ¶
func NewManager(opts ...ManagerOption) *Manager
NewManager creates a new Manager with default settings
type ManagerOption ¶
type ManagerOption func(*Manager)
ManagerOption configures a Manager
func WithConcurrency ¶
func WithConcurrency(n int) ManagerOption
WithConcurrency sets the maximum number of concurrent operations
func WithTimeout ¶
func WithTimeout(d time.Duration) ManagerOption
WithTimeout sets the per-operation timeout
type MockSupervisor ¶
type MockSupervisor struct {
ServiceDir string
SuperviseDir string
ControlFile string
StatusFile string
ServiceType ServiceType // Track which supervision system we're mocking
}
MockSupervisor creates a fake supervise directory structure for testing This allows tests to run without actual supervisor processes
func CreateMockService ¶
func CreateMockService(serviceName string, config *ServiceConfig) (serviceDir string, mock *MockSupervisor, cleanup func(), err error)
CreateMockService creates a service with a mock supervisor for testing
func NewMockSupervisor ¶
func NewMockSupervisor(serviceDir string) (*MockSupervisor, error)
NewMockSupervisor creates a mock supervise directory for testing
func NewMockSupervisorWithType ¶
func NewMockSupervisorWithType(serviceDir string, serviceType ServiceType) (*MockSupervisor, error)
NewMockSupervisorWithType creates a mock supervise directory for a specific supervision system
func (*MockSupervisor) Cleanup ¶
func (m *MockSupervisor) Cleanup() error
Cleanup removes the mock supervise directory
func (*MockSupervisor) UpdateStatus ¶
func (m *MockSupervisor) UpdateStatus(running bool, pid int) error
UpdateStatus updates the mock status file
type MultiError ¶
type MultiError struct {
// Errors contains all accumulated errors
Errors []error
}
MultiError aggregates multiple errors from bulk operations
func (*MultiError) Add ¶
func (m *MultiError) Add(err error)
Add appends an error to the collection if it's not nil
func (*MultiError) Err ¶
func (m *MultiError) Err() error
Err returns nil if no errors occurred, otherwise returns the MultiError itself
func (*MultiError) Error ¶
func (m *MultiError) Error() string
Error returns a summary of the accumulated errors
type OpError ¶
type OpError struct {
// Op is the operation that failed
Op Operation
// Path is the file path involved in the operation
Path string
// Err is the underlying error
Err error
}
OpError represents an error from a runit operation
type Operation ¶
type Operation int
Operation represents a control operation type
const ( // OpUnknown represents an unknown operation OpUnknown Operation = iota // OpUp starts the service (want up) OpUp // OpOnce starts the service once OpOnce // OpDown stops the service (want down) OpDown // OpTerm sends SIGTERM to the service OpTerm // OpInterrupt sends SIGINT to the service OpInterrupt // OpHUP sends SIGHUP to the service OpHUP // OpAlarm sends SIGALRM to the service OpAlarm // OpQuit sends SIGQUIT to the service OpQuit // OpKill sends SIGKILL to the service OpKill // OpPause sends SIGSTOP to the service OpPause // OpCont sends SIGCONT to the service OpCont // OpUSR1 sends SIGUSR1 to the service OpUSR1 // OpUSR2 sends SIGUSR2 to the service OpUSR2 // OpExit terminates the supervise process OpExit // OpStatus represents a status query operation OpStatus )
type RunitStateParser ¶
type RunitStateParser struct{}
RunitStateParser parses Runit status files (20 bytes)
func (*RunitStateParser) Name ¶
func (p *RunitStateParser) Name() string
Name returns the parser name
func (*RunitStateParser) Parse ¶
func (p *RunitStateParser) Parse(data []byte) (Status, error)
Parse parses the status data and returns a Status
func (*RunitStateParser) ValidateSize ¶
func (p *RunitStateParser) ValidateSize(size int) bool
ValidateSize checks if the status file size is valid
type S6FormatVersion ¶
type S6FormatVersion int
S6FormatVersion represents the S6 status file format version
const ( // S6FormatUnknown indicates the format could not be determined S6FormatUnknown S6FormatVersion = iota // S6FormatPre220 is the old 35-byte format (S6 < 2.20.x) S6FormatPre220 // S6FormatCurrent is the new 43-byte format (S6 >= 2.20.0) S6FormatCurrent )
type S6StateParserCurrent ¶
type S6StateParserCurrent struct{}
S6StateParserCurrent parses S6 status files for versions >= 2.20.0 (43 bytes)
func (*S6StateParserCurrent) Name ¶
func (p *S6StateParserCurrent) Name() string
Name returns the parser name
func (*S6StateParserCurrent) Parse ¶
func (p *S6StateParserCurrent) Parse(data []byte) (Status, error)
Parse parses the status data and returns a Status
func (*S6StateParserCurrent) ValidateSize ¶
func (p *S6StateParserCurrent) ValidateSize(size int) bool
ValidateSize checks if the status file size is valid
type S6StateParserPre220 ¶
type S6StateParserPre220 struct{}
S6StateParserPre220 parses S6 status files for versions < 2.20.0 (35 bytes)
func (*S6StateParserPre220) Name ¶
func (p *S6StateParserPre220) Name() string
Name returns the parser name
func (*S6StateParserPre220) Parse ¶
func (p *S6StateParserPre220) Parse(data []byte) (Status, error)
Parse parses the status data and returns a Status
func (*S6StateParserPre220) ValidateSize ¶
func (p *S6StateParserPre220) ValidateSize(size int) bool
ValidateSize checks if the status file size is valid
type ServiceBuilder ¶
type ServiceBuilder struct {
// contains filtered or unexported fields
}
ServiceBuilder provides a fluent interface for creating runit service directories with run scripts, environment variables, logging, and process control settings.
func NewServiceBuilder ¶
func NewServiceBuilder(name, dir string) *ServiceBuilder
NewServiceBuilder creates a new ServiceBuilder with default settings
func NewServiceBuilderWithConfig ¶
func NewServiceBuilderWithConfig(name, dir string, config *ServiceConfig) *ServiceBuilder
NewServiceBuilderWithConfig creates a service builder for the specified supervision system
func ServiceBuilderDaemontools ¶
func ServiceBuilderDaemontools(name, dir string) *ServiceBuilder
ServiceBuilderDaemontools creates a service builder configured for daemontools
func ServiceBuilderRunit ¶
func ServiceBuilderRunit(name, dir string) *ServiceBuilder
ServiceBuilderRunit creates a service builder configured for runit
func ServiceBuilderS6 ¶
func ServiceBuilderS6(name, dir string) *ServiceBuilder
ServiceBuilderS6 creates a service builder configured for s6
func (*ServiceBuilder) Build ¶
func (b *ServiceBuilder) Build() error
Build creates the service directory structure and scripts
func (*ServiceBuilder) Config ¶
func (b *ServiceBuilder) Config() *ServiceBuilderConfig
Config returns a copy of the current configuration
func (*ServiceBuilder) WithChpst ¶
func (b *ServiceBuilder) WithChpst(fn func(*ChpstConfig)) *ServiceBuilder
WithChpst configures process control settings
func (*ServiceBuilder) WithChpstPath ¶
func (b *ServiceBuilder) WithChpstPath(path string) *ServiceBuilder
WithChpstPath sets the path to the chpst binary
func (*ServiceBuilder) WithCmd ¶
func (b *ServiceBuilder) WithCmd(cmd []string) *ServiceBuilder
WithCmd sets the command to execute
func (*ServiceBuilder) WithCwd ¶
func (b *ServiceBuilder) WithCwd(cwd string) *ServiceBuilder
WithCwd sets the working directory
func (*ServiceBuilder) WithEnv ¶
func (b *ServiceBuilder) WithEnv(key, value string) *ServiceBuilder
WithEnv adds an environment variable
func (*ServiceBuilder) WithEnvMap ¶
func (b *ServiceBuilder) WithEnvMap(env map[string]string) *ServiceBuilder
WithEnvMap adds multiple environment variables from a map
func (*ServiceBuilder) WithFinish ¶
func (b *ServiceBuilder) WithFinish(cmd []string) *ServiceBuilder
WithFinish sets the command to run when the service stops
func (*ServiceBuilder) WithStderrPath ¶
func (b *ServiceBuilder) WithStderrPath(path string) *ServiceBuilder
WithStderrPath sets a separate path for stderr output
func (*ServiceBuilder) WithSvlogd ¶
func (b *ServiceBuilder) WithSvlogd(fn func(*ConfigSvlogd)) *ServiceBuilder
WithSvlogd configures logging settings
func (*ServiceBuilder) WithSvlogdPath ¶
func (b *ServiceBuilder) WithSvlogdPath(path string) *ServiceBuilder
WithSvlogdPath sets the path to the svlogd binary
func (*ServiceBuilder) WithUmask ¶
func (b *ServiceBuilder) WithUmask(umask fs.FileMode) *ServiceBuilder
WithUmask sets the file mode creation mask
type ServiceBuilderConfig ¶
type ServiceBuilderConfig struct {
// Name is the service name
Name string
// Dir is the base directory where the service will be created
Dir string
// Cmd is the command and arguments to execute
Cmd []string
// Cwd is the working directory for the service
Cwd string
// Umask sets the file mode creation mask
Umask fs.FileMode
// Env contains environment variables for the service
Env map[string]string
// Chpst configures process limits and user context
Chpst *ChpstConfig
// Svlogd configures logging
Svlogd *ConfigSvlogd
// Finish is the command to run when the service stops
Finish []string
// StderrPath is an optional path to redirect stderr (if different from stdout)
StderrPath string
// ChpstPath is the path to the chpst binary
ChpstPath string
// SvlogdPath is the path to the svlogd binary
SvlogdPath string
}
ServiceBuilderConfig represents the configuration for a service This struct contains all the settings that can be configured for a service
func (*ServiceBuilderConfig) Clone ¶
func (c *ServiceBuilderConfig) Clone() *ServiceBuilderConfig
Clone creates a deep copy of the ServiceBuilderConfig
type ServiceClient ¶
type ServiceClient interface {
// Basic operations
Up(ctx context.Context) error
Down(ctx context.Context) error
Status(ctx context.Context) (Status, error)
// Signal operations
Term(ctx context.Context) error
Kill(ctx context.Context) error
HUP(ctx context.Context) error
Alarm(ctx context.Context) error
Interrupt(ctx context.Context) error
Quit(ctx context.Context) error
USR1(ctx context.Context) error
USR2(ctx context.Context) error
// Control operations
Once(ctx context.Context) error
Pause(ctx context.Context) error
Continue(ctx context.Context) error
// Aliases
Start(ctx context.Context) error // Alias for Up
Stop(ctx context.Context) error // Alias for Down
Restart(ctx context.Context) error
// Supervision control
ExitSupervise(ctx context.Context) error
// Watch monitors the service's status for changes
// Returns a channel of events and a stop function
Watch(ctx context.Context) (<-chan WatchEvent, WatchCleanupFunc, error)
// Wait blocks until the service reaches one of the specified states
// If states is nil or empty, waits for any status change
Wait(ctx context.Context, states []State) (Status, error)
}
ServiceClient is the main interface all supervision clients implement. It provides a unified API for controlling services across different supervision systems (runit, daemontools, s6, systemd).
func NewClient ¶
func NewClient(serviceDir string, serviceType ServiceType) (ServiceClient, error)
NewClient creates a ServiceClient based on the detected or specified supervision system
type ServiceConfig ¶
type ServiceConfig struct {
// Type specifies which supervision system this is for
Type ServiceType
// ServiceDir is the base service directory (e.g., /etc/service, /service, /run/service)
ServiceDir string
// ChpstPath is the path to the privilege/resource control tool
ChpstPath string
// LoggerPath is the path to the logger tool
LoggerPath string
// RunsvdirPath is the path to the service scanner
RunsvdirPath string
// SupportedOps contains the set of supported operations
SupportedOps map[Operation]struct{}
}
ServiceConfig contains configuration for different supervision systems
func ConfigDaemontools ¶
func ConfigDaemontools() *ServiceConfig
ConfigDaemontools returns the default configuration for daemontools
func ConfigRunit ¶
func ConfigRunit() *ServiceConfig
ConfigRunit returns the default configuration for runit
func ConfigSystemd ¶
func ConfigSystemd() *ServiceConfig
ConfigSystemd returns the default configuration for systemd
func (*ServiceConfig) IsOperationSupported ¶
func (c *ServiceConfig) IsOperationSupported(op Operation) bool
IsOperationSupported checks if an operation is supported by this service type
type ServiceType ¶
type ServiceType int
ServiceType represents the type of service supervision system
const ( // ServiceTypeUnknown represents an unknown supervision system ServiceTypeUnknown ServiceType = iota // ServiceTypeRunit represents runit supervision ServiceTypeRunit // ServiceTypeDaemontools represents daemontools supervision ServiceTypeDaemontools // ServiceTypeS6 represents s6 supervision ServiceTypeS6 // ServiceTypeSystemd represents systemd supervision ServiceTypeSystemd )
func (ServiceType) String ¶
func (st ServiceType) String() string
String returns the string representation of ServiceType
type State ¶
type State int
State represents the current state of a runit service
const ( // StateUnknown indicates the state could not be determined StateUnknown State = iota // StateDown indicates the service is down and wants to be down StateDown // StateStarting indicates the service wants to be up but is not running yet StateStarting // StateRunning indicates the service is running and wants to be up StateRunning // StatePaused indicates the service is paused (SIGSTOP) StatePaused // StateStopping indicates the service is running but wants to be down StateStopping // StateFinishing indicates the finish script is executing StateFinishing // StateCrashed indicates the service is down but wants to be up StateCrashed // StateExited indicates the supervise process has exited StateExited )
type StateParser ¶
type StateParser interface {
// Parse parses the raw status file data into a Status struct
Parse(data []byte) (Status, error)
// ValidateSize checks if the data size is valid for this parser
ValidateSize(size int) bool
// Name returns the name of this parser for debugging
Name() string
}
StateParser defines the interface for parsing supervision system status files
func GetStateParser ¶
func GetStateParser(serviceType ServiceType, dataSize int) (StateParser, error)
GetStateParser returns the appropriate parser for the given service type and data size
type Status ¶
type Status struct {
// State is the inferred service state
State State
// PID is the process ID of the service (0 if not running)
PID int
// Since is the timestamp when the service entered its current state
Since time.Time
// Uptime is the duration since the service entered its current state.
// This field provides a snapshot of the uptime at the moment of status read.
// Note: This value becomes stale immediately after reading as time progresses.
// It's included for convenience and compatibility with sv output format.
// For accurate time calculations, use Since with time.Since(status.Since).
Uptime time.Duration
// Ready indicates if the service has signaled readiness (S6 and potentially systemd)
// For S6: Set when the service has sent a readiness notification
// For other systems: May indicate similar readiness states if supported
Ready bool
// ReadySince is the timestamp when the service became ready (if available)
// Only populated for S6 currently, zero value for other systems
ReadySince time.Time
// Flags contains service configuration flags
Flags Flags
// Raw contains the original 20-byte status record as an array (stack allocated)
Raw [StatusFileSize]byte
// S6Format indicates which S6 format version was detected (only set for S6 status files)
S6Format S6FormatVersion
}
Status represents the decoded state of a runit service
func DecodeStatusDaemontools ¶
DecodeStatusDaemontools decodes an 18-byte daemontools status file
func DecodeStatusRunit ¶
DecodeStatusRunit decodes a 20-byte runit status file
func DecodeStatusS6 ¶
DecodeStatusS6 decodes an s6 status file (35 bytes)
type StatusSystemd ¶
type StatusSystemd struct {
// ActiveState is the active state (active, inactive, failed, etc.)
ActiveState string
// SubState is the sub state (running, dead, exited, etc.)
SubState string
// LoadState is the load state (loaded, not-found, error, etc.)
LoadState string
// Running indicates if the service is currently running
Running bool
// MainPID is the main process ID (0 if not running)
MainPID int
// StartTime is when the service was started
StartTime time.Time
// Uptime is how long the service has been running
Uptime time.Duration
// Result is the result of the last run (success, exit-code, signal, etc.)
Result string
// Properties contains all properties returned by systemctl show
Properties map[string]string
}
StatusSystemd represents the status of a systemd service
func (*StatusSystemd) MapToStatus ¶
func (s *StatusSystemd) MapToStatus() *Status
MapToStatus converts StatusSystemd to runit Status for compatibility
func (*StatusSystemd) String ¶
func (s *StatusSystemd) String() string
String returns a human-readable status string
type SupervisionSystem ¶
type SupervisionSystem struct {
Name string
Type ServiceType
Available bool
Config *ServiceConfig
Setup func() error
Teardown func() error
}
SupervisionSystem represents a supervision system to test
type SupervisorProcess ¶
type SupervisorProcess struct {
Type ServiceType
ServiceDir string
Cmd *exec.Cmd
Started bool
}
SupervisorProcess manages a supervisor process for testing
func CreateTestServiceWithSupervisor ¶
func CreateTestServiceWithSupervisor(ctx context.Context, sys SupervisionSystem, serviceName string, _ *TestLogger) (client interface{}, supervisor *SupervisorProcess, cleanup func() error, err error)
CreateTestServiceWithSupervisor creates a service and starts its supervisor
func StartSupervisor ¶
func StartSupervisor(ctx context.Context, serviceType ServiceType, serviceDir string) (*SupervisorProcess, error)
StartSupervisor starts the appropriate supervisor process for the service type
func (*SupervisorProcess) Stop ¶
func (sp *SupervisorProcess) Stop() error
Stop stops the supervisor process
type TestLogger ¶
type TestLogger struct {
// contains filtered or unexported fields
}
TestLogger handles logging with timestamps
func NewTestLogger ¶
NewTestLogger creates a new test logger instance
func (*TestLogger) GetLogs ¶
func (l *TestLogger) GetLogs() []string
GetLogs returns all logged messages
func (*TestLogger) Log ¶
func (l *TestLogger) Log(format string, args ...interface{})
Log writes a log message to both test output and log file
type VersionInfo ¶
type VersionInfo struct {
// Version is the semantic version
Version string
// Protocol is the runit protocol version supported
Protocol string
// Compatible indicates compatibility with daemontools
Compatible bool
}
VersionInfo contains detailed version information
type WatchCleanupFunc ¶
type WatchCleanupFunc func() error
WatchCleanupFunc is a function that cleans up watch resources
type WatchEvent ¶
WatchEvent represents a status change event from watching a service
Source Files
¶
- client_daemontools.go
- client_interface.go
- client_runit.go
- client_s6.go
- devtree_stub.go
- doc.go
- errors.go
- factory.go
- factory_daemontools.go
- factory_runit.go
- factory_s6.go
- factory_systemd.go
- integration_test_helpers.go
- manager.go
- runit.go
- service_builder.go
- service_builder_config.go
- state_parser.go
- status_decode.go
- status_format_constants.go
- systemd_builder.go
- systemd_client.go
- test_helpers.go
- test_helpers_common.go
- test_mock_supervisor.go
- test_types.go
- version.go
- watch.go
- watch_impl.go
- watch_types.go
- watch_unified.go
- watch_wait.go
- watch_wait_impl.go
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
basic
command
Package main provides a basic example of using the go-runit library.
|
Package main provides a basic example of using the go-runit library. |
|
compat
command
Package main demonstrates using go-runit with different supervision systems (runit, daemontools, s6) through the factory functions.
|
Package main demonstrates using go-runit with different supervision systems (runit, daemontools, s6) through the factory functions. |
|
manager
command
Package main provides an example of managing multiple runit services.
|
Package main provides an example of managing multiple runit services. |
|
wait
command
Example demonstrating the Wait() interface for blocking until status changes
|
Example demonstrating the Wait() interface for blocking until status changes |
|
watch
command
Package main provides an example of watching service status changes.
|
Package main provides an example of watching service status changes. |
|
internal
|
|
|
unix
Package unix provides platform-specific Unix constants.
|
Package unix provides platform-specific Unix constants. |