devcontainer

package
v0.19.0 Latest Latest
Warning

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

Go to latest
Published: May 27, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Overview

Package devcontainer manages devcontainer lifecycle: parsing devcontainer.json, building images, creating/starting/stopping containers, and executing commands.

Index

Constants

View Source
const (
	LabelManaged    = "dev.human.managed"     // "true"
	LabelProject    = "dev.human.project"     // absolute path to project dir
	LabelConfigHash = "dev.human.config-hash" // SHA256 of devcontainer.json
	LabelName       = "dev.human.name"        // human-friendly name
)

Docker labels for identifying human-managed devcontainers.

Variables

View Source
var StdCopy = stdcopy.StdCopy

StdCopy re-exports stdcopy.StdCopy so callers within the devcontainer package can demux exec output without importing the Docker SDK directly.

Functions

func ConfigHash

func ConfigHash(data []byte) string

ConfigHash returns a hex-encoded SHA256 hash of devcontainer.json content.

func ContainerName

func ContainerName(projectDir string) string

ContainerName returns the Docker container name for a devcontainer. Format: human-dc-<project>

func DeleteMeta

func DeleteMeta(name string) error

DeleteMeta removes the devcontainer metadata file from disk.

func DevcontainersDir

func DevcontainersDir() string

DevcontainersDir returns the directory where devcontainer metadata is stored.

func FindConfig

func FindConfig(projectDir string) (string, error)

FindConfig locates the devcontainer.json file for a project directory. Search order: .devcontainer/devcontainer.json, then .devcontainer.json.

func ImageName

func ImageName(projectDir, configHash string) string

ImageName returns the Docker image tag for a devcontainer build. Format: human-dc-<project>:<hash12>

func InstallFeatures

func InstallFeatures(ctx context.Context, docker DockerClient, puller FeaturePuller,
	containerID string, features map[string]interface{}, remoteUser string,
	logger zerolog.Logger, out io.Writer) error

InstallFeatures downloads and installs devcontainer features into a running container using exec. Each feature's install.sh is copied in via base64 encoding, then executed with the appropriate option environment variables.

func ManagedLabels

func ManagedLabels(projectDir, name, configHash string) map[string]string

ManagedLabels returns the standard set of labels for a human-managed container.

func MetaPath

func MetaPath(name string) string

MetaPath returns the file path for a devcontainer's metadata JSON.

func ParseRunArgs

func ParseRunArgs(args []string, opts *ContainerCreateOptions, logger zerolog.Logger)

ParseRunArgs translates devcontainer.json runArgs (Docker CLI flags) into ContainerCreateOptions fields. Unknown flags are logged as warnings.

func RunHook

func RunHook(ctx context.Context, docker DockerClient, containerID, user string, cmd interface{}, logger zerolog.Logger) error

RunHook executes a lifecycle command inside a container. The cmd parameter follows the devcontainer.json spec:

  • string: run via /bin/sh -c "<string>"
  • []interface{}: run as a direct command (each element is a string arg)
  • map[string]interface{}: run each value in parallel (keys are labels)

Returns nil if cmd is nil (hook not defined).

func RunLifecycleHooks

func RunLifecycleHooks(ctx context.Context, docker DockerClient, containerID, user string, cfg *DevcontainerConfig, logger zerolog.Logger, out io.Writer) error

RunLifecycleHooks executes the devcontainer lifecycle hooks in order inside a container. Sequence: onCreateCommand -> updateContentCommand -> postCreateCommand -> postStartCommand

func SanitizeName

func SanitizeName(name string) string

SanitizeName converts a project directory basename into a Docker-safe name. Lowercased, non-alphanumeric chars replaced with hyphens, trimmed.

func StripJSONC

func StripJSONC(data []byte) []byte

StripJSONC removes // line comments and /* */ block comments from JSONC input, preserving content inside JSON string literals.

func WriteMeta

func WriteMeta(m Meta) error

WriteMeta persists devcontainer metadata to disk.

Types

type BuildConfig

type BuildConfig struct {
	Dockerfile string            `json:"dockerfile,omitempty"`
	Context    string            `json:"context,omitempty"`
	Args       map[string]string `json:"args,omitempty"`
	Target     string            `json:"target,omitempty"`
	CacheFrom  []string          `json:"cacheFrom,omitempty"`
}

BuildConfig holds Dockerfile build configuration.

type ContainerConfigInfo

type ContainerConfigInfo struct {
	Env    []string
	Labels map[string]string
}

ContainerConfigInfo holds container configuration from inspection.

type ContainerCreateOptions

type ContainerCreateOptions struct {
	Name        string
	Image       string
	Cmd         []string
	Env         []string // KEY=VALUE pairs
	Labels      map[string]string
	WorkingDir  string
	User        string
	ExtraHosts  []string // "host:ip" entries for /etc/hosts
	Binds       []string // "src:dst[:opts]" bind mounts
	CapAdd      []string // added capabilities
	SecurityOpt []string // security options
	Privileged  bool
	NetworkMode string
	ShmSize     int64
}

ContainerCreateOptions bundles all parameters for creating a container. The implementation maps these to separate Docker SDK parameters.

type ContainerInspectResponse

type ContainerInspectResponse struct {
	ID     string
	Name   string
	State  ContainerState
	Image  string
	Config ContainerConfigInfo
}

ContainerInspectResponse holds container inspection results.

type ContainerListOptions

type ContainerListOptions struct {
	All          bool              // include stopped containers
	LabelFilters map[string]string // label key=value pairs
	NameFilter   string            // filter by container name (Docker regex match)
}

ContainerListOptions filters container listing.

type ContainerRemoveOptions

type ContainerRemoveOptions struct {
	Force         bool
	RemoveVolumes bool
}

ContainerRemoveOptions configures container removal.

type ContainerState

type ContainerState struct {
	Status   string // "running", "exited", "created", etc.
	Running  bool
	ExitCode int
}

ContainerState represents the container's runtime state.

type ContainerSummary

type ContainerSummary struct {
	ID     string
	Names  []string
	Image  string
	State  string // "running", "exited", etc.
	Labels map[string]string
}

ContainerSummary holds basic container metadata from listing.

type DevcontainerConfig

type DevcontainerConfig struct {
	Name                 string                 `json:"name,omitempty"`
	Image                string                 `json:"image,omitempty"`
	Build                *BuildConfig           `json:"build,omitempty"`
	DockerFile           string                 `json:"dockerFile,omitempty"`
	Features             map[string]interface{} `json:"features,omitempty"`
	Mounts               []interface{}          `json:"mounts,omitempty"`
	RunArgs              []string               `json:"runArgs,omitempty"`
	ForwardPorts         []interface{}          `json:"forwardPorts,omitempty"`
	RemoteEnv            map[string]string      `json:"remoteEnv,omitempty"`
	ContainerEnv         map[string]string      `json:"containerEnv,omitempty"`
	RemoteUser           string                 `json:"remoteUser,omitempty"`
	ContainerUser        string                 `json:"containerUser,omitempty"`
	WorkspaceFolder      string                 `json:"workspaceFolder,omitempty"`
	CapAdd               []string               `json:"capAdd,omitempty"`
	SecurityOpt          []string               `json:"securityOpt,omitempty"`
	Privileged           bool                   `json:"privileged,omitempty"`
	OverrideCommand      *bool                  `json:"overrideCommand,omitempty"`
	InitializeCommand    interface{}            `json:"initializeCommand,omitempty"`
	OnCreateCommand      interface{}            `json:"onCreateCommand,omitempty"`
	UpdateContentCommand interface{}            `json:"updateContentCommand,omitempty"`
	PostCreateCommand    interface{}            `json:"postCreateCommand,omitempty"`
	PostStartCommand     interface{}            `json:"postStartCommand,omitempty"`
	PostAttachCommand    interface{}            `json:"postAttachCommand,omitempty"`
}

DevcontainerConfig represents a parsed devcontainer.json. Supports the subset of the spec needed for image-based and Dockerfile-based configs.

func ParseConfig

func ParseConfig(data []byte) (*DevcontainerConfig, error)

ParseConfig parses a devcontainer.json file, handling JSONC (comments).

func ReadConfig

func ReadConfig(projectDir string) (*DevcontainerConfig, error)

ReadConfig finds and parses the devcontainer.json for a project directory.

func ResolveVariables

func ResolveVariables(cfg *DevcontainerConfig, projectDir string) *DevcontainerConfig

ResolveVariables replaces devcontainer.json variable placeholders in string fields. Supported: ${localEnv:VAR}, ${localWorkspaceFolder}, ${localWorkspaceFolderBasename}.

type DockerClient

type DockerClient interface {
	// Image operations
	ImageBuild(ctx context.Context, buildContext io.Reader, opts ImageBuildOptions) (io.ReadCloser, error)
	ImagePull(ctx context.Context, ref string, opts ImagePullOptions) (io.ReadCloser, error)
	ImageInspect(ctx context.Context, imageRef string) (ImageInspectResponse, error)
	ImageList(ctx context.Context, opts ImageListOptions) ([]ImageSummary, error)

	// Container lifecycle
	ContainerCreate(ctx context.Context, opts ContainerCreateOptions) (string, error)
	ContainerStart(ctx context.Context, containerID string) error
	ContainerStop(ctx context.Context, containerID string, timeout *int) error
	ContainerRemove(ctx context.Context, containerID string, opts ContainerRemoveOptions) error
	ContainerInspect(ctx context.Context, containerID string) (ContainerInspectResponse, error)
	ContainerList(ctx context.Context, opts ContainerListOptions) ([]ContainerSummary, error)
	ContainerLogs(ctx context.Context, containerID string, opts LogsOptions) (io.ReadCloser, error)
	ContainerCommit(ctx context.Context, containerID string, ref string) (string, error)

	// File transfer
	CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader) error

	// Exec for lifecycle hooks and user commands.
	ExecCreate(ctx context.Context, containerID string, cmd []string, opts ExecOptions) (string, error)
	ExecAttach(ctx context.Context, execID string) (ExecAttachResponse, error)
	ExecInspect(ctx context.Context, execID string) (ExecInspectResponse, error)

	Close() error
}

DockerClient abstracts Docker Engine operations for devcontainer management. The interface is intentionally simplified compared to the raw Docker SDK; the implementation in docker_engine.go handles the SDK-specific details.

func NewDockerClient

func NewDockerClient() (DockerClient, error)

NewDockerClient creates a DockerClient backed by the Docker Engine API.

type ExecAttachResponse

type ExecAttachResponse struct {
	Reader io.Reader
	Conn   io.Closer
}

ExecAttachResponse wraps the exec attachment, providing access to stdout/stderr.

func (ExecAttachResponse) Close

func (r ExecAttachResponse) Close() error

Close releases the underlying connection.

type ExecInspectResponse

type ExecInspectResponse struct {
	ExitCode int
	Running  bool
}

ExecInspectResponse holds exec process inspection results.

type ExecOptions

type ExecOptions struct {
	User         string
	WorkingDir   string
	Env          []string // KEY=VALUE pairs
	AttachStdout bool
	AttachStderr bool
	AttachStdin  bool
	Tty          bool
}

ExecOptions configures command execution inside a container.

type FeatureMeta

type FeatureMeta struct {
	ID            string                   `json:"id"`
	Version       string                   `json:"version"`
	Name          string                   `json:"name"`
	Options       map[string]FeatureOption `json:"options"`
	InstallsAfter []string                 `json:"installsAfter"`
	ContainerEnv  map[string]string        `json:"containerEnv"`
}

FeatureMeta is the parsed devcontainer-feature.json from a feature tarball.

type FeatureOption

type FeatureOption struct {
	Type    string      `json:"type"`
	Default interface{} `json:"default"`
}

FeatureOption describes a single feature option.

type FeaturePuller

type FeaturePuller interface {
	Pull(ctx context.Context, ref string) (installSh []byte, meta *FeatureMeta, err error)
}

FeaturePuller abstracts OCI feature download for testability.

type HumanConfig

type HumanConfig struct {
	ConfigDir string `yaml:"configdir"`
}

HumanConfig holds devcontainer settings from .humanconfig.

func LoadHumanConfig

func LoadHumanConfig(dir string) (*HumanConfig, error)

LoadHumanConfig reads the devcontainer section from .humanconfig.

type ImageBuildOptions

type ImageBuildOptions struct {
	Dockerfile string
	Tags       []string
	BuildArgs  map[string]*string
	Target     string
	CacheFrom  []string
	Remove     bool // remove intermediate containers
}

ImageBuildOptions configures an image build.

type ImageBuilder

type ImageBuilder struct {
	Docker DockerClient
	Logger zerolog.Logger
}

ImageBuilder handles building or pulling devcontainer images.

func (*ImageBuilder) EnsureImage

func (b *ImageBuilder) EnsureImage(ctx context.Context, cfg *DevcontainerConfig, projectDir, configHash string, rebuild bool, out io.Writer) (string, string, error)

EnsureImage ensures a devcontainer image exists. If not cached (or rebuild requested), it builds/pulls the image per the devcontainer config. Returns the image ID.

type ImageInspectResponse

type ImageInspectResponse struct {
	ID   string
	Tags []string
}

ImageInspectResponse holds image inspection results.

type ImageListOptions

type ImageListOptions struct {
	LabelFilters map[string]string // label key=value pairs
}

ImageListOptions filters image listing.

type ImagePullOptions

type ImagePullOptions struct {
	RegistryAuth string // base64-encoded auth for private registries
}

ImagePullOptions configures an image pull.

type ImageSummary

type ImageSummary struct {
	ID   string
	Tags []string
}

ImageSummary holds basic image metadata.

type LogsOptions

type LogsOptions struct {
	Follow     bool
	Tail       string // number of lines, e.g. "100"
	ShowStdout bool
	ShowStderr bool
}

LogsOptions configures container log retrieval.

type Manager

type Manager struct {
	Docker DockerClient
	Logger zerolog.Logger
}

Manager orchestrates devcontainer lifecycle operations.

func (*Manager) Down

func (m *Manager) Down(ctx context.Context, name string, removeVolumes bool) error

Down stops and removes a devcontainer.

func (*Manager) Exec

func (m *Manager) Exec(ctx context.Context, containerID string, cmd []string, user string, stdin io.Reader, stdout, stderr io.Writer) (int, error)

Exec runs a command inside a running devcontainer.

func (*Manager) List

func (m *Manager) List(ctx context.Context) ([]Meta, error)

List returns metadata for all managed devcontainers, refreshing status from Docker.

func (*Manager) Status

func (m *Manager) Status(ctx context.Context, name string) (*Meta, error)

Status returns the current status of a devcontainer by inspecting Docker.

func (*Manager) Stop

func (m *Manager) Stop(ctx context.Context, name string) error

Stop stops a running devcontainer.

func (*Manager) Up

func (m *Manager) Up(ctx context.Context, opts UpOptions) (*Meta, error)

Up creates and starts a devcontainer. If the container already exists and is running, it prints a message and returns. If stopped with the same config, it restarts it. If the config changed, it removes the old container first.

type Meta

type Meta struct {
	Name          string    `json:"name"`
	ProjectDir    string    `json:"project_dir"`
	ContainerID   string    `json:"container_id"`
	ContainerName string    `json:"container_name"`
	ImageID       string    `json:"image_id"`
	ImageName     string    `json:"image_name"`
	Status        Status    `json:"status"`
	CreatedAt     time.Time `json:"created_at"`
	StartedAt     time.Time `json:"started_at,omitempty"`
	StoppedAt     time.Time `json:"stopped_at,omitempty"`
	WorkspaceDir  string    `json:"workspace_dir"`
	RemoteUser    string    `json:"remote_user"`
	DaemonAddr    string    `json:"daemon_addr,omitempty"`
	ConfigHash    string    `json:"config_hash"`
}

Meta holds persisted metadata for a managed devcontainer.

func ListMetas

func ListMetas() ([]Meta, error)

ListMetas returns metadata for all managed devcontainers.

func ReadMeta

func ReadMeta(name string) (Meta, error)

ReadMeta loads devcontainer metadata from disk.

type OCIFeaturePuller

type OCIFeaturePuller struct{}

OCIFeaturePuller downloads devcontainer features from OCI registries.

func (*OCIFeaturePuller) Pull

func (p *OCIFeaturePuller) Pull(_ context.Context, featureRef string) ([]byte, *FeatureMeta, error)

Pull downloads a devcontainer feature OCI artifact and returns the raw tarball bytes and parsed metadata.

type Status

type Status string

Status represents the lifecycle state of a managed devcontainer.

const (
	StatusRunning  Status = "running"
	StatusStopped  Status = "stopped"
	StatusCreating Status = "creating"
	StatusFailed   Status = "failed"
)

type UpOptions

type UpOptions struct {
	ProjectDir    string
	Rebuild       bool
	DaemonInfo    *daemon.DaemonInfo // nil = no daemon injection
	Out           io.Writer
	ContainerName string // override container name (default: derived from project dir)
	SourceDir     string // override mount source (default: same as ProjectDir)
}

UpOptions configures the devcontainer up operation.

Jump to

Keyboard shortcuts

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