Documentation
¶
Overview ¶
Package container provides container lifecycle management for agents.
Index ¶
- type AgentOpts
- type Container
- type ContainerManager
- type DockerManager
- func (m *DockerManager) CaptureToolserverDiagnostics(ctx context.Context, name, reason string) error
- func (m *DockerManager) Close()
- func (m *DockerManager) GetRunning(ctx context.Context, agentID uuid.UUID) (*Container, error)
- func (m *DockerManager) KillToolserver(ctx context.Context, name string) error
- func (m *DockerManager) LockSwap(agentID uuid.UUID) func()
- func (m *DockerManager) MarkBusy(agentID uuid.UUID)
- func (m *DockerManager) MarkIdle(agentID uuid.UUID)
- func (m *DockerManager) PruneAgentResources(ctx context.Context, validAgents map[string]string)
- func (m *DockerManager) RemoveImage(ctx context.Context, imageRef string) error
- func (m *DockerManager) RunningAgents(ctx context.Context, agentIDs []uuid.UUID) (map[uuid.UUID]bool, error)
- func (m *DockerManager) StartAgent(ctx context.Context, opts AgentOpts) (*Container, error)
- func (m *DockerManager) StartToolserver(ctx context.Context, opts ToolserverOpts) (*Container, error)
- func (m *DockerManager) StopAgent(ctx context.Context, agentID uuid.UUID) error
- func (m *DockerManager) StopToolserver(ctx context.Context, name string) error
- type ToolserverOpts
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AgentOpts ¶
type AgentOpts struct {
AgentID uuid.UUID
Image string // Docker image to run (e.g., "my-agent:abc123")
Env map[string]string // Additional environment variables
}
AgentOpts configures an agent container.
type Container ¶
type Container struct {
ID string // Docker container ID
Name string // Human-readable name
Endpoint string // HTTP endpoint (e.g., "http://172.17.0.2:8080")
Token string // Bearer token for authenticating requests to this container
// Image is the tag the container was started with, copied from
// Docker's Config.Image at inspect time. StartAgent compares this
// against opts.Image to detect a stale running container after a
// build/rollback swap — adopting one with the wrong image would
// silently keep the agent on the old code.
Image string
}
Container represents a running container.
type ContainerManager ¶
type ContainerManager interface {
// StartAgent ensures an agent container is running.
// Returns the existing container if already running and healthy.
StartAgent(ctx context.Context, opts AgentOpts) (*Container, error)
// GetRunning returns the running container for an agent without starting
// one if absent. Returns (nil, nil) when no container is up. Used by
// out-of-band signals (e.g. /refresh push) where booting a container
// just to notify it would defeat the purpose.
GetRunning(ctx context.Context, agentID uuid.UUID) (*Container, error)
// RunningAgents reports, per requested agent ID, whether a running
// container currently exists for it. One Docker query regardless of
// how many agents are asked about — for list/grid views that would
// otherwise fan out into one inspect per agent.
RunningAgents(ctx context.Context, agentIDs []uuid.UUID) (map[uuid.UUID]bool, error)
// StopAgent stops a specific agent's container (resolved from the agent
// ID via the instance-scoped name scheme).
StopAgent(ctx context.Context, agentID uuid.UUID) error
// MarkBusy / MarkIdle bracket an in-flight request to an agent
// container. While the in-flight count is above zero the idle
// reaper leaves the container alone, even past the idle timeout —
// so a run that runs longer than the timeout is not killed
// mid-execution. MarkIdle also refreshes the idle clock, so the
// timeout is measured from the end of the last request. Pair every
// MarkBusy with exactly one MarkIdle.
MarkBusy(agentID uuid.UUID)
MarkIdle(agentID uuid.UUID)
// StartToolserver starts an ephemeral toolserver container for build operations.
// Returns the container with a WebSocket endpoint for tool execution.
StartToolserver(ctx context.Context, opts ToolserverOpts) (*Container, error)
// StopToolserver stops and removes an ephemeral toolserver container.
StopToolserver(ctx context.Context, name string) error
// KillToolserver force-kills (SIGKILL) and removes an ephemeral
// toolserver container without waiting for graceful shutdown. Used
// on the build-cancel path so an in-flight tool stops emitting logs
// the moment cancel hits, instead of after the 5s graceful timeout.
KillToolserver(ctx context.Context, name string) error
// CaptureToolserverDiagnostics snapshots abnormal runtime state/logs
// before the ephemeral toolserver container is removed.
CaptureToolserverDiagnostics(ctx context.Context, name, reason string) error
// RemoveImage removes a Docker image by reference (e.g., "agentID:hash").
RemoveImage(ctx context.Context, imageRef string) error
// LockSwap serializes the agent's container-swap window. Held by the
// builder around Phase F (StopAgent → StartAgent → UpdateAgentRefs)
// and by EnsureRunning around its GetAgent → StartAgent critical
// section, so a concurrent trigger can't start the old image while a
// build is mid-swap (and vice versa). Returns a release function
// callers must defer. Scope is just the swap — codegen, image build,
// and migration validation all run outside the lock.
LockSwap(agentID uuid.UUID) func()
}
ContainerManager manages the lifecycle of agent containers.
type DockerManager ¶
type DockerManager struct {
// contains filtered or unexported fields
}
DockerManager implements ContainerManager using the Docker API.
func NewDockerManager ¶
func NewDockerManager(cfg *config.Config, logger *zap.Logger) *DockerManager
NewDockerManager creates a Docker-based ContainerManager.
func (*DockerManager) CaptureToolserverDiagnostics ¶ added in v0.4.0
func (m *DockerManager) CaptureToolserverDiagnostics(ctx context.Context, name, reason string) error
CaptureToolserverDiagnostics snapshots abnormal tool runtime state/logs.
func (*DockerManager) Close ¶
func (m *DockerManager) Close()
Close stops the idle reaper and closes the Docker client.
func (*DockerManager) GetRunning ¶
GetRunning implements ContainerManager. Returns (nil, nil) when no container exists for the agent — caller is expected to treat that as "nothing to do" rather than an error. Repopulates the in-memory cache when it finds a running container Airlock didn't previously know about (typical after an Airlock restart).
func (*DockerManager) KillToolserver ¶ added in v0.1.6
func (m *DockerManager) KillToolserver(ctx context.Context, name string) error
KillToolserver force-removes an ephemeral toolserver container without waiting for graceful shutdown. RemoveOptions{Force: true} sends SIGKILL and removes in one call, so any in-flight tool execution dies immediately. Used by the build-cancellation path: graceful shutdown is 5+ seconds of dead air during which the toolserver keeps running its in-flight tool (e.g. a long `bash go build`) and emitting log lines — which makes the cancel feel like it didn't take. Idempotent: returns nil/NotFound if the container is already gone.
func (*DockerManager) LockSwap ¶ added in v0.4.0
func (m *DockerManager) LockSwap(agentID uuid.UUID) func()
LockSwap acquires the per-agent container-swap mutex. See the ContainerManager interface comment for the design rationale.
func (*DockerManager) MarkBusy ¶ added in v0.4.0
func (m *DockerManager) MarkBusy(agentID uuid.UUID)
MarkBusy records the start of an in-flight request to an agent container. While the in-flight count is above zero the idle reaper skips the container, so a run that outlasts idleTimeout is not stopped mid-execution. Pair every MarkBusy with exactly one MarkIdle.
func (*DockerManager) MarkIdle ¶ added in v0.4.0
func (m *DockerManager) MarkIdle(agentID uuid.UUID)
MarkIdle records the end of an in-flight request. It also refreshes the idle clock so the timeout is measured from the end of the last request rather than its start.
func (*DockerManager) PruneAgentResources ¶
func (m *DockerManager) PruneAgentResources(ctx context.Context, validAgents map[string]string)
PruneAgentResources removes Docker containers and images for agents that no longer exist in the database, and removes stale image tags for active agents (keeping only the current image_ref).
validAgents maps agent UUID string → current image_ref (e.g., "uuid:hash"). Any container or UUID-tagged image owned by this instance (run.airlock.instance label) not matching this set is removed. Other instances' resources carry a different label value and are never listed here.
func (*DockerManager) RemoveImage ¶
func (m *DockerManager) RemoveImage(ctx context.Context, imageRef string) error
RemoveImage removes a Docker image by reference.
func (*DockerManager) RunningAgents ¶ added in v0.4.0
func (m *DockerManager) RunningAgents(ctx context.Context, agentIDs []uuid.UUID) (map[uuid.UUID]bool, error)
RunningAgents implements ContainerManager. One ContainerList call, scoped to this instance via the ownership label, then matched back to the requested IDs via agentName. Builder/toolserver containers ("<instance>-agent-builder-*") also carry the label but never equal an agentName(id), so they fall out of the lookup harmlessly.
func (*DockerManager) StartAgent ¶
StartAgent implements ContainerManager.
func (*DockerManager) StartToolserver ¶
func (m *DockerManager) StartToolserver(ctx context.Context, opts ToolserverOpts) (*Container, error)
StartToolserver starts an ephemeral toolserver container for build operations. The container runs the toolserver binary with the workspace mounted. Returns the container with a WebSocket endpoint for remote tool execution.
func (*DockerManager) StopAgent ¶
StopAgent implements ContainerManager. Idempotent: if Docker stopped or removed the container out-of-band (crash, OOM, daemon restart, the idle reaper), the desired post-condition — container not running — is already met, so a not-found error is success. Without this a dead-but-status='active' agent could never be stopped and so never restarted (the UI only offers Stop while active).
func (*DockerManager) StopToolserver ¶
func (m *DockerManager) StopToolserver(ctx context.Context, name string) error
StopToolserver stops and removes an ephemeral toolserver container.
type ToolserverOpts ¶
type ToolserverOpts struct {
Image string // toolserver image (e.g., "agent-builder:v1.0.0")
Mounts []mount.Mount // workspace bind mounts
WorkDir string // -space-dir value inside the container
Env []string // additional environment variables
LogCallback func(line string)
}
ToolserverOpts configures an ephemeral toolserver container for build operations.