Documentation
¶
Index ¶
- Variables
- func WithPreflightTimeout(parent context.Context) (context.Context, context.CancelFunc)
- type BuildOptions
- type Docker
- func (d *Docker) Build(ctx context.Context, o BuildOptions, stdout io.Writer) error
- func (d *Docker) CheckDaemon(ctx context.Context) error
- func (d *Docker) Close() error
- func (d *Docker) ImageExists(ctx context.Context, image string) (bool, error)
- func (d *Docker) Run(ctx context.Context, s Spec) error
- type ErrDaemonUnreachable
- type ExitError
- type Mount
- type Option
- type Options
- type Spec
Constants ¶
This section is empty.
Variables ¶
var ErrNoTTY = errors.New("interactive TTY required on stdin and stdout")
Functions ¶
func WithPreflightTimeout ¶ added in v0.0.4
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
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
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
CheckDaemon pings the daemon, returning *ErrDaemonUnreachable on failure.
func (*Docker) ImageExists ¶ added in v0.1.0
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
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).
type Mount ¶
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
WithRawMode overrides the terminal raw-mode function used by Run.
func WithStreams ¶ added in v0.1.0
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
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 ¶
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 ¶
Args returns argv starting with "run". Mount source/target fields use RFC 4180 CSV quoting so paths containing ',' or '"' parse unambiguously.
func (Spec) ContainerConfig ¶
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 ¶
ShellCommand renders s as a multi-line backslash-continued `docker run` command.