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 ¶
- Variables
- func CheckAvailability(ctx context.Context) error
- func CleanupKeychainCredentials(homeDir string)
- func DefaultImage() string
- func EnsureImage(ctx context.Context, image string) error
- func GenerateName(sessionID string, sessionTitle string) string
- func IsDaemonRunning(ctx context.Context) bool
- func IsDockerAvailable() bool
- func IsManagedContainer(name string) bool
- func ListManagedContainers(ctx context.Context) ([]string, error)
- func RefreshAgentConfigs(homeDir string, cHome string) (bindMounts []VolumeMount, homeMounts []VolumeMount)
- func SandboxDir(homeDir string, hostRel string) string
- func ShellJoinArgs(args []string) string
- func SyncAgentConfig(homeDir string, mount AgentConfigMount) (string, error)
- type AgentConfigMount
- type Container
- func (c *Container) Create(ctx context.Context, cfg *ContainerConfig) (string, error)
- func (c *Container) ExecPrefix() []string
- func (c *Container) ExecPrefixWithEnv(env map[string]string) []string
- func (c *Container) Exists(ctx context.Context) (bool, error)
- func (c *Container) IsRunning(ctx context.Context) (bool, error)
- func (c *Container) Name() string
- func (c *Container) Remove(ctx context.Context, force bool) error
- func (c *Container) Start(ctx context.Context) error
- func (c *Container) Stop(ctx context.Context) error
- type ContainerConfig
- type ContainerConfigOption
- func WithAgentConfigs(bindMounts []VolumeMount, homeMounts []VolumeMount) ContainerConfigOption
- func WithCPULimit(limit string) ContainerConfigOption
- func WithContainerHome(home string) ContainerConfigOption
- func WithEnvironment(env map[string]string) ContainerConfigOption
- func WithExtraVolumes(volumes map[string]string) ContainerConfigOption
- func WithGitConfig(path string) ContainerConfigOption
- func WithMemoryLimit(limit string) ContainerConfigOption
- func WithSSH(path string) ContainerConfigOption
- func WithVolumeIgnores(dirs []string) ContainerConfigOption
- func WithWorktree(repoRoot string, relativePath string) ContainerConfigOption
- type VolumeMount
Constants ¶
This section is empty.
Variables ¶
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 ¶
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 EnsureImage ¶
EnsureImage checks that image exists locally, pulling it if missing.
func GenerateName ¶
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 ¶
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 ¶
IsManagedContainer returns true if the name matches the agent-deck naming convention.
func ListManagedContainers ¶
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 ¶
SandboxDir returns the shared sandbox directory path for a tool's config.
func ShellJoinArgs ¶
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 ¶
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 ¶
NewContainer creates a container handle with the given name and image.
func (*Container) Create ¶
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 ¶
ExecPrefix returns the command prefix for running a command inside this container. Returns ["docker", "exec", "-it", name].
func (*Container) ExecPrefixWithEnv ¶
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 ¶
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 ¶
IsRunning returns true if the container is currently running. Uses exit code as the primary signal rather than parsing error messages.
func (*Container) Remove ¶
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.
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.