docker

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: 27 Imported by: 0

Documentation

Overview

Package docker — RUNE-121 init-step execution.

Package docker provides a Docker-based implementation of the runner interface.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DockerClient

type DockerClient interface {
	ContainerExecCreate(ctx context.Context, containerID string, config container.ExecOptions) (container.ExecCreateResponse, error)
	ContainerExecAttach(ctx context.Context, execID string, config container.ExecStartOptions) (types.HijackedResponse, error)
	ContainerExecInspect(ctx context.Context, execID string) (container.ExecInspect, error)
	ContainerExecResize(ctx context.Context, execID string, options container.ResizeOptions) error
}

DockerClient defines the Docker API methods we need

type DockerConfig

type DockerConfig struct {
	// APIVersion is the Docker API version to use
	// If empty, auto-negotiation will be used
	APIVersion string

	// FallbackAPIVersion is used when auto-negotiation fails
	// Default is "1.43" which is widely compatible
	FallbackAPIVersion string

	// Timeout for API version negotiation in seconds
	NegotiationTimeoutSeconds int

	// Permissions for mounts created on the host before binding into containers
	// If zero, sensible defaults will be used.
	SecretDirMode  os.FileMode
	SecretFileMode os.FileMode
	ConfigDirMode  os.FileMode
	ConfigFileMode os.FileMode

	// Registry authentication configuration loaded from runefile
	Registries []RegistryConfig

	// DisableAmbientRegistryAuth turns off the ambient fallbacks used
	// when no [[docker.registries]] entry matches an image host: the
	// GCE metadata service account (Artifact Registry / GCR) and the
	// docker CLI config of the user runed runs as. Off by default —
	// ambient auth only engages when explicit config resolved nothing.
	DisableAmbientRegistryAuth bool

	// Container log rotation for the json-file driver. Caps per-container log
	// growth on the host — the agent log forwarder reads container logs but does
	// not truncate them, so without this the daemon's logs grow unbounded.
	// LogMaxSize empty disables rotation (inherit the daemon default);
	// LogMaxFile <= 0 omits max-file.
	LogMaxSize string // e.g. "10m"
	LogMaxFile int    // e.g. 3
}

DockerConfig holds Docker runner configuration options

func DefaultDockerConfig

func DefaultDockerConfig() *DockerConfig

DefaultDockerConfig returns the default Docker configuration

type DockerExecStream

type DockerExecStream struct {
	// contains filtered or unexported fields
}

DockerExecStream implements the runner.ExecStream interface for Docker containers.

func NewDockerExecStream

func NewDockerExecStream(
	ctx context.Context,
	cli DockerClient,
	containerID string,
	instanceID string,
	options runner.ExecOptions,
	logger log.Logger,
) (*DockerExecStream, error)

NewDockerExecStream creates a new DockerExecStream.

func (*DockerExecStream) Close

func (s *DockerExecStream) Close() error

Close terminates the exec session and releases resources.

func (*DockerExecStream) ExitCode

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

ExitCode blocks until the exec process completes, then returns its exit code. The wait is bounded by the stream's context (s.ctx) — a probe timeout or Close() unblocks it — so a hung command surfaces as an error rather than blocking forever.

func (*DockerExecStream) Read

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

Read reads data from the standard output of the process.

func (*DockerExecStream) ResizeTerminal

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

ResizeTerminal resizes the terminal (if TTY was enabled).

func (*DockerExecStream) Signal

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

Signal sends a signal to the process.

func (*DockerExecStream) Stderr

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

Stderr provides access to the standard error stream of the process.

func (*DockerExecStream) Write

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

Write sends data to the standard input of the process.

type DockerRunner

type DockerRunner struct {
	// contains filtered or unexported fields
}

DockerRunner implements the runner.Runner interface for Docker.

func NewDockerRunner

func NewDockerRunner(logger log.Logger) (*DockerRunner, error)

NewDockerRunner creates a new DockerRunner instance.

func NewDockerRunnerWithConfig

func NewDockerRunnerWithConfig(logger log.Logger, config *DockerConfig) (*DockerRunner, error)

NewDockerRunnerWithConfig creates a new DockerRunner with specific configuration.

func (*DockerRunner) Create

func (r *DockerRunner) Create(ctx context.Context, instance *runetypes.Instance) error

Create creates a new container but does not start it. The container name is `<namespace>-<instance.Name>-<id_prefix>` where id_prefix starts at 8 hex chars of the instance UUID and extends only when docker reports a name collision — git-style abbreviation. The UUID suffix:

  • Eliminates cross-namespace collisions (the `landing-0` bug): prod-landing-0-<id> and dev-landing-0-<id> never collide.
  • Eliminates the tombstone-rename dance: a Failed instance keeps its container forever, and the freshly-created replacement gets its own UUID-suffixed name without colliding.
  • Stays human-readable: `docker ps` shows "prod-landing-0-5d68e677" which encodes ns/service/ordinal/id.

Container lookups in this runner go through `getContainerID` which prefers `instance.ContainerID` over labels, so dynamic-length names do not complicate any code path.

func (*DockerRunner) Dial

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

Dial opens a TCP connection to the given port on the container's network address. Used by `rune port-forward` (RUNE-122). The container IP is discovered via the same logic the rest of the runner uses (pickContainerIP) so behaviour is consistent with how the orchestrator's ingress and networking layers reach containers.

TODO(multi-node): today every container runs on the runed host so this dial is local. Once instances can live on other nodes (Release 2), this must route through the bound node's agent.

func (*DockerRunner) Exec

func (r *DockerRunner) Exec(ctx context.Context, instance *runetypes.Instance, options runner.ExecOptions) (runner.ExecStream, error)

Exec creates an interactive exec session with a running container.

func (*DockerRunner) GetLogs

func (r *DockerRunner) GetLogs(ctx context.Context, instance *runetypes.Instance, options runner.LogOptions) (io.ReadCloser, error)

GetLogs retrieves logs from a container.

func (*DockerRunner) HealthCheck

func (r *DockerRunner) HealthCheck(ctx context.Context) error

HealthCheck pings the Docker daemon. A non-nil error means the daemon is unreachable — the server keeps running and the store stays fine, but no container can be created/started/restarted until Docker recovers. This is the signal `rune status` surfaces as "Runners: docker=unreachable".

func (*DockerRunner) InstanceIP

func (r *DockerRunner) InstanceIP(ctx context.Context, instance *runetypes.Instance) (string, error)

InstanceIP implements runner.IPProvider for endpoint publishing.

func (*DockerRunner) InstanceStats

func (r *DockerRunner) InstanceStats(ctx context.Context, instance *types.Instance) (*types.InstanceUsage, error)

InstanceStats reports a live resource-usage sample for the instance's container, implementing runner.StatsProvider.

Sampling strategy (keeps list RPCs fast after the first call):

  • First read for a container: a blocking stats read (stream=false) — the daemon primes it with two internal samples (~1s) so PreCPUStats is valid and the very first answer is a real instantaneous percent.
  • Subsequent reads: a ContainerStatsOneShot (single fast sample) with the CPU delta computed against our cached previous counters — i.e. average CPU over the interval since the last read.
  • Reads within statsResultTTL return the previous computed sample without touching the daemon.

func (*DockerRunner) List

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

List lists all service instances managed by this runner.

func (*DockerRunner) Remove

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

Remove removes a container.

func (*DockerRunner) RunDebug

func (r *DockerRunner) RunDebug(ctx context.Context, instance *runetypes.Instance, options runner.ExecOptions) (runner.ExecStream, error)

RunDebug spawns an ephemeral inspection sidecar from the given instance's template (image, env, mounts, resources) with the entrypoint overridden to `sleep infinity` so the failing app does not re-run. Opens an exec session against the sidecar to run options.Command. The sidecar is torn down (stop + remove) when the returned ExecStream is Closed.

The caller's instance is treated as a TEMPLATE only — its container is not touched. The sidecar gets its own container ID + labels so getContainerID lookups never confuse the two.

func (*DockerRunner) RunInit

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

RunInit implements runner.Runner.RunInit for Docker. It runs one InitStep as a one-shot container that shares the parent instance's resolved volume / secret / config mounts (filtered per the step spec) and waits for it to terminate.

On normal termination RunInit returns the container's exit code (zero on success). On RuntimeError (image pull failure, container create/start failure, log capture failure, etc.) it returns a non-nil error and the exit code is undefined.

Cancellation of ctx kills the step container and removes it.

func (*DockerRunner) SetDNSInjection

func (r *DockerRunner) SetDNSInjection(servers []string, search []string)

SetDNSInjection toggles --dns/--dns-search injection on subsequent ContainerCreate calls. The agent calls this after the embedded DNS server has bound (RUNE-063) and the data plane is healthy (RUNE-041). Pass nil/empty servers to disable injection.

Safe to call concurrently with container creates: only future creates pick up the new value.

func (*DockerRunner) Start

func (r *DockerRunner) Start(ctx context.Context, instance *runetypes.Instance) error

Start starts an existing container.

func (*DockerRunner) Status

Status retrieves the current status of a container.

Self-heal: when the stored instance.ContainerID no longer inspects (RUNE-BUG: a stale mapping made the reconciler recreate healthy probed services forever), the container is re-resolved through the rune.instance.id label — a label match is definitively THIS instance's container, since every UUID gets exactly one. On a hit the in-memory instance is updated (ContainerID + ContainerIP); the orchestrator persists the healed mapping when it observes the change. If the label lookup finds nothing the container is genuinely gone and the not-found error stands (recreate is correct).

func (*DockerRunner) Stop

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

Stop stops a running container.

func (*DockerRunner) Type

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

type RegistryAuth

type RegistryAuth struct {
	Type     string `mapstructure:"type"` // basic | token | dockerconfigjson | ecr | gcp
	Username string `mapstructure:"username"`
	Password string `mapstructure:"password"`
	Token    string `mapstructure:"token"`
	Region   string `mapstructure:"region"`
}

RegistryAuth defines supported auth types

type RegistryConfig

type RegistryConfig struct {
	Name     string       `mapstructure:"name"`
	Registry string       `mapstructure:"registry"`
	Auth     RegistryAuth `mapstructure:"auth"`
}

RegistryConfig defines a registry auth entry

type SliceStringer

type SliceStringer []string

SliceStringer creates a string formatter for string slices.

func (SliceStringer) String

func (s SliceStringer) String() string

String implements the fmt.Stringer interface.

Directories

Path Synopsis
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.

Jump to

Keyboard shortcuts

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