engine

package
v0.0.0 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package engine names the runtimes a cell can run on, records which guest OS each one supports, and defines the verbs every runtime implements.

cmd/ picks a Name with Resolve. The verbs are the target interface for every engine: an implementation lives in a subpackage, adds itself with Register from an init func, and cmd/ looks it up with For and calls Init, Build or Run. Docker (internal/engine/docker), tart (internal/engine/tart) and winkit (internal/engine/winkit) are registered.

Example

Example demonstrates looking up a registered engine by name. Docker, tart, and winkit register themselves via init(); call For to get the implementation.

package main

import (
	"fmt"

	"github.com/devcell-sh/devcell/internal/engine"
)

func main() {
	_, err := engine.For("nonexistent")
	fmt.Println(err)
}
Output:
engine "nonexistent" is not available in this build; see https://github.com/devcell-sh/devcell/issues

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Register

func Register(n Name, e Engine)

Register makes e the implementation For returns for n. Engine packages call it from an init func. Like database/sql.Register, it panics if e is nil or n is already registered.

Registration, rather than a switch in For, is what lets engine subpackages import this package for the option types without an import cycle.

func Retired

func Retired(n Name) (hint string, ok bool)

Retired returns what to run instead of the removed engine n, and whether n is one.

func Supports

func Supports(n Name, g Guest) bool

Supports reports whether engine n can run guest g.

func Valid

func Valid(n Name) bool

Valid reports whether n is an engine cell can dispatch to.

Types

type BuildOpts

type BuildOpts struct {
	Cell Cell
	// Stack builds this stack instead of Cell.Stack (--stack); "" keeps
	// Cell.Stack. Docker validates it and falls back to DEVCELL_STACK.
	Stack   string
	Update  bool   // update nix flake inputs before applying the stack (--update)
	DryRun  bool   // print the commands instead of running them (--dry-run)
	Force   bool   // replace the guest image even if it already exists (--force)
	NoCache bool   // download the base image again instead of using the engine's cache (--no-cache)
	Stage   string // tart only: "base" builds the stack-agnostic base template; "full" or "" also applies the stack (--stage)

	// Image tags the built image instead of the default user image tag
	// (--image). Docker only; DEVCELL_BUILD_IMAGE is the fallback.
	Image string
	// BuildThreads sets nix's download parallelism, max-substitution-jobs
	// and http-connections (--build-threads); 0 keeps the default. Docker
	// only; it wins over DEVCELL_BUILD_THREADS and [build] threads.
	BuildThreads int
}

BuildOpts configures Engine.Build.

type Cell

type Cell struct {
	WorkspaceName string         // workspace name; home is ~/.devcell/<WorkspaceName>
	WorkspaceHome string         // the workspace's home on the host, ~/.devcell/<WorkspaceName>
	HostHome      string         // host user's home directory
	HostUser      string         // host user's login name ($USER); docker creates the same user in the container
	BaseDir       string         // project directory on the host
	ConfigDir     string         // global config dir: $XDG_CONFIG_HOME/devcell or ~/.config/devcell
	BuildDir      string         // build context: <BaseDir>/.devcell when the project has a devcell.toml, else ConfigDir
	Config        cfg.CellConfig // merged config, [env] expanded, engine flags folded in
	Stack         string         // resolved stack
	Modules       []string       // resolved [cell] modules
	VNCPort       string         // host port forwarded to the guest's VNC server
	RDPPort       string         // host port forwarded to the guest's RDP server

	// CellID tells apart cells opened on the same project from different
	// terminal panes: DEVCELL_CELL_ID, else the tmux or zellij pane id.
	CellID string
	// CellName is <project dir name>-<CellID>. Docker names the container
	// after it and mounts the project at /<CellName>.
	CellName string
	// ContainerName is the docker container name, devcell-<CellName>.
	ContainerName string
	// Hostname is the guest hostname when neither [cell] hostname nor
	// DEVCELL_HOSTNAME sets one: devcell-<CellName>.
	Hostname string

	// Guest is the OS image the engine boots, from --os, else [cell] os,
	// else the engine's default (see GuestFor). Engines with more than one
	// guest (winkit: WindowsPE, WindowsFull) pick their build stage and
	// template from it; empty means the engine's DefaultGuest.
	Guest Guest
}

Cell is the cell and project a verb acts on, as cmd/ resolved them from flags, the environment and the merged config.

func (Cell) WithStack

func (c Cell) WithStack(stack string) Cell

WithStack returns c with Stack set to stack, or c unchanged when stack is empty. Engines apply a --stack override (BuildOpts.Stack, InitOpts.Stack) with it.

type Engine

type Engine interface {
	// Init prepares the host for this engine once, before the first Build:
	// base images, boxes, keys. It may prompt on stdin.
	Init(ctx context.Context, opts InitOpts) error

	// Build creates or refreshes the guest the cell runs in and applies the
	// cell's stack and modules to it.
	Build(ctx context.Context, opts BuildOpts) error

	// Run acquires the cell's guest (building it when it is missing or
	// opts.Rebuild is set), boots it, and runs the agent in the project
	// directory with the terminal attached. It returns when the agent exits.
	// A non-zero agent exit is returned as *ExitError.
	Run(ctx context.Context, opts RunOpts) error
}

Engine is one runtime a cell can run on. Each verb gets everything it needs in its option struct. Engine-specific settings (tart SSH port, winkit ISO) come from Cell.Config, not from the caller.

func For

func For(n Name) (Engine, error)

For returns the implementation registered for n.

type ExitError

type ExitError struct {
	Code int
}

ExitError reports that the agent ran and exited with a non-zero status. cmd/ exits with the same status.

func (*ExitError) Error

func (e *ExitError) Error() string

type Guest

type Guest string

Guest is the OS image inside the cell. The --os and [cell] os values map to guests with GuestForOS.

const (
	Linux       Guest = "linux"
	MacOS       Guest = "macos"
	WindowsPE   Guest = "winpe"        // Windows PE + WSL1; no Windows state persists
	WindowsFull Guest = "windows-full" // full Windows + WSL1 (winkit stage full-wsl); not reachable from the CLI yet
)

func DefaultGuest

func DefaultGuest(n Name) (Guest, bool)

DefaultGuest returns the guest engine n runs when no OS is chosen, and whether n is a known engine.

func GuestFor

func GuestFor(n Name, osValues ...string) Guest

GuestFor returns the guest engine n runs: the guest of the first value in osValues (--os, then [cell] os) that maps to a guest n supports, else n's default guest. Empty, unknown and unsupported values are skipped, so a stale [cell] os under an explicit --engine does not fail the run. It returns "" for an unknown engine.

func GuestForOS

func GuestForOS(v string) (Guest, bool)

GuestForOS maps an --os or [cell] os value to its guest, and reports whether the value is known.

"windows" is the full Windows install (the default winkit guest). "winpe" is the PE boot volume (opt-in, lighter, no persistent Windows state).

type InitOpts

type InitOpts struct {
	Cell Cell
	// Stack is the --stack value, "" when it is not given. Tart and winkit
	// use it instead of Cell.Stack; docker writes it to the new
	// devcell.toml, which defaults to the base stack.
	Stack string
	Force bool // regenerate what an earlier Init created, e.g. SSH keys (--force)

	// Modules is the explicit [cell] modules list written to a new
	// devcell.toml (--modules). Docker only.
	Modules []string
	// Yes answers yes to every prompt, e.g. re-initializing a project that
	// already has a devcell.toml (--yes). Docker only.
	Yes bool
	// Update updates the nix flake inputs to their latest revisions instead
	// of only locking them (--update; --force implies it). Docker only.
	Update bool
}

InitOpts configures Engine.Init.

type Name

type Name string

Name is an execution engine, how a cell is run: the value of --engine and [cell] engine.

const (
	Docker Name = "docker" // Linux container
	Tart   Name = "tart"   // macOS VM on Apple Silicon
	Winkit Name = "winkit" // Windows VM via go-winkit: vz on macOS hosts, qemu on Linux hosts
)

func DefaultFor

func DefaultFor(g Guest) (Name, bool)

DefaultFor returns the engine guest g runs on when no engine is chosen, and whether g is a known guest.

func Resolve

func Resolve(flagEngine, flagOS, tomlEngine, tomlOS string) (n Name, deprecation string, err error)

Resolve returns the engine from the first non-empty source:

  1. CLI --engine flag
  2. CLI --os flag (mapped via GuestForOS and DefaultFor)
  3. TOML [cell].engine
  4. TOML [cell].os (mapped the same way)
  5. Docker (default)

The winning --engine or [cell] engine value must be Valid or a deprecated alias. When both --engine and --os are set, the pair must be in the capability table: incompatible pairs (e.g. --os windows --engine tart) return an error.

deprecation is a warning for a deprecated engine name the result came from (e.g. "qemu"), for the caller to print once; it is empty otherwise.

type RunOpts

type RunOpts struct {
	Cell         Cell
	Binary       string            // agent binary to run in the guest, e.g. "claude"
	DefaultFlags []string          // flags devcell always passes to Binary
	Args         []string          // the user's args, devcell's own flags stripped
	Env          map[string]string // agent env added after the cell's guest env, e.g. OPENCODE_CONFIG_CONTENT
	Rebuild      bool              // rebuild the guest before running (--build)
	Force        bool              // build a missing guest without asking first (--force)
	Update       bool              // update nix flake inputs, then rebuild (--update)
	Background   bool              // leave the guest running after the agent exits (--background)
	DryRun       bool              // print the commands instead of running them (--dry-run)
	Debug        bool              // log every step (--debug)

	// Detach starts the guest in the background and returns once it is up,
	// instead of attaching the terminal (cell start). Docker detaches the
	// container; winkit detaches the QEMU process.
	Detach bool
	// NoSecrets skips 1Password: no document is read and the agent does not
	// run under `op run` (--no-secrets, --skip-secrets, --no-1password).
	// Docker only.
	NoSecrets bool
	// NixDaemon starts nix-daemon in the guest so the agent can install
	// packages at runtime (--nix-daemon). Docker only.
	NixDaemon bool
	// NoPorts publishes no host ports, neither [ports] nor the GUI ports
	// (--no-ports). Docker only.
	NoPorts bool
	// UseFlake installs the packages of the project's flake.nix in the guest
	// once the user trusts it (--use-flake; [cell] flake turns it on too).
	// Docker only.
	UseFlake bool
	// AutoCleanup reaps nix-store roots no running cell uses before the
	// agent starts (--auto-cleanup). Docker only.
	AutoCleanup bool
	// ForceInsecureNetwork disables proxy mode even when [network.proxy]
	// enabled = true (--force-insecure-network). Docker only.
	ForceInsecureNetwork bool
	// Solitary enables full network lockdown: force-enables the proxy,
	// strips dangerous caps/mounts/privileged, and isolates the container
	// from the host (--solitary). Docker only.
	Solitary bool

	// NewBootView, when set, builds the boot panel the engine reports
	// progress to instead of the inline ux.BootPanel (CELL-657: the cage
	// renders it in a tmux popup). Docker only.
	NewBootView func(groups []ux.PanelGroup) ux.BootView
	// HideBanner drops the "<workspace> > <cell>" line above the boot panel
	// (the cage's bar already shows it).
	HideBanner bool
	// BeforeAttach, when set, runs after the cell is booted and before the
	// agent is attached to the terminal. An error aborts the run without
	// starting the agent. Docker only.
	BeforeAttach func() error
}

RunOpts configures Engine.Run.

Directories

Path Synopsis
Package docker is the docker engine: it builds `docker run`, `docker exec` and thin-image build argv, manages images, the shared nix-store volume and devcell containers, watches in-container boot progress, and implements `cell build df`, `cell build prune` and `cell cleanup`.
Package docker is the docker engine: it builds `docker run`, `docker exec` and thin-image build argv, manages images, the shared nix-store volume and devcell containers, watches in-container boot progress, and implements `cell build df`, `cell build prune` and `cell cleanup`.
Package tart implements the cell engine for macOS VMs on Apple Silicon via the tart CLI.
Package tart implements the cell engine for macOS VMs on Apple Silicon via the tart CLI.
Package winkit is the winkit engine: Windows guests built and booted by go-winkit (vz on macOS hosts, qemu on Linux hosts).
Package winkit is the winkit engine: Windows guests built and booted by go-winkit (vz on macOS hosts, qemu on Linux hosts).

Jump to

Keyboard shortcuts

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