workbenchdocker

package
v1.0.13 Latest Latest
Warning

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

Go to latest
Published: Aug 7, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package workbenchdocker is a thin typed wrapper around the Docker Engine SDK (github.com/docker/docker/client), used to create/start/stop/remove the containers and volumes that back a single workbench (a per-user sandbox running the `claude` CLI inside a persistent tmux session).

This package talks to whichever daemon URL it's constructed with — one client per call, pointed at whichever docker_hosts row a given workbench is assigned to (resolved by internal/service/v1/workbench/workbench.go's resolveClient), not a single startup-time config value. See docs/workbench/02_docker_topology.md for why a docker host is expected to be a dedicated second dockerd process, not the daemon Artel's own containers run on. It intentionally does not create the `workbench-net` network itself (assumed to pre-exist on the configured daemon) and does not expose any inbound port on the containers it creates.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

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

Client wraps the Docker SDK client with the narrow surface a workbench's container/volume lifecycle needs.

func New

func New(host string, tlsCfg TLSConfig) (*Client, error)

New constructs a Client talking to the Docker daemon at host (e.g. "unix:///var/run/docker-workbenches.sock", "tcp://host:2376" for a local/insecure daemon, or "tcp://host:2376" with a populated tlsCfg for a remote mTLS-secured daemon — see docs/workbench/02_docker_topology.md, "Option C"). API version negotiation is enabled so the client stays compatible with the daemon regardless of exactly which API version it speaks.

An empty tlsCfg reproduces exactly the pre-TLS behavior (plain client.WithHost, no custom HTTP client) — this must not regress the local unix-socket/dind path.

func (*Client) CapturePane

func (c *Client) CapturePane(ctx context.Context, containerID string) (string, error)

CapturePane returns the current visible contents of the workbench's tmux pane (tmuxSessionName), via `tmux capture-pane -p`. Used to observe the subscription_login TUI flow (login URL, OAuth errors, ...) without disturbing it — see docs/workbench/03_auth_and_login_flow.md, "Mechanism (confirmed)".

func (*Client) CreateContainer

func (c *Client) CreateContainer(ctx context.Context, opts CreateOpts) (string, error)

CreateContainer creates (but does not start) a workbench container: the hardcoded workbench image, attached to the dedicated workbench-net network (assumed to pre-exist on the configured daemon — see docs/workbench/02_docker_topology.md), with opts.VolumeName mounted at workspaceMountPath, hardcoded CPU/memory limits, no exposed ports, and labeled for operational visibility.

func (*Client) CreateVolume

func (c *Client) CreateVolume(ctx context.Context, name string) error

CreateVolume creates a named Docker volume, labeled for operational visibility.

func (*Client) RemoveContainer

func (c *Client) RemoveContainer(ctx context.Context, containerID string) error

RemoveContainer force-removes a workbench container. It does not remove the container's volume — call RemoveVolume separately.

func (*Client) RemoveVolume

func (c *Client) RemoveVolume(ctx context.Context, name string) error

RemoveVolume force-removes a named Docker volume.

func (*Client) SendKeys

func (c *Client) SendKeys(ctx context.Context, containerID string, keys string) error

SendKeys relays keys into the workbench's tmux pane (tmuxSessionName) via `tmux send-keys ... <keys> Enter`, followed by Enter as a separate key. keys is arbitrary, user-controlled input (an OAuth code or first-run keystrokes the user types/pastes) — it is passed as a single, literal argv element of ExecOptions.Cmd, never through a shell (`/bin/sh -c ...`), so there is no shell-metacharacter injection surface: the exec'd process is `tmux` itself, invoked directly, and keys is one opaque argument to it, not text that gets re-parsed as shell syntax. See docs/workbench/03_auth_and_login_flow.md, "Mechanism (confirmed)", step 4.

func (*Client) StartContainer

func (c *Client) StartContainer(ctx context.Context, containerID string, env map[string]string) error

StartContainer starts an already-created workbench container and injects env into it.

The Docker Engine API has no way to attach environment variables to a container at `docker start` time — env is otherwise only settable at `docker create` time, which is deliberately too early here (see CreateOpts). Once started, env is instead propagated into the running container's tmux session (tmuxSessionName) via a docker exec, so the value only ever lives in the tmux server's in-memory session state — never baked into the image, never written to the mounted volume. See docs/workbench/03_auth_and_login_flow.md for the full login-flow design this is feeding into (unconfirmed/spike-flagged there as of this writing); this is the mechanism this client offers to keep that property intact.

func (*Client) StopContainer

func (c *Client) StopContainer(ctx context.Context, containerID string) error

StopContainer gracefully stops a running workbench container, leaving it (and its volume) intact for a later restart.

type CreateOpts

type CreateOpts struct {
	// Name is the container name (e.g. "workbench-<vault_id>").
	Name string
	// VolumeName is the pre-created named volume to mount at workspaceMountPath.
	VolumeName string
}

CreateOpts configures a new workbench container. Deliberately excludes any secret/env value — per docs/workbench/01_data_model_and_lifecycle.md, a workbench container is created with no auth env vars at all; those are only decided and supplied later, at StartContainer time.

type TLSConfig

type TLSConfig struct {
	CaCert     string
	ClientCert string
	ClientKey  string
}

TLSConfig carries the decrypted, in-memory PEM-encoded TLS client credentials for connecting to a remote Docker daemon over TLS/mTLS — the docker_hosts.ca_cert_enc/client_cert_enc/ client_key_enc columns (migrations/062_docker_hosts_tls.sql), decrypted by dockerhosts.Repo.GetWithCreds. All three fields empty means "no TLS" — see New.

Jump to

Keyboard shortcuts

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