runner

package
v0.0.1-dev.137 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 11, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package runner provides interfaces and implementations for managing service instances.

Index

Constants

This section is empty.

Variables

View Source
var ErrDebugNotSupported = errDebugNotSupported{}

ErrDebugNotSupported is returned by Runner.RunDebug implementations that don't support spawning an ephemeral sidecar from an existing instance's template (process runner, test runner). The exec service surfaces this as FailedPrecondition with a clear "your runtime doesn't support --debug" message instead of pretending it worked.

View Source
var ErrInitNotSupported = errInitNotSupported{}

ErrInitNotSupported is returned by Runner.RunInit implementations that do not (yet) support init steps. The instance controller surfaces this as a fatal scheduling error so operators get a clear message rather than a silent skip.

Functions

This section is empty.

Types

type DialCall

type DialCall struct {
	InstanceID string
	Port       uint32
}

DialCall captures one Runner.Dial invocation for assertions in tests.

type ExecOptions

type ExecOptions struct {
	// Command is the command to execute.
	Command []string

	// Env is a map of environment variables to set for the command.
	Env map[string]string

	// WorkingDir is the working directory for the command.
	WorkingDir string

	// TTY indicates whether to allocate a pseudo-TTY.
	TTY bool

	// TerminalWidth is the initial width of the terminal.
	TerminalWidth uint32

	// TerminalHeight is the initial height of the terminal.
	TerminalHeight uint32
}

ExecOptions defines options for executing a command in a running instance.

func GetExecOptions

func GetExecOptions(command []string, instance *types.Instance) ExecOptions

GetExecOptions returns ExecOptions using values from the instance

type ExecStream

type ExecStream interface {
	// Write writes data to the standard input of the process.
	Write(p []byte) (n int, err error)

	// Read reads data from the standard output of the process.
	Read(p []byte) (n int, err error)

	// Stderr provides access to the standard error stream of the process.
	Stderr() io.Reader

	// ResizeTerminal resizes the terminal (if TTY was enabled).
	ResizeTerminal(width, height uint32) error

	// Signal sends a signal to the process.
	Signal(sigName string) error

	// ExitCode returns the exit code after the process has completed.
	// Returns an error if the process has not completed or if there was an error.
	ExitCode() (int, error)

	// Close terminates the exec session and releases resources.
	Close() error
}

ExecStream provides bidirectional communication with an exec session.

type FakeExecStream

type FakeExecStream struct {
	StdoutContent []byte
	StdoutPos     int
	StderrContent []byte
	StderrReader  io.Reader
	ExitCodeVal   int
	SignalsSent   []string
	InputCapture  []byte
	Closed        bool
	// contains filtered or unexported fields
}

FakeExecStream implements ExecStream for testing

func NewFakeExecStream

func NewFakeExecStream(stdout, stderr []byte, exitCode int) *FakeExecStream

NewFakeExecStream creates a new fake exec stream with predefined content

func (*FakeExecStream) Close

func (s *FakeExecStream) Close() error

Close marks the stream as closed

func (*FakeExecStream) ExitCode

func (s *FakeExecStream) ExitCode() (int, error)

ExitCode returns the predefined exit code

func (*FakeExecStream) Read

func (s *FakeExecStream) Read(p []byte) (n int, err error)

Read returns predefined output content in chunks

func (*FakeExecStream) ResizeTerminal

func (s *FakeExecStream) ResizeTerminal(width, height uint32) error

ResizeTerminal records terminal resize events

func (*FakeExecStream) Signal

func (s *FakeExecStream) Signal(sigName string) error

Signal records signals sent to the process

func (*FakeExecStream) Stderr

func (s *FakeExecStream) Stderr() io.Reader

Stderr returns an io.Reader for the stderr stream

func (*FakeExecStream) Write

func (s *FakeExecStream) Write(p []byte) (n int, err error)

Write captures input that would be sent to the exec process

type HealthChecker

type HealthChecker interface {
	HealthCheck(ctx context.Context) error
}

HealthChecker is implemented by runners that can verify their backing runtime is reachable (e.g. the Docker runner pinging the daemon). A runner that does not implement it is treated as always-ready — correct for the process runner, which has no external daemon. Used by RunnerManager.RunnerHealth to surface "Docker is down" in `rune status`.

type IPProvider

type IPProvider interface {
	InstanceIP(ctx context.Context, instance *types.Instance) (string, error)
}

IPProvider is implemented by runners that can resolve a running instance's primary routable IP for endpoint publishing.

type InitCall

type InitCall struct {
	InstanceID string
	Step       types.InitStep
}

InitCall captures one Runner.RunInit invocation for assertions in tests.

type InstanceStatus

type InstanceStatus struct {
	// State is the current state of the instance.
	State types.InstanceStatus

	// ContainerID is the ID of the container (if applicable).
	ContainerID string

	// InstanceID is the ID of the Rune instance.
	InstanceID string

	// CreatedAt is when the instance was created.
	CreatedAt time.Time

	// StartedAt is when the instance was started.
	StartedAt time.Time

	// FinishedAt is when the instance finished or failed.
	FinishedAt time.Time

	// ExitCode is the exit code if the instance has stopped.
	ExitCode int

	// ErrorMessage contains any error information.
	ErrorMessage string
}

InstanceStatus extends types.InstanceStatus with additional details needed by runners.

type LogOptions

type LogOptions struct {
	// Follow indicates whether to follow the log output (like tail -f).
	Follow bool

	// Tail indicates the number of lines to show from the end of the logs (0 for all).
	Tail int

	// Since shows logs since a specific timestamp.
	Since time.Time

	// Until shows logs until a specific timestamp.
	Until time.Time

	// Timestamps indicates whether to include timestamps.
	Timestamps bool
}

LogOptions defines options for retrieving logs.

type LogReader

type LogReader interface {
	Reader
}

LogReader represents a readable stream of log data.

type MockExecStream

type MockExecStream struct {
	mock.Mock
}

MockExecStream is a mock implementation of the runner.ExecStream interface

func (*MockExecStream) Close

func (m *MockExecStream) Close() error

func (*MockExecStream) ExitCode

func (m *MockExecStream) ExitCode() (int, error)

func (*MockExecStream) Read

func (m *MockExecStream) Read(p []byte) (n int, err error)

func (*MockExecStream) ResizeTerminal

func (m *MockExecStream) ResizeTerminal(width, height uint32) error

func (*MockExecStream) Signal

func (m *MockExecStream) Signal(sigName string) error

func (*MockExecStream) Stderr

func (m *MockExecStream) Stderr() io.Reader

func (*MockExecStream) Write

func (m *MockExecStream) Write(p []byte) (n int, err error)

type MockRunner

type MockRunner struct {
	mock.Mock
}

MockRunner is a mock implementation of the runner.Runner interface for testing

func (*MockRunner) Create

func (m *MockRunner) Create(ctx context.Context, instance *types.Instance) error

func (*MockRunner) Exec

func (m *MockRunner) Exec(ctx context.Context, instance *types.Instance, options ExecOptions) (ExecStream, error)

func (*MockRunner) GetLogs

func (m *MockRunner) GetLogs(ctx context.Context, instance *types.Instance, options LogOptions) (io.ReadCloser, error)

func (*MockRunner) List

func (m *MockRunner) List(ctx context.Context, namespace string) ([]*types.Instance, error)

func (*MockRunner) Remove

func (m *MockRunner) Remove(ctx context.Context, instance *types.Instance, force bool) error

func (*MockRunner) RunDebug

func (m *MockRunner) RunDebug(ctx context.Context, instance *types.Instance, options ExecOptions) (ExecStream, error)

func (*MockRunner) RunInit

func (m *MockRunner) RunInit(ctx context.Context, instance *types.Instance, step types.InitStep) (int, error)

func (*MockRunner) Start

func (m *MockRunner) Start(ctx context.Context, instance *types.Instance) error

func (*MockRunner) Status

func (m *MockRunner) Status(ctx context.Context, instance *types.Instance) (types.InstanceStatus, error)

func (*MockRunner) Stop

func (m *MockRunner) Stop(ctx context.Context, instance *types.Instance, timeout time.Duration) error

type Reader

type Reader interface {
	io.Reader
}

Reader is an interface that represents a readable stream. It extends the standard io.Reader interface.

type Runner

type Runner interface {
	// Type returns the type of runner.
	Type() types.RunnerType

	// Create creates a new service instance but does not start it.
	Create(ctx context.Context, instance *types.Instance) error

	// Start starts an existing service instance.
	Start(ctx context.Context, instance *types.Instance) error

	// Stop stops a running service instance.
	Stop(ctx context.Context, instance *types.Instance, timeout time.Duration) error

	// Remove removes a service instance.
	Remove(ctx context.Context, instance *types.Instance, force bool) error

	// GetLogs retrieves logs from a service instance.
	GetLogs(ctx context.Context, instance *types.Instance, options LogOptions) (io.ReadCloser, error)

	// Status retrieves the current status of a service instance.
	Status(ctx context.Context, instance *types.Instance) (types.InstanceStatus, error)

	// List lists all service instances managed by this runner.
	List(ctx context.Context, namespace string) ([]*types.Instance, error)

	// Exec creates an interactive exec session with a running instance.
	// Returns an ExecStream for bidirectional communication.
	Exec(ctx context.Context, instance *types.Instance, options ExecOptions) (ExecStream, error)

	// RunDebug spawns an ephemeral inspection container ("sidecar") from
	// the given (typically Failed) instance's image+env+mounts, with the
	// entrypoint overridden to `sleep infinity` so the inner app does NOT
	// re-run, then opens an exec session against the sidecar to run the
	// caller's command. The sidecar is stopped and removed when the
	// returned ExecStream is Closed (use defer). The original instance's
	// container is never touched.
	//
	// Runners that don't support spawn-from-template return
	// ErrDebugNotSupported.
	RunDebug(ctx context.Context, instance *types.Instance, options ExecOptions) (ExecStream, error)

	// Dial opens a TCP connection to the given port on the running
	// instance. Used by the port-forward command (RUNE-122). The
	// returned net.Conn is owned by the caller and must be Closed.
	// Implementations should honour ctx for the dial itself; the
	// returned Conn carries its own lifetime thereafter.
	Dial(ctx context.Context, instance *types.Instance, port uint32) (net.Conn, error)

	// RunInit executes one InitStep (RUNE-121) synchronously against
	// the given instance and returns the step's exit code (0 on
	// success). The runner is responsible for:
	//
	//   - filtering the instance's resolved volume / secret / config
	//     mounts according to step.Volumes / step.SecretMounts /
	//     step.ConfigmapMounts (a nil filter inherits all; a non-nil
	//     empty filter mounts none),
	//   - merging step.Env over the instance environment (step keys
	//     win),
	//   - applying step.Resources when set (otherwise inherit the
	//     instance's resources),
	//   - honouring the instance's image-pull policy for step.Image,
	//   - waiting for the step to terminate (or be cancelled via
	//     ctx) and capturing logs,
	//   - cleaning up the underlying container/process before
	//     returning.
	//
	// The instance controller, not the runner, owns iteration order,
	// runIf evaluation, restart-policy retries, and persistence of
	// InitStepState.
	//
	// Runners that do not support init steps must return
	// ErrInitNotSupported.
	RunInit(ctx context.Context, instance *types.Instance, step types.InitStep) (exitCode int, err error)
}

Runner defines the interface for service runners, which are responsible for managing the lifecycle of service instances (containers, processes, etc.).

type RunnerProvider

type RunnerProvider interface {
	// GetInstanceRunner returns the appropriate runner for an instance
	GetInstanceRunner(instance *types.Instance) (Runner, error)
}

RunnerProvider defines a simplified interface for getting runners

type StatsProvider

type StatsProvider interface {
	InstanceStats(ctx context.Context, instance *types.Instance) (*types.InstanceUsage, error)
}

StatsProvider is implemented by runners that can report live resource usage for a running instance (the docker runner via the daemon's stats API). Runners without the capability simply don't implement it — the API read path type-asserts and leaves Instance.Usage nil, which the dashboard renders as "unknown" rather than 0.

CPUPercent semantics: share of the WHOLE HOST (0–100), the same denominator as node-level CPU on HealthService, so instance and node bars compare 1:1.

type TestExecStream

type TestExecStream struct {
	StdoutContent []byte
	StderrContent []byte
	ExitCodeVal   int
	InputCapture  []byte
	SignalsSent   []string
	Resizes       []struct{ Width, Height uint32 }
	// contains filtered or unexported fields
}

TestExecStream is a predictable implementation of ExecStream for testing

func (*TestExecStream) Close

func (s *TestExecStream) Close() error

Close marks the stream as closed

func (*TestExecStream) ExitCode

func (s *TestExecStream) ExitCode() (int, error)

ExitCode returns the predefined exit code

func (*TestExecStream) Read

func (s *TestExecStream) Read(p []byte) (n int, err error)

Read returns predefined output content in chunks

func (*TestExecStream) ResizeTerminal

func (s *TestExecStream) ResizeTerminal(width, height uint32) error

ResizeTerminal records terminal resize events

func (*TestExecStream) Signal

func (s *TestExecStream) Signal(sigName string) error

Signal records signals sent to the process

func (*TestExecStream) Stderr

func (s *TestExecStream) Stderr() io.Reader

Stderr returns an io.Reader for the stderr stream

func (*TestExecStream) Write

func (s *TestExecStream) Write(p []byte) (n int, err error)

Write captures input that would be sent to the exec process

type TestRunner

type TestRunner struct {
	// Configurable test behavior
	StatusResults map[string]types.InstanceStatus
	Instances     map[string]*types.Instance
	ExecOutput    []byte
	ExecErrOutput []byte
	ExitCodeVal   int
	LogOutput     []byte
	ErrorToReturn error

	// Optional tracking for verification
	CreatedInstances []*types.Instance
	StartedInstances []string
	StoppedInstances []string
	RemovedInstances []string
	ExecCalls        []string
	ExecOptions      []ExecOptions
	LogCalls         []string
	StatusCalls      []string

	// Port-forward tracking (RUNE-122)
	DialCalls    []DialCall
	LastDialPeer net.Conn

	// StopFunc, if non-nil, replaces the default Stop behaviour.
	// Tests use this to observe store state mid-teardown (e.g. assert
	// the controller flipped Status=Terminating BEFORE invoking
	// runner.Stop, not after).
	StopFunc func(ctx context.Context, instance *types.Instance, timeout time.Duration) error

	// Init step tracking (RUNE-121)
	InitCalls    []InitCall
	InitExitCode int
	// InitFunc, if non-nil, overrides the default behaviour. It is
	// invoked under r.mu and receives the current 1-based attempt count
	// for this step (so tests can simulate "fail twice then succeed"
	// scenarios). Returning a nil error and exit==0 means success.
	InitFunc func(call int, step types.InitStep) (int, error)
	// contains filtered or unexported fields
}

TestRunner is a simplified, predictable implementation of Runner for testing. Instead of requiring expectations to be set up, it returns predefined responses.

func NewTestRunner

func NewTestRunner() *TestRunner

NewTestRunner creates a new TestRunner with default behavior

func (*TestRunner) Create

func (r *TestRunner) Create(ctx context.Context, instance *types.Instance) error

Create tracks instance creation

func (*TestRunner) Dial

func (r *TestRunner) Dial(ctx context.Context, instance *types.Instance, port uint32) (net.Conn, error)

Dial returns one end of a net.Pipe; the other end is exposed via LastDialPeer for tests that want to read/write the "remote side." DialCalls captures the call. If ErrorToReturn is set the call fails.

func (*TestRunner) Exec

func (r *TestRunner) Exec(ctx context.Context, instance *types.Instance, options ExecOptions) (ExecStream, error)

Exec returns a predefined TestExecStream

func (*TestRunner) GetExecCalls

func (r *TestRunner) GetExecCalls() []string

GetExecCalls returns a copy of ExecCalls (thread-safe)

func (*TestRunner) GetLogs

func (r *TestRunner) GetLogs(ctx context.Context, instance *types.Instance, options LogOptions) (io.ReadCloser, error)

GetLogs returns predefined log output

func (*TestRunner) GetStartedInstances

func (r *TestRunner) GetStartedInstances() []string

GetStartedInstances returns a copy of StartedInstances (thread-safe)

func (*TestRunner) GetStoppedInstances

func (r *TestRunner) GetStoppedInstances() []string

GetStoppedInstances returns a copy of StoppedInstances (thread-safe)

func (*TestRunner) List

func (r *TestRunner) List(ctx context.Context, namespace string) ([]*types.Instance, error)

List returns all registered instances

func (*TestRunner) Remove

func (r *TestRunner) Remove(ctx context.Context, instance *types.Instance, force bool) error

Remove tracks instance removal

func (*TestRunner) RunDebug

func (r *TestRunner) RunDebug(ctx context.Context, instance *types.Instance, options ExecOptions) (ExecStream, error)

RunDebug is unsupported by the test runner; included so it satisfies the Runner interface. Returns ErrDebugNotSupported.

func (*TestRunner) RunInit

func (r *TestRunner) RunInit(ctx context.Context, instance *types.Instance, step types.InitStep) (int, error)

RunInit records the call and returns the configured init exit code. Errors are surfaced via ErrorToReturn for parity with other methods. For per-attempt control (e.g. retry tests), set InitFunc.

func (*TestRunner) Start

func (r *TestRunner) Start(ctx context.Context, instance *types.Instance) error

Start tracks instance starting

func (*TestRunner) Status

func (r *TestRunner) Status(ctx context.Context, instance *types.Instance) (types.InstanceStatus, error)

Status returns predefined status or Running as default

func (*TestRunner) Stop

func (r *TestRunner) Stop(ctx context.Context, instance *types.Instance, timeout time.Duration) error

Stop tracks instance stopping. If StopFunc is set, it overrides the default behaviour — useful for tests that need to inspect store / runner state mid-teardown without racing the controller's own goroutines.

func (*TestRunner) Type

func (r *TestRunner) Type() types.RunnerType

Directories

Path Synopsis
Package docker — RUNE-121 init-step execution.
Package docker — RUNE-121 init-step execution.
bridges
Package bridges enumerates Docker bridge networks so the agent's embedded DNS server can bind on each bridge gateway IP.
Package bridges enumerates Docker bridge networks so the agent's embedded DNS server can bind on each bridge gateway IP.
Package process — RUNE-121 init-step execution for the process runtime.
Package process — RUNE-121 init-step execution for the process runtime.
security
Package security provides security implementations for process runners
Package security provides security implementations for process runners

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL