shared

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Feb 22, 2026 License: MIT Imports: 36 Imported by: 0

Documentation

Overview

Package shared provides domain logic and shared options for container commands. Container option types live here alongside domain orchestration, avoiding the need for a separate opts/ package to break import cycles.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddFlags added in v0.1.2

func AddFlags(flags *pflag.FlagSet, opts *ContainerOptions)

AddFlags adds common container flags to the given flag set. This is the single point for flag registration shared between run and create commands.

func InitContainerConfig

func InitContainerConfig(ctx context.Context, opts InitConfigOpts) error

InitContainerConfig handles one-time claude config initialization for new containers. Called after EnsureConfigVolumes when the config volume was freshly created.

Steps:

  1. If strategy=="copy": prepare host claude config, copy to volume
  2. If use_host_auth: prepare credentials, copy to volume

func InjectOnboardingFile

func InjectOnboardingFile(ctx context.Context, opts InjectOnboardingOpts) error

InjectOnboardingFile writes ~/.claude.json to a created (not started) container. Must be called after ContainerCreate and before ContainerStart. The file marks Claude Code onboarding as complete so the user is not prompted.

func InjectPostInitScript

func InjectPostInitScript(ctx context.Context, opts InjectPostInitOpts) error

InjectPostInitScript writes ~/.clawker/post-init.sh to a created (not started) container. Must be called after ContainerCreate and before ContainerStart. The entrypoint is responsible for running this script once on first start and creating a ~/.claude/post-initialized marker to prevent re-runs on restart.

func MarkMutuallyExclusive added in v0.1.2

func MarkMutuallyExclusive(cmd *cobra.Command)

MarkMutuallyExclusive marks agent and name flags as mutually exclusive on the command.

func MergeLabels added in v0.1.2

func MergeLabels(baseLabels, userLabels map[string]string) map[string]string

MergeLabels merges user-provided labels with base labels. Base labels take precedence (clawker labels should not be overwritten).

func NeedsSocketBridge added in v0.1.2

func NeedsSocketBridge(cfg *config.Project) bool

NeedsSocketBridge returns true if the project config enables GPG or SSH forwarding, which requires a socket bridge daemon.

func ParseLabelsToMap added in v0.1.2

func ParseLabelsToMap(labels []string) map[string]string

ParseLabelsToMap converts a slice of "key=value" strings to a map. This is useful for merging user labels with clawker labels.

func RebuildMissingDefaultImage

func RebuildMissingDefaultImage(ctx context.Context, opts RebuildMissingImageOpts) error

RebuildMissingDefaultImage prompts the user to rebuild a missing default image. In non-interactive mode, prints instructions and returns an error. In interactive mode, prompts for flavor selection and rebuilds with TUI progress.

func ResolveAgentEnv added in v0.2.0

func ResolveAgentEnv(agent config.AgentConfig, projectDir string) (map[string]string, []string, error)

ResolveAgentEnv merges env_file, from_env, and env into a single map. Precedence (lowest to highest): env_file < from_env < env. The projectDir is used to resolve relative paths in env_file entries. Returns the merged env map, any warnings (e.g. unset from_env vars), and an error.

func ResolveAgentName added in v0.1.2

func ResolveAgentName(agent string, generateRandom func() string) string

ResolveAgentName returns the agent name, generating one if not provided. This is a helper that commands can use for generating random names.

Types

type ContainerOptions added in v0.1.2

type ContainerOptions struct {
	// Naming
	Agent string // Agent name for clawker naming (clawker.<project>.<agent>)
	Name  string // Same as agent, for Docker CLI familiarity

	// Container configuration
	Env             []string // Environment variables
	EnvFile         []string // Read env vars from file(s)
	Volumes         []string // Bind mounts
	Publish         *PortOpts
	Workdir         string     // Working directory
	User            string     // User
	Entrypoint      string     // Override entrypoint
	TTY             bool       // Allocate TTY
	Stdin           bool       // Keep STDIN open
	Attach          *ListOpts  // Attach to STDIN, STDOUT, STDERR
	NetMode         NetworkOpt // Network connection (supports advanced syntax)
	Labels          []string   // Additional labels
	LabelsFile      []string   // Read labels from file(s)
	AutoRemove      bool       // Auto-remove on exit
	Domainname      string     // Container NIS domain name
	ContainerIDFile string     // Write container ID to file
	GroupAdd        []string   // Additional groups

	// Resource limits
	Memory            docker.MemBytes           // Memory limit (e.g., "512m", "2g")
	MemorySwap        docker.MemSwapBytes       // Total memory (memory + swap), -1 for unlimited
	MemoryReservation docker.MemBytes           // Memory soft limit
	ShmSize           docker.MemBytes           // Size of /dev/shm
	CPUs              docker.NanoCPUs           // Number of CPUs (e.g., "1.5", "0.5")
	CPUShares         int64                     // CPU shares (relative weight)
	CPUSetCPUs        string                    // CPUs to allow (0-3, 0,1)
	CPUSetMems        string                    // MEMs to allow (0-3, 0,1)
	CPUPeriod         int64                     // CFS period
	CPUQuota          int64                     // CFS quota
	CPURtPeriod       int64                     // Realtime period
	CPURtRuntime      int64                     // Realtime runtime
	BlkioWeight       uint16                    // Block IO weight (10-1000)
	BlkioWeightDevice *docker.WeightDeviceOpt   // Per-device block IO weight
	DeviceReadBps     *docker.ThrottleDeviceOpt // Read rate limit (bytes/sec)
	DeviceWriteBps    *docker.ThrottleDeviceOpt // Write rate limit (bytes/sec)
	DeviceReadIOps    *docker.ThrottleDeviceOpt // Read rate limit (IO/sec)
	DeviceWriteIOps   *docker.ThrottleDeviceOpt // Write rate limit (IO/sec)
	PidsLimit         int64                     // Process limit (-1 unlimited)
	OOMKillDisable    bool                      // Disable OOM Killer
	OOMScoreAdj       int                       // OOM preferences (-1000 to 1000)
	Swappiness        int64                     // Memory swappiness (0-100, -1 for default)
	CPUCount          int64                     // CPU count (Windows only)
	CPUPercent        int64                     // CPU percent (Windows only)
	IOMaxBandwidth    docker.MemBytes           // Max IO bandwidth (Windows only)
	IOMaxIOps         uint64                    // Max IOps (Windows only)

	// Networking
	Hostname     string   // Container hostname
	DNS          []string // Custom DNS servers
	DNSSearch    []string // Custom DNS search domains
	DNSOptions   []string // DNS options
	ExtraHosts   []string // Extra hosts (host:IP mapping)
	Expose       []string // Expose port(s) without publishing
	PublishAll   bool     // Publish all exposed ports
	MacAddress   string   // Container MAC address
	IPv4Address  string   // IPv4 address
	IPv6Address  string   // IPv6 address
	Links        []string // Add link to another container
	Aliases      []string // Network-scoped aliases
	LinkLocalIPs []string // Link-local addresses

	// Storage
	Tmpfs        []string         // Tmpfs mounts (path or path:options)
	ReadOnly     bool             // Mount root filesystem as read-only
	VolumesFrom  []string         // Mount volumes from another container
	VolumeDriver string           // Volume driver
	StorageOpt   []string         // Storage driver options
	Mounts       *docker.MountOpt // Advanced mount specifications

	// Devices
	Devices           *docker.DeviceOpt // Host devices to add
	GPUs              *docker.GpuOpts   // GPU devices
	DeviceCgroupRules []string          // Device cgroup rules

	// Security
	CapAdd          []string // Add Linux capabilities
	CapDrop         []string // Drop Linux capabilities
	Privileged      bool     // Give extended privileges to container
	SecurityOpt     []string // Security options (e.g., seccomp, apparmor, label)
	DisableFirewall bool     // Override project config: disable firewall

	// Health check
	HealthCmd           string        // Command to run to check health
	HealthInterval      time.Duration // Time between health checks
	HealthTimeout       time.Duration // Maximum time to allow health check to run
	HealthRetries       int           // Consecutive failures needed to report unhealthy
	HealthStartPeriod   time.Duration // Start period for the container to initialize
	HealthStartInterval time.Duration // Check interval during start period
	NoHealthcheck       bool          // Disable any container-specified HEALTHCHECK

	// Process and runtime
	Restart     string // Restart policy (no, always, on-failure[:max-retries], unless-stopped)
	StopSignal  string // Signal to stop the container (e.g., SIGTERM)
	StopTimeout int    // Timeout (in seconds) to stop a container
	Init        bool   // Run init inside the container

	// Namespace/Runtime
	PidMode      string // PID namespace
	IpcMode      string // IPC namespace
	UtsMode      string // UTS namespace
	UsernsMode   string // User namespace
	CgroupnsMode string // Cgroup namespace
	CgroupParent string // Parent cgroup
	Runtime      string // OCI runtime
	Isolation    string // Container isolation

	// Logging
	LogDriver string   // Logging driver
	LogOpts   []string // Log driver options

	// Resource limits (ulimits)
	Ulimits *docker.UlimitOpt // Ulimit options

	// Annotations and kernel parameters
	Annotations *MapOpts // OCI annotations
	Sysctls     *MapOpts // Kernel parameters

	// Workspace configuration
	Mode     string // "bind" or "snapshot" (empty = use config default)
	Worktree string // Git worktree: "" (none), "branch", or "branch:base"

	// Internal (set after parsing positional args)
	Image   string
	Command []string
}

ContainerOptions holds common options for container run and create commands. Commands can embed this struct and add command-specific options.

func NewContainerOptions added in v0.1.2

func NewContainerOptions() *ContainerOptions

NewContainerOptions creates a new ContainerOptions with initialized fields.

func (*ContainerOptions) BuildConfigs added in v0.1.2

func (opts *ContainerOptions) BuildConfigs(flags *pflag.FlagSet, mounts []mount.Mount, projectCfg *config.Project) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error)

BuildConfigs builds Docker container, host, and network configs from the options. This consolidates the duplicated buildConfigs logic from run.go and create.go. The flags parameter is used to detect whether certain flags were explicitly set (e.g., --entrypoint="" to reset entrypoint, --stop-timeout, --init).

func (*ContainerOptions) GetAgentName added in v0.1.2

func (opts *ContainerOptions) GetAgentName() string

GetAgentName returns the agent name from either --agent or --name flag.

func (*ContainerOptions) ValidateFlags added in v0.1.2

func (opts *ContainerOptions) ValidateFlags() error

ValidateFlags performs cross-field validation on the options.

type CopyFromContainerFn added in v0.2.0

type CopyFromContainerFn func(ctx context.Context, containerID, srcPath string) (io.ReadCloser, error)

CopyFromContainerFn is the signature for reading a tar archive from a container. Returns a ReadCloser for the tar stream; caller must close it.

func NewCopyFromContainerFn added in v0.2.0

func NewCopyFromContainerFn(client *docker.Client) CopyFromContainerFn

NewCopyFromContainerFn creates a CopyFromContainerFn that delegates to the docker client.

type CopyToContainerFn

type CopyToContainerFn func(ctx context.Context, containerID, destPath string, content io.Reader) error

CopyToContainerFn is the signature for copying a tar archive to a container. Wraps the lower-level Docker CopyToContainer API into a simpler interface.

func NewCopyToContainerFn

func NewCopyToContainerFn(client *docker.Client) CopyToContainerFn

TODO: This is implemented wrong. constructors need to be added to accept factory *cmdutil.Factory, we don't pass indivdual deps) NewCopyToContainerFn creates a CopyToContainerFn that delegates to the docker client. This is the standard production wiring — use directly instead of writing an inline closure.

type CopyToVolumeFn

type CopyToVolumeFn func(ctx context.Context, volumeName, srcDir, destPath string, ignorePatterns []string) error

CopyToVolumeFn is the signature for copying a directory to a Docker volume. Matches *docker.Client.CopyToVolume.

type CreateContainerConfig added in v0.1.2

type CreateContainerConfig struct {
	Client      *docker.Client
	Cfg         config.Config
	Config      *config.Project
	ProjectName string
	Options     *ContainerOptions
	Flags       *pflag.FlagSet
	Version     string
	GitManager  func() (*git.GitManager, error)
	HostProxy   func() hostproxy.HostProxyService
	Logger      iostreams.Logger
	Is256Color  bool
	IsTrueColor bool
}

CreateContainerConfig holds all inputs for CreateContainer.

type CreateContainerEvent added in v0.1.2

type CreateContainerEvent struct {
	Step    string      // "workspace", "config", "environment", "container"
	Status  StepStatus  // Step lifecycle state
	Message string      // User-facing text
	Type    MessageType // Info or Warning
}

CreateContainerEvent is sent on the events channel during CreateContainer. Callers use these to drive spinners, collect warnings, etc.

type CreateContainerResult added in v0.1.2

type CreateContainerResult struct {
	ContainerID      string
	AgentName        string
	ContainerName    string
	WorkDir          string
	HostProxyRunning bool
}

CreateContainerResult holds the outputs of CreateContainer.

func CreateContainer added in v0.1.2

func CreateContainer(ctx context.Context, cfg *CreateContainerConfig, events chan<- CreateContainerEvent) (_ *CreateContainerResult, retErr error)

CreateContainer is the single entry point for container creation, shared by run and create commands. It performs workspace setup, config initialization, environment resolution, Docker container creation, and post-create injection.

Progress is communicated via the events channel (nil for silent mode). Developer diagnostics go to zerolog. Callers own all terminal output.

Uses named return retErr so deferred volume cleanup can inspect the error.

type InitConfigOpts

type InitConfigOpts struct {
	// ProjectName is the project name for volume naming.
	ProjectName string
	// AgentName is the agent name for volume naming.
	AgentName string
	// ContainerWorkDir is the workspace directory inside the container (e.g. "/workspace").
	// Used to rewrite projectPath values in installed_plugins.json.
	ContainerWorkDir string
	// ClaudeCode is the claude code configuration. Nil uses defaults (copy strategy + host auth).
	ClaudeCode *config.ClaudeCodeConfig
	// CopyToVolume copies a directory to a Docker volume.
	// In production, wire this to (*docker.Client).CopyToVolume.
	CopyToVolume CopyToVolumeFn
}

InitConfigOpts holds options for container init orchestration.

type InjectOnboardingOpts

type InjectOnboardingOpts struct {
	// ContainerID is the Docker container ID to inject the file into.
	ContainerID string
	// Cfg provides config constants (e.g. domain, label prefix) for containerfs.
	Cfg config.Config
	// CopyToContainer copies a tar archive to the container at the given destination path.
	// In production, wire this to a function that calls (*docker.Client).CopyToContainer.
	CopyToContainer CopyToContainerFn
}

InjectOnboardingOpts holds options for onboarding file injection.

type InjectPostInitOpts

type InjectPostInitOpts struct {
	// ContainerID is the Docker container ID to inject the script into.
	ContainerID string
	// Script is the user's post_init content from clawker.yaml.
	Script string
	// Cfg provides config constants for containerfs.
	Cfg config.Config
	// CopyToContainer copies a tar archive to the container at the given destination path.
	// In production, wire this to a function that calls (*docker.Client).CopyToContainer.
	CopyToContainer CopyToContainerFn
}

InjectPostInitOpts holds options for post-init script injection.

type ListOpts added in v0.1.2

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

ListOpts holds a list of values for repeatable string flags (like -e VAR1 -e VAR2). Implements pflag.Value interface.

func NewListOpts added in v0.1.2

func NewListOpts(validator func(string) (string, error)) *ListOpts

NewListOpts creates a new ListOpts with optional validator. If validator is nil, values are accepted as-is.

func NewListOptsRef added in v0.1.2

func NewListOptsRef(values *[]string, validator func(string) (string, error)) *ListOpts

NewListOptsRef creates a new ListOpts that stores values in the provided slice. This is useful when you want to reuse an existing slice.

func (*ListOpts) GetAll added in v0.1.2

func (o *ListOpts) GetAll() []string

GetAll returns all values in the list.

func (*ListOpts) Len added in v0.1.2

func (o *ListOpts) Len() int

Len returns the number of values in the list.

func (*ListOpts) Set added in v0.1.2

func (o *ListOpts) Set(value string) error

Set adds a value to the list after validation.

func (*ListOpts) String added in v0.1.2

func (o *ListOpts) String() string

String returns a comma-separated string of all values.

func (*ListOpts) Type added in v0.1.2

func (o *ListOpts) Type() string

Type returns the type string for pflag.

type MapOpts added in v0.1.2

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

MapOpts holds key=value pairs for flags like --label or --env. Implements pflag.Value interface.

func NewMapOpts added in v0.1.2

func NewMapOpts(validator func(key, value string) error) *MapOpts

NewMapOpts creates a new MapOpts with optional validator.

func (*MapOpts) Get added in v0.1.2

func (o *MapOpts) Get(key string) (string, bool)

Get returns the value for a key.

func (*MapOpts) GetAll added in v0.1.2

func (o *MapOpts) GetAll() map[string]string

GetAll returns all key-value pairs as a map.

func (*MapOpts) Len added in v0.1.2

func (o *MapOpts) Len() int

Len returns the number of key-value pairs.

func (*MapOpts) Set added in v0.1.2

func (o *MapOpts) Set(value string) error

Set parses a key=value string and adds it to the map.

func (*MapOpts) String added in v0.1.2

func (o *MapOpts) String() string

String returns a string representation of the map.

func (*MapOpts) Type added in v0.1.2

func (o *MapOpts) Type() string

Type returns the type string for pflag.

type MessageType added in v0.1.2

type MessageType int

MessageType classifies the severity of a step message.

const (
	MessageInfo    MessageType = iota // Informational substep update
	MessageWarning                    // Non-fatal issue
)

type NetworkAttachmentOpts added in v0.1.2

type NetworkAttachmentOpts struct {
	Target       string
	Aliases      []string
	DriverOpts   map[string]string
	Links        []string
	IPv4Address  netip.Addr
	IPv6Address  netip.Addr
	MacAddress   string
	LinkLocalIPs []netip.Addr
	GwPriority   int
}

NetworkAttachmentOpts holds options for a single network attachment. This mirrors Docker CLI's opts.NetworkAttachmentOpts.

type NetworkOpt added in v0.1.2

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

NetworkOpt is a pflag.Value that supports advanced --network syntax. Simple usage: --network bridge Advanced usage: --network name=mynet,alias=web,driver-opt=foo=bar,ip=172.20.0.5,ip6=::1,mac-address=...,link-local-ip=...,gw-priority=100 Multiple networks: --network mynet1 --network mynet2

func (*NetworkOpt) NetworkMode added in v0.1.2

func (n *NetworkOpt) NetworkMode() string

NetworkMode returns the network mode string for use with HostConfig.NetworkMode. For the first network, this returns the target name. For empty networks, returns "".

func (*NetworkOpt) Set added in v0.1.2

func (n *NetworkOpt) Set(value string) error

Set parses a --network value. It supports both simple mode names (e.g., "bridge", "host", "mynet") and advanced key=value syntax (e.g., "name=mynet,alias=web,driver-opt=opt1=val1").

func (*NetworkOpt) String added in v0.1.2

func (n *NetworkOpt) String() string

String returns a string representation of the network option.

func (*NetworkOpt) Type added in v0.1.2

func (n *NetworkOpt) Type() string

Type returns the type name for pflag.

func (*NetworkOpt) Value added in v0.1.2

func (n *NetworkOpt) Value() []NetworkAttachmentOpts

Value returns the parsed network attachment options.

type PortOpts added in v0.1.2

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

PortOpts holds port mappings for -p/--publish flags. Implements pflag.Value interface.

func NewPortOpts added in v0.1.2

func NewPortOpts() *PortOpts

NewPortOpts creates a new PortOpts.

func (*PortOpts) GetAsStrings added in v0.1.2

func (o *PortOpts) GetAsStrings() []string

GetAsStrings returns the port mappings as a slice of strings in "hostPort:containerPort" format. This is primarily useful for testing and comparison.

func (*PortOpts) GetExposedPorts added in v0.1.2

func (o *PortOpts) GetExposedPorts() network.PortSet

GetExposedPorts returns the exposed ports set for container config.

func (*PortOpts) GetPortBindings added in v0.1.2

func (o *PortOpts) GetPortBindings() network.PortMap

GetPortBindings returns the port bindings for host config.

func (*PortOpts) Len added in v0.1.2

func (o *PortOpts) Len() int

Len returns the number of port bindings.

func (*PortOpts) Set added in v0.1.2

func (o *PortOpts) Set(value string) error

Set parses a port mapping spec (e.g., "8080:80", "127.0.0.1:8080:80/tcp") and adds it to the port mappings.

func (*PortOpts) String added in v0.1.2

func (o *PortOpts) String() string

String returns a string representation of the port mappings.

func (*PortOpts) Type added in v0.1.2

func (o *PortOpts) Type() string

Type returns the type string for pflag.

type RebuildMissingImageOpts

type RebuildMissingImageOpts struct {
	ImageRef    string
	IOStreams   *iostreams.IOStreams
	TUI         *tui.TUI
	Prompter    func() *prompter.Prompter
	BuildImage  docker.BuildDefaultImageFn
	CommandVerb string // "run" or "create" for error messages
}

RebuildMissingImageOpts holds options for the rebuild prompt flow.

type StepStatus added in v0.1.2

type StepStatus int

StepStatus represents the lifecycle state of a creation step.

const (
	StepRunning  StepStatus = iota // Step in progress
	StepComplete                   // Step finished successfully
	StepCached                     // Step skipped (already done)
)

Jump to

Keyboard shortcuts

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