docker

package
v0.19.18 Latest Latest
Warning

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

Go to latest
Published: Feb 26, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package docker manages container lifecycle for sandboxed agent sessions.

Shell assumptions: commands delivered via tmux traverse two shell layers (tmux's implicit /bin/sh -c and wrapIgnoreSuspend's bash -c). Values in ExecPrefix / ExecPrefixWithEnv are therefore unquoted — quoting is applied once at the wrapIgnoreSuspend boundary.

Security: the Docker socket is intentionally NOT mounted into containers. Agents run inside a sandbox with no access to the host Docker daemon.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrDockerNotAvailable indicates the docker CLI is not installed.
	ErrDockerNotAvailable = errors.New("docker CLI is not installed or not in PATH")

	// ErrDaemonNotRunning indicates the docker daemon is not running.
	ErrDaemonNotRunning = errors.New("docker daemon is not running; start Docker and try again")
)

Sentinel errors for Docker operations.

Functions

func CheckAvailability

func CheckAvailability(ctx context.Context) error

CheckAvailability verifies both the CLI and the daemon are usable. Returns nil when docker is ready, or a descriptive error.

func CleanupKeychainCredentials

func CleanupKeychainCredentials(homeDir string)

CleanupKeychainCredentials removes plaintext credential files that were extracted from the macOS Keychain during sandbox sync. Called on session teardown to avoid persisting secrets on the host filesystem.

func DefaultImage

func DefaultImage() string

DefaultImage returns the default sandbox image name.

func EnsureImage

func EnsureImage(ctx context.Context, image string) error

EnsureImage checks that image exists locally, pulling it if missing.

func GenerateName

func GenerateName(sessionID string, sessionTitle string) string

GenerateName builds a container name from a session ID and human-readable title. Format: agent-deck-{title}-{id8}. The 8-char ID suffix guarantees uniqueness; the title is just for human readability in docker ps output.

func IsDaemonRunning

func IsDaemonRunning(ctx context.Context) bool

IsDaemonRunning returns true if the docker daemon is responsive. A 5-second defensive timeout is applied so callers without a deadline cannot block indefinitely.

func IsDockerAvailable

func IsDockerAvailable() bool

IsDockerAvailable returns true if the docker CLI is installed and in PATH.

func IsManagedContainer

func IsManagedContainer(name string) bool

IsManagedContainer returns true if the name matches the agent-deck naming convention.

func ListManagedContainers

func ListManagedContainers(ctx context.Context) ([]string, error)

ListManagedContainers returns names of all containers with the managed-by=agent-deck label.

func RefreshAgentConfigs

func RefreshAgentConfigs(homeDir string, cHome string) (bindMounts []VolumeMount, homeMounts []VolumeMount)

RefreshAgentConfigs syncs all tool configs into shared sandbox directories. Called on every session start to pick up credential changes and new files. On container reuse (exists=true), the existing container keeps its bind mounts but gets refreshed sandbox directory contents via the shared host directory. cHome is the container's home directory (e.g. "/root" for root images). Returns bind mounts for tool config dirs and home-level seed file mounts.

func SandboxDir

func SandboxDir(homeDir string, hostRel string) string

SandboxDir returns the shared sandbox directory path for a tool's config.

func ShellJoinArgs

func ShellJoinArgs(args []string) string

ShellJoinArgs joins command arguments into a shell-safe string. Each argument is single-quoted to prevent shell interpretation of special characters (spaces, quotes, $, backticks, semicolons, etc.). Arguments that are simple (alphanumeric, hyphens, underscores, dots, slashes, equals, colons, commas) are left unquoted for readability.

func SyncAgentConfig

func SyncAgentConfig(homeDir string, mount AgentConfigMount) (string, error)

SyncAgentConfig syncs host tool config into a shared sandbox directory. Seed files use write-once semantics: they are written only if they don't already exist, preserving any state accumulated by the container. Top-level files from the host dir are always copied (overwriting previous copies).

Types

type AgentConfigMount

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

AgentConfigMount declares how a tool's config directory is synced into sandbox containers.

func AgentConfigMounts

func AgentConfigMounts() []AgentConfigMount

AgentConfigMounts returns a shallow clone of all tool config mount definitions. Callers receive their own slice and cannot mutate the package-level configuration.

func (AgentConfigMount) ContainerPath

func (m AgentConfigMount) ContainerPath(home string) string

ContainerPath returns the full container path for this mount. The home parameter is the container's home directory (e.g. containerHome).

type Container

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

Container manages a single Docker container lifecycle.

func FromName

func FromName(name string) *Container

FromName creates a container handle for an existing container by name. The returned handle supports lifecycle operations (Exists, IsRunning, Start, Stop, Remove, ExecPrefix) but not Create — use NewContainer for that.

func NewContainer

func NewContainer(name string, image string) *Container

NewContainer creates a container handle with the given name and image.

func (*Container) Create

func (c *Container) Create(ctx context.Context, cfg *ContainerConfig) (string, error)

Create creates the container from the given config without starting it. Returns the container ID on success. If the container already exists, it is treated as a no-op and the existing container ID is returned.

func (*Container) ExecPrefix

func (c *Container) ExecPrefix() []string

ExecPrefix returns the command prefix for running a command inside this container. Returns ["docker", "exec", "-it", name].

func (*Container) ExecPrefixWithEnv

func (c *Container) ExecPrefixWithEnv(env map[string]string) []string

ExecPrefixWithEnv returns the command prefix with -e flags for runtime env vars. Each token is a discrete argument suitable for exec.Command (no shell quoting). Use ShellJoinArgs to convert to a shell-safe string when embedding in bash -c. Keys are sorted for deterministic output.

func (*Container) Exists

func (c *Container) Exists(ctx context.Context) (bool, error)

Exists returns true if the container exists (running or stopped). A non-zero exit code from docker inspect indicates the container does not exist. Other errors (e.g. Docker daemon unreachable) are propagated.

func (*Container) IsRunning

func (c *Container) IsRunning(ctx context.Context) (bool, error)

IsRunning returns true if the container is currently running. Uses exit code as the primary signal rather than parsing error messages.

func (*Container) Name

func (c *Container) Name() string

Name returns the container name.

func (*Container) Remove

func (c *Container) Remove(ctx context.Context, force bool) error

Remove removes the container and its anonymous volumes. If force is true, a running container is killed first. If the container does not exist, this is a no-op.

func (*Container) Start

func (c *Container) Start(ctx context.Context) error

Start starts a stopped container. If the container is already running, this is a no-op.

func (*Container) Stop

func (c *Container) Stop(ctx context.Context) error

Stop gracefully stops a running container.

type ContainerConfig

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

ContainerConfig holds settings for container creation. All fields are unexported to enforce construction via NewContainerConfig and the options pattern (WithGitConfig, WithSSH, etc.), preventing partially initialized configs.

func NewContainerConfig

func NewContainerConfig(projectPath string, opts ...ContainerConfigOption) *ContainerConfig

NewContainerConfig creates a ContainerConfig for a sandboxed session. projectPath is the host directory to mount as /workspace (must be non-empty). Optional ContainerConfigOption functions customize mounts, limits, and environment.

type ContainerConfigOption

type ContainerConfigOption func(*ContainerConfig)

ContainerConfigOption customizes a ContainerConfig during NewContainerConfig.

func WithAgentConfigs

func WithAgentConfigs(bindMounts []VolumeMount, homeMounts []VolumeMount) ContainerConfigOption

WithAgentConfigs adds bind mounts from sandbox sync results.

func WithCPULimit

func WithCPULimit(limit string) ContainerConfigOption

WithCPULimit sets the CPU quota for the container (e.g. "2.0").

func WithContainerHome

func WithContainerHome(home string) ContainerConfigOption

WithContainerHome overrides the default container home directory (/root). Use this for non-root images where the home directory differs.

func WithEnvironment

func WithEnvironment(env map[string]string) ContainerConfigOption

WithEnvironment merges key=value environment variables into the container config. Used for both host-resolved variables (via collectDockerEnvVars) and static values.

func WithExtraVolumes

func WithExtraVolumes(volumes map[string]string) ContainerConfigOption

WithExtraVolumes adds user-configured bind mounts (host → container path). Both paths must be absolute. Host paths are resolved through EvalSymlinks to prevent symlink-based blocklist bypass (e.g. /home/user/link → /var/run/docker.sock). Host paths in blockedHostPaths and blockedHostPrefixes are rejected. Container paths in blockedContainerPaths and blockedContainerPrefixes are rejected to prevent overwriting critical paths.

func WithGitConfig

func WithGitConfig(path string) ContainerConfigOption

WithGitConfig mounts the host gitconfig file read-only inside the container.

func WithMemoryLimit

func WithMemoryLimit(limit string) ContainerConfigOption

WithMemoryLimit sets the memory cap for the container (e.g. "4g").

func WithSSH

func WithSSH(path string) ContainerConfigOption

WithSSH mounts the host ~/.ssh directory read-only inside the container.

func WithVolumeIgnores

func WithVolumeIgnores(dirs []string) ContainerConfigOption

WithVolumeIgnores converts directory names into anonymous volumes at /workspace/<dir>. This prevents large host directories (e.g. node_modules) from syncing into the container. Entries containing path separators or ".." are rejected to prevent path traversal.

func WithWorktree

func WithWorktree(repoRoot string, relativePath string) ContainerConfigOption

WithWorktree mounts the full repository root and adjusts workingDir to the worktree subdirectory. repoRoot is the absolute host path to the git repository root. relativePath is the worktree path relative to repoRoot.

type VolumeMount

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

VolumeMount represents a single bind mount.

Jump to

Keyboard shortcuts

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