docker

package
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Jun 15, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrNoTTY = errors.New("interactive TTY required on stdin and stdout")

Functions

func WithPreflightTimeout added in v0.0.4

func WithPreflightTimeout(parent context.Context) (context.Context, context.CancelFunc)

WithPreflightTimeout wraps parent with a preflightTimeout deadline; callers must defer the returned cancel.

Types

type BuildOptions

type BuildOptions struct {
	Image          string   // -t tag (required)
	DockerfilePath string   // -f path (required)
	ContextDir     string   // empty ⇒ Build auto-creates a temp dir
	NoCache        bool     // --no-cache
	BuildArgs      []string // forwarded as build arguments
	Quiet          bool     // suppress build progress output
}

BuildOptions is the caller-supplied input to Build. Path fields must be absolute.

type Docker added in v0.1.0

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

Docker holds the dependencies shared by Run, Build, CheckDaemon, and ImageExists. Construct with New; call Close when done.

func New added in v0.1.0

func New(opts ...Option) (*Docker, error)

New constructs a Docker with real defaults: an environment-built moby client, stdin+stdout TTY detection, and term.MakeRaw. Options apply before client construction so WithClient can suppress the real newClient() call (avoiding an orphaned transport when a test injects a fake).

func (*Docker) Build added in v0.1.0

func (d *Docker) Build(ctx context.Context, o BuildOptions, stdout io.Writer) error

Build builds the image described by o, writing progress output to stdout. CI/pipe-safe; never checks for a TTY. The struct's client is shared, not closed here.

func (*Docker) CheckDaemon added in v0.1.0

func (d *Docker) CheckDaemon(ctx context.Context) error

CheckDaemon pings the daemon, returning *ErrDaemonUnreachable on failure.

func (*Docker) Close added in v0.1.0

func (d *Docker) Close() error

Close releases the underlying Docker client connection.

func (*Docker) ImageExists added in v0.1.0

func (d *Docker) ImageExists(ctx context.Context, image string) (bool, error)

ImageExists reports whether the named image tag exists locally. (false, nil) only for a classified not-found; other errors return (false, err).

func (*Docker) Run added in v0.1.0

func (d *Docker) Run(ctx context.Context, s Spec) error

Run launches s interactively using the struct's injected apiClient, TTY predicate, raw-mode function, and I/O streams. Returns ErrNoTTY unless both stdin and stdout are TTYs, and *ExitError on non-zero container exit.

Lifecycle order (fixes AutoRemove + wait-before-start race, output truncation, and stdin goroutine leak — findings #1, #2, #3):

Create → Attach → raw mode → ContainerWait(next-exit) → ContainerStart →
  stream copies → drain stdout → close stdin handle → join stdin copy →
  map StatusCode → ExitError

Registering the wait before start guarantees the daemon delivers the exit status even when the container exits and is auto-removed within milliseconds.

Stdin-goroutine join: production path opens /dev/tty as a fresh O_NONBLOCK file description (never altering fd 0's shared flags — see newPollableStdin). Closing it unblocks the pending Read via the Go runtime poller. If the open or poller registration fails, the goroutine is leaked — this is the documented fallback, matching what the docker CLI does. Injected test readers implementing io.Closer (e.g. os.Pipe read-end) are treated identically to the pollable dup path and the goroutine is always joined.

d.resizeGoroutineHook, when non-nil, is called at the end of the resize goroutine body (before closing resizeDone). Tests inject a hook to verify the goroutine was joined before Run returned; nil in production.

type ErrDaemonUnreachable

type ErrDaemonUnreachable struct {
	Cause error
}

ErrDaemonUnreachable is returned by CheckDaemon when the daemon cannot be reached.

func (*ErrDaemonUnreachable) Error

func (e *ErrDaemonUnreachable) Error() string

func (*ErrDaemonUnreachable) Unwrap

func (e *ErrDaemonUnreachable) Unwrap() error

type ExitError

type ExitError struct {
	Code int
}

ExitError is returned by Run on non-zero container exit. Code is the daemon's status code (e.g. 137 for SIGKILL).

func (*ExitError) Error

func (e *ExitError) Error() string

type Mount

type Mount struct {
	Type            string
	Host, Container string
	ReadOnly        bool
}

Mount is a single docker mount entry. Type "" or "bind" → bind; "tmpfs" → tmpfs (Host ignored); "volume" → volume (Host is the volume name).

type Option added in v0.1.0

type Option func(*Docker)

Option is a functional option for New.

func WithClient added in v0.1.0

func WithClient(c apiClient) Option

WithClient injects a pre-built apiClient. Same-package _test.go only (apiClient is unexported).

func WithRawMode added in v0.1.0

func WithRawMode(fn func(int) (*term.State, error)) Option

WithRawMode overrides the terminal raw-mode function used by Run.

func WithStreams added in v0.1.0

func WithStreams(in io.Reader, out io.Writer) Option

WithStreams overrides the stdin reader and stdout writer used by Run for container I/O. Fd-based terminal operations (raw mode, GetSize, resize) always use the real os.Stdin; only the data copies are redirected.

func WithTTYCheck added in v0.1.0

func WithTTYCheck(fn func() bool) Option

WithTTYCheck overrides the TTY-detection predicate used by Run.

type Options

type Options struct {
	ProjectRoot   string // host path mounted at /workspace/<WorkspaceName>
	WorkspaceName string // e.g. "makeslop-ab12cd"
	BaseDir       string // ~/.makeslop
	// WorkspaceHost is the per-workspace cache directory on the host
	// (e.g. ~/.makeslop/workspaces/<WorkspaceName>). Caller computes this;
	// BuildSpec uses it directly for cache overlay mounts.
	WorkspaceHost string
	Image         string
	Command       string // shell to exec inside the container
	// MaskedFiles: absolute host paths under ProjectRoot to shadow with /dev/null.
	MaskedFiles []string
	// MaskedDirs: absolute host paths under ProjectRoot to replace with tmpfs.
	MaskedDirs []string

	// TmpDirSize is passed verbatim to --tmpfs /tmp:size=<TmpDirSize>; config.Load
	// owns the default, BuildSpec does not re-default.
	TmpDirSize string

	// Env holds "KEY=VALUE" pairs to inject; copied verbatim (caller sorts).
	Env []string

	// MountAgentCache gates the per-workspace agent-state cache overlays
	// (workspaceHost/.claude/, .codex/). The global ~/.makeslop equivalents are
	// always present regardless.
	MountAgentCache bool

	// MountContentCache gates the per-workspace content cache overlays
	// (workspaceHost/docs/, CLAUDE.md); false lets the project's own files show.
	MountContentCache bool

	// ProtectProjectConfig mounts <ProjectRoot>/.makeslop.yaml read-only over
	// itself inside the container, preventing the agent from rewriting the sandbox
	// policy. Only set when the file actually exists on the host (a missing bind
	// source would fail container create).
	ProtectProjectConfig bool

	// MaskGitHooks overlays <workspacePath>/.git/hooks with a tmpfs, preventing
	// the agent from planting hooks that execute on the host. Only set when
	// <ProjectRoot>/.git is a directory (worktrees/submodule gitfiles are skipped
	// — their hooks directory lives outside the workspace).
	MaskGitHooks bool
}

Options is the caller-supplied input to BuildSpec. Path fields must be absolute and EvalSymlinks-evaluated.

type Spec

type Spec struct {
	Image   string
	Command string
	Workdir string
	Env     []string // "KEY=VALUE" pairs; nil/empty → no -e flags
	Mounts  []Mount
	Tmpfs   []string
	CapDrop []string
	SecOpt  []string
}

Spec is the deterministic shape of a `docker run` invocation.

func BuildSpec

func BuildSpec(o Options) Spec

BuildSpec is pure: same Options → same Spec. Mask overlays must follow the directory bind they shadow so docker's argv-order evaluation makes them win; disabled groups are omitted, never reordered.

func (Spec) Args

func (s Spec) Args() []string

Args returns argv starting with "run". Mount source/target fields use RFC 4180 CSV quoting so paths containing ',' or '"' parse unambiguously.

func (Spec) ContainerConfig

func (s Spec) ContainerConfig() *container.Config

ContainerConfig returns the SDK container.Config for this Spec.

func (Spec) HostConfig

func (s Spec) HostConfig() *container.HostConfig

HostConfig returns the SDK container.HostConfig for this Spec.

func (Spec) ShellCommand

func (s Spec) ShellCommand() string

ShellCommand renders s as a multi-line backslash-continued `docker run` command.

Jump to

Keyboard shortcuts

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