Documentation
¶
Overview ¶
Package docker — RUNE-121 init-step execution.
Package docker provides a Docker-based implementation of the runner interface.
Index ¶
- type DockerClient
- type DockerConfig
- type DockerExecStream
- func (s *DockerExecStream) Close() error
- func (s *DockerExecStream) ExitCode() (int, error)
- func (s *DockerExecStream) Read(p []byte) (n int, err error)
- func (s *DockerExecStream) ResizeTerminal(width, height uint32) error
- func (s *DockerExecStream) Signal(sigName string) error
- func (s *DockerExecStream) Stderr() io.Reader
- func (s *DockerExecStream) Write(p []byte) (n int, err error)
- type DockerRunner
- func (r *DockerRunner) Create(ctx context.Context, instance *runetypes.Instance) error
- func (r *DockerRunner) Dial(ctx context.Context, instance *runetypes.Instance, port uint32) (net.Conn, error)
- func (r *DockerRunner) Exec(ctx context.Context, instance *runetypes.Instance, options runner.ExecOptions) (runner.ExecStream, error)
- func (r *DockerRunner) GetLogs(ctx context.Context, instance *runetypes.Instance, options runner.LogOptions) (io.ReadCloser, error)
- func (r *DockerRunner) HealthCheck(ctx context.Context) error
- func (r *DockerRunner) InstanceIP(ctx context.Context, instance *runetypes.Instance) (string, error)
- func (r *DockerRunner) InstanceStats(ctx context.Context, instance *types.Instance) (*types.InstanceUsage, error)
- func (r *DockerRunner) List(ctx context.Context, namespace string) ([]*runetypes.Instance, error)
- func (r *DockerRunner) Remove(ctx context.Context, instance *runetypes.Instance, force bool) error
- func (r *DockerRunner) RunDebug(ctx context.Context, instance *runetypes.Instance, options runner.ExecOptions) (runner.ExecStream, error)
- func (r *DockerRunner) RunInit(ctx context.Context, instance *runetypes.Instance, step runetypes.InitStep) (int, error)
- func (r *DockerRunner) SetDNSInjection(servers []string, search []string)
- func (r *DockerRunner) Start(ctx context.Context, instance *runetypes.Instance) error
- func (r *DockerRunner) Status(ctx context.Context, instance *runetypes.Instance) (runetypes.InstanceStatus, error)
- func (r *DockerRunner) Stop(ctx context.Context, instance *runetypes.Instance, timeout time.Duration) error
- func (r *DockerRunner) Type() types.RunnerType
- type RegistryAuth
- type RegistryConfig
- type SliceStringer
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.
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 ¶
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) 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) Status ¶
func (r *DockerRunner) Status(ctx context.Context, instance *runetypes.Instance) (runetypes.InstanceStatus, error)
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. |