stack

package
v0.0.0-...-36f92f7 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2026 License: AGPL-3.0 Imports: 53 Imported by: 0

Documentation

Overview

Package stack reconciles a resolved project with what runs on the engine: it computes the desired resources, compares them with the labelled resources that exist, and applies the difference. It keeps no state: the engine is the source of truth.

Index

Constants

View Source
const BuildRepository = "localhost/egzo-build/"

BuildRepository is where the images `up` builds are tagged. The registry is localhost, so a missing image is never looked up on Docker Hub, and Podman names its local builds the same way.

View Source
const DefaultHarnessPrefix = "ghcr.io/egzo-ai/egzo-harness-"

DefaultHarnessPrefix is where harness images are published.

View Source
const DotenvFile = ".env"

DotenvFile is the file of the project directory the env backend reads a variable from when the environment does not have it, as Docker Compose does.

View Source
const LeaseTTL = 30 * time.Minute

LeaseTTL is how long a lease stays valid. A command does not renew it: it is far longer than any command takes.

Variables

View Source
var ErrEmptySecret = errors.New("empty secret")

ErrEmptySecret is wrapped by the error for a secret that holds nothing.

View Source
var ErrNotASecret = errors.New("not a secret")

ErrNotASecret is wrapped by the error for a pass name that is a directory of the store.

View Source
var ErrNotPublished = errors.New("no templates are published: run `egzo project up` first")

ErrNotPublished means `up` has not published templates yet.

View Source
var ErrPassNotFound = errors.New("`pass` was not found on PATH")

ErrPassNotFound is wrapped by the error for a pass vault when `pass` is not on PATH.

View Source
var Holder = func() string {
	host, _ := os.Hostname()
	return fmt.Sprintf("egzo %s, pid %d on %s", version.Version, os.Getpid(), host)
}

Holder is who takes the lease, as it is written on it. The hub says which user.

Functions

func Age

func Age(d time.Duration) string

Age is a duration as ps shows it: the largest unit that fits, 5s, 7m, 3h, 2d.

func AgentUser

func AgentUser(c *engine.Client) string

AgentUser is who agents run as: the invoking user, so files they write on the host are theirs. Podman maps users itself (rootless container root is the invoking user), so it keeps the image's.

func Apply

func Apply(ctx context.Context, c *engine.Client, desired Desired, plan []Action, dryRun bool, out io.Writer) error

Apply executes a plan. With dryRun it only reports what it would do.

func BaseVolume

func BaseVolume(project, workspace string) string

BaseVolume is the volume of the base clone of a git workspace.

func BindInstances

func BindInstances(ctx context.Context, c *engine.Client, project string, instances []Instance, p Published) error

BindInstances gives the proxy the credentials of the instances, bound to their templates' profiles. It binds every instance it can and reports each one it could not.

func BindingFor

func BindingFor(id, token, profile string) proxy.Binding

BindingFor is what the proxy needs to let an instance through: its id, its credentials, the profile of its template and the public half of its ssh identity. It holds no secret.

func BuildPolicy

func BuildPolicy(project *config.Resolved, secrets, placeholders map[string]string) proxy.Policy

BuildPolicy turns the egress profiles agents use into the policy the proxy enforces, one entry per profile. It embeds secret values, so it must only travel through exec stdin, never a label, environment variable or file visible to `inspect`. Which agent uses which profile is a matter of bindings (see BindingFor), which carry no secret.

func CheckOwnership

func CheckOwnership(observed Observed, project, dir string) error

CheckOwnership refuses to work when the project name is already used by a project that was created from another directory. There is no override: rename one of the projects.

func CheckWorktrees

func CheckWorktrees(ctx context.Context, c *engine.Client, env PrepEnv, project, dir string, plan []Worktree, reuse bool) error

CheckWorktrees refuses a plan that would take over what is already there: a worktree volume, or the branch of the instance in the base. Both are somebody's work, so only reuse continues with them.

func CloneBases

func CloneBases(ctx context.Context, c *engine.Client, project *config.Resolved, dir string, env PrepEnv, out, warn io.Writer)

CloneBases makes the base clone of every git workspace an agent lists and that has none yet, as `up`'s last step. A failure is not fatal: it is written to warn, and the next `spawn` (or `egzo workspace fetch`) tries again. The clone goes through the proxy under the egress profile of the first template that lists the workspace.

func ControlRequest

func ControlRequest(ctx context.Context, c *engine.Client, project, method, path string, body []byte) ([]byte, error)

ControlRequest sends one request to the control sidecar's operator API through exec and returns the response body. It is how the CLI, and later the hub, talk to the control sidecar.

func ControlStream

func ControlStream(ctx context.Context, c *engine.Client, project, method, path string, out, errOut io.Writer) error

ControlStream runs a streaming request in the control sidecar and copies its output to out.

func DirectoryWorkspacesOf

func DirectoryWorkspacesOf(project *config.Resolved, agent config.ResolvedAgent) []string

DirectoryWorkspacesOf lists the directory workspaces an agent mounts.

func Down

func Down(ctx context.Context, c *engine.Client, observed Observed, env PrepEnv, project, dir string, out io.Writer) error

Down removes everything egzo made for a project: its containers, then their networks, then its volumes (the control state, the CA and the homes). Workspace directories on the host are never touched.

func EnsureDirectoryVolumes

func EnsureDirectoryVolumes(ctx context.Context, c *engine.Client, env PrepEnv, project *config.Resolved, dir string, names ...string) error

EnsureDirectoryVolumes makes the volumes of the directory workspaces that are missing, empty and the agent user's. With names it makes only those; a name that is not a directory workspace of the project is ignored.

func EnsurePlaceholders

func EnsurePlaceholders(ctx context.Context, c *engine.Client, project *config.Resolved) (map[string]string, error)

EnsurePlaceholders returns the placeholder of every reference, which the control sidecar makes the first time and keeps for as long as its volume lives.

func FetchBase

func FetchBase(ctx context.Context, c *engine.Client, project *config.Resolved, dir string, env PrepEnv, name string, out io.Writer) error

FetchBase makes the base clone of a git workspace when it is missing and fetches into it when it is there, through the proxy under the egress profile of the first template that lists the workspace. It is `workspace fetch`.

func ForgetWorktrees

func ForgetWorktrees(ctx context.Context, c *engine.Client, env PrepEnv, project, dir string, observed Observed, instances []string) error

ForgetWorktrees makes the base clones forget the worktrees of instances whose volumes are gone, so that a name can be used again. The branches stay: what was committed outlives the instance. It is best effort: a base that cannot be reached has nothing the next spawn of the name cannot cope with (`--reuse` forces).

func FromDotenv

func FromDotenv(ref config.SecretRef, dir string) bool

FromDotenv tells whether the env backend reads ref from the project's .env rather than the environment.

func GetFiles

func GetFiles(ctx context.Context, c *engine.Client, env PrepEnv, project, volume, src, dest string, out io.Writer) error

GetFiles copies a path of a workspace volume (a directory workspace's, or an instance's worktree) out to this machine. A directory's contents go to dest, which is made; a file goes to dest, or into it when dest is a directory.

func InsidePath

func InsidePath(p string) (string, error)

InsidePath cleans a path given as inside a workspace and refuses one that leaves it: absolute, or climbing out.

func InstanceContainer

func InstanceContainer(project, instance string) string

InstanceContainer is the name of an instance's container.

func InstanceNetwork

func InstanceNetwork(project, instance string) string

InstanceNetwork is the name of an instance's network.

func Lock

func Lock(ctx context.Context, c *engine.Client, project, image string) (release func(), err error)

Lock takes the project's lock, or fails with a *LockedError when another command holds it. image is any image the engine has or can pull: the egzo image.

func LockName

func LockName(project string) string

LockName is the name of the lease container of a project.

func LockWait

func LockWait(ctx context.Context, c *engine.Client, project, image string, timeout time.Duration) (release func(), err error)

LockWait is Lock for commands that are meant to run side by side, such as several spawns at once: when another command holds the lock it waits for it, up to the timeout, and then fails like Lock.

func NewInstanceID

func NewInstanceID() string

NewInstanceID makes the id of an instance: a ULID, 48 bits of milliseconds then 80 random bits in 26 characters, so ids sort by the time they were made. Nothing derives it from the name, which can come back; the id never does.

func PlaceholderRefs

func PlaceholderRefs(project *config.Resolved) []string

PlaceholderRefs lists, sorted, the secret references that a placeholder service of a profile some agent uses names.

func PutFiles

func PutFiles(ctx context.Context, c *engine.Client, env PrepEnv, project, dir, workspace, src, dest string, out io.Writer) error

PutFiles copies a file or a directory of this machine into a directory workspace, as the agent user. dest is the path in the workspace: for a directory it is the directory the contents go to ("" is the workspace's root).

func ReadDotenv

func ReadDotenv(dir string) (map[string]string, error)

ReadDotenv reads the variables of the project's .env (none when there is no file). An error never holds a value.

func ReadPlaceholders

func ReadPlaceholders(ctx context.Context, c *engine.Client, project *config.Resolved) map[string]string

ReadPlaceholders returns the placeholders the control sidecar holds for the references, and the stand-in for the ones it does not (or when it cannot be asked). It creates nothing: it is what a dry run and the staleness check use.

func ReadPrompts

func ReadPrompts(project *config.Resolved, dir string) (map[string]string, error)

ReadPrompts reads the prompt file of every agent that has one. The text travels in the published template and reaches the agent in EGZO_PROMPT, so nothing of the host is mounted and a spawn needs no file. A prompt that cannot be read is an error.

func ReadSecret

func ReadSecret(ref config.SecretRef, dir string) (string, error)

ReadSecret reads the value of a secret from its backend. dir is the project directory, where the env backend finds the project's .env. An error never contains a value.

func ReadSecretKey

func ReadSecretKey(ref config.SecretRef, dir string) (string, error)

ReadSecretKey reads the project's secret key: a secret like any other, at least seal.MinKeyBytes long.

func ReadSecretText

func ReadSecretText(ref config.SecretRef, dir string) (string, error)

ReadSecretText is ReadSecret for a secret that is text of several lines, such as an ssh private key: a pass entry is read whole instead of by its first line (the other lines are notes for any other secret).

func ReloadPolicy

func ReloadPolicy(ctx context.Context, c *engine.Client, project *config.Resolved, dir string) error

ReloadPolicy loads the egress policy into a proxy that was started again, and binds the instances again: the policy and the bindings live in the proxy's memory, so a restarted proxy refuses everything until it is given them. The policy comes from the published templates, as spawn does, so a file edited since `up` changes nothing for the instances that run; only the secrets' locations come from the file. The proxy needs a moment before its operator API answers, so this retries for a while.

func RemoveInstances

func RemoveInstances(ctx context.Context, c *engine.Client, observed Observed, env PrepEnv, project, dir string, names []string, force bool, out io.Writer) (removed []string, err error)

RemoveInstances removes instances: the container, its registration in control and in the proxy, its network, and its volumes: the home and the worktrees. The branches the instances made stay in the base clones, which forget the removed worktrees. Nothing is removed unless every name is an instance and, without force, every instance is stopped. It returns the names it removed.

func RemoveWorkspaces

func RemoveWorkspaces(ctx context.Context, c *engine.Client, observed Observed, names []string, all bool, out io.Writer) error

RemoveWorkspaces deletes the volumes of workspaces: the directory, or the base clone of a git workspace. It refuses while a container mounts the volume, and a git workspace while a worktree of it is left. With all it deletes every workspace volume the project has, left-over worktrees included, that nothing uses.

func RemoveWorktreeVolumes

func RemoveWorktreeVolumes(ctx context.Context, c *engine.Client, env PrepEnv, observed Observed, project, dir, workspace string, instances []string, out io.Writer) error

RemoveWorktreeVolumes deletes the worktree volumes that no instance owns any more (a spawn that could not undo itself, or an instance whose removal did not finish), and makes the base forget them. The branches stay.

func ResolveSecrets

func ResolveSecrets(project *config.Resolved, dir string) (map[string]string, error)

ResolveSecrets reads the value of every secret an agent's profile injects, the secret key, and the upstream CA. A secret that cannot be read is an error: an agent must not start without the credentials its profile promises.

func RunPrep

func RunPrep(ctx context.Context, c *engine.Client, spec PrepSpec) (string, error)

RunPrep runs a prep container to completion and returns what it printed. A non-zero exit is an error carrying that output.

func RunWorktreePreps

func RunWorktreePreps(ctx context.Context, c *engine.Client, project *config.Resolved, dir string, env PrepEnv, from InstanceIdentity, tokens map[string]string, plan []Worktree, options WorktreeOptions, out io.Writer) error

RunWorktreePreps makes the worktrees of an instance, one at a time, on the instance's own network, so the base is cloned (when it is missing) and fetched through the proxy under the instance's identity. A volume that this call made and that the job did not fill is removed again: an empty base or worktree is not work.

func StaleError

func StaleError(stale []Instance) error

StaleError is what `up` says when stale instances stand in its way.

func Unlock

func Unlock(ctx context.Context, c *engine.Client, project string) (holder string, wasLocked bool, err error)

Unlock removes the project's lock whoever holds it, and says who did. It is for a command that was killed.

func Up

func Up(ctx context.Context, c *engine.Client, project *config.Resolved, dir string, opts Options, out io.Writer) error

Up converges a project's infrastructure: the sidecars, their networks and volumes, the proxy's policy, and the published templates. It starts no agent: instances are spawned from the templates. It refuses while an instance is stale, because converging would leave it running something the file no longer says.

func WorkspaceVolume

func WorkspaceVolume(project, workspace string) string

WorkspaceVolume is the volume of a directory workspace.

func WorktreeVolume

func WorktreeVolume(project, workspace, instance string) string

WorktreeVolume is the volume of the worktree of an instance of a git workspace.

func WriteStatus

func WriteStatus(rows []Row, now time.Time, out io.Writer)

WriteStatus prints a project's containers.

Types

type Action

type Action struct {
	Verb string // create, remove, start, connect, disconnect
	Type string // container, network, volume
	Name string
	ID   string // existing resource, for remove, start and disconnect
	// Peer is the container a connect or disconnect action moves in or out of the network Name;
	// Alias is the name it is reachable by on that network.
	Peer  string
	Alias string
}

Action is one step of converging a project.

func BuildPlan

func BuildPlan(desired Desired, observed Observed, recreate bool) []Action

BuildPlan compares the desired resources with what exists. The returned actions are in execution order: containers go first when removing and last when creating.

Volumes hold data, so they are never removed or recreated by up: only `egzo project down` deletes them.

func (Action) String

func (a Action) String() string

type Attachment

type Attachment struct {
	Container string
	Alias     string
	Networks  []string
}

Attachment joins a sidecar to agent networks under an alias. It is not part of the sidecar's definition: instances come and go without recreating the sidecar.

type ContainerSpec

type ContainerSpec struct {
	Name  string
	Image string
	Cmd   []string
	User  string
	// OwnedVolumes are volumes the container writes as User: the engine creates volumes owned by
	// root and agents do not run as root, so they are handed over once the container exists.
	OwnedVolumes []string
	Env          []string
	Mounts       []MountSpec
	Tmpfs        map[string]string
	Network      string
	WorkingDir   string
	Harness      string
	NanoCPUs     int64
	Memory       int64
	Healthcheck  []string
	// PidsLimit caps processes and threads; MemorySwap equals Memory when a memory limit is set, so
	// swap does not double it.
	PidsLimit  int64
	MemorySwap int64
	// Agents run under an init process that reaps children and forwards signals.
	Init bool
	// Hardened sidecars get a read-only root filesystem. Agents need a writable one.
	ReadonlyRootfs bool
	Identity       engine.Identity `json:"-"`
}

type Desired

type Desired struct {
	Networks    []NetworkSpec
	Volumes     []VolumeSpec
	Containers  []ContainerSpec
	Attachments []Attachment
	Control     string
	Proxy       string // empty when the project has no agents
	// PrepImage runs the short-lived prep containers (git, volume ownership).
	PrepImage string
}

Desired is everything a project should consist of.

func Desire

func Desire(project *config.Resolved, dir string, in Inputs) (Desired, error)

Desire computes the desired resources of a project.

func DesireInstance

func DesireInstance(view *config.Resolved, dir string, in Inputs, name string, from InstanceIdentity) (Desired, error)

DesireInstance computes the resources of one instance: its network, its home volume, its container, and the attachments of the sidecars to its network. view is the project with the instance as an agent (see Published.View); name is the instance's key in it.

type DotenvError

type DotenvError struct {
	Line   int    // 0 when the parser does not say
	Reason string // a message of egzo's, or empty
}

DotenvError is a .env that cannot be parsed. It never holds a value: the parser's own messages can quote one.

func (*DotenvError) Error

func (e *DotenvError) Error() string

type ExistsError

type ExistsError struct {
	Name     string
	Template string
}

ExistsError is what a spawn answers when the name is taken by an instance.

func (*ExistsError) Error

func (e *ExistsError) Error() string

type Inputs

type Inputs struct {
	// Image is the all-in-one egzo image that runs every sidecar role.
	Image string
	// Tokens maps each instance to the token that identifies it to the proxy and control.
	Tokens map[string]string
	// User is the "uid:gid" agents run as, so what they write on the host is the invoking user's.
	// Empty leaves it to the image (Podman maps users itself).
	User string
	// HarnessPrefix is the start of a harness image's name, ending in "egzo-harness-".
	HarnessPrefix string
	// Prompts maps each agent that has a prompt file to its text (see ReadPrompts).
	Prompts map[string]string
	// Instances are the names of the instances that exist: the sidecars are attached to their networks.
	Instances []string
	// Placeholders maps each instance to the variables it gets and their placeholder texts (not secrets).
	Placeholders map[string]map[string]string
	// SignIns maps each instance to the variables that carry the stand-ins of its sign-ins (not secrets: they only work
	// through the proxy), for the harness to write where its client keeps its tokens.
	SignIns map[string]map[string]string
}

Inputs are what Desire needs besides the resolved project.

type Instance

type Instance struct {
	Name         string
	ID           string // see NewInstanceID
	Template     string // the key of the template, from the service label
	Actor        string
	Container    string
	State        string
	Created      time.Time
	TemplateHash string
}

Instance is an agent spawned from a template, as the engine shows it. State is "missing" for what is left of an instance that has no container any more.

func StaleInstances

func StaleInstances(observed Observed, p Published) []Instance

StaleInstances lists the instances that do not match the templates of p.

func (Instance) Stale

func (i Instance) Stale(p Published) bool

Stale reports whether the instance no longer matches its template: the template changed since it was spawned, or is gone.

type InstanceIdentity

type InstanceIdentity struct {
	// ID is the instance's own id (see NewInstanceID).
	ID           string
	Template     string
	Actor        string
	TemplateHash string
}

InstanceIdentity says where an instance came from.

type LockedError

type LockedError struct {
	Project string
	Holder  string
	Expires time.Time
}

LockedError is what a command that cannot take the lock says.

func (*LockedError) Error

func (e *LockedError) Error() string

type LogProbe

type LogProbe struct {
	// Driver and Options are what the engine gave the container (the effective configuration, the daemon's own
	// options included).
	Driver  string
	Options map[string]string
	// Readable is whether the log could be read back at all. When it could not, ReadError says why.
	Readable  bool
	ReadError string
	// Separated is whether standard output and standard error came back apart.
	Separated bool
	// Followed is whether a line written while we were already following arrived while the container was still
	// running, which is what a client that follows needs.
	Followed bool
}

LogProbe is what the engine's default logging did with a throwaway container.

func ProbeLogs

func ProbeLogs(ctx context.Context, c *engine.Client, image string) (LogProbe, error)

ProbeLogs runs a short container from image under the engine's default logging and reads its log back, following it. An error means the probe itself could not run (no such image, no engine); a log that cannot be read is a result, not an error.

func (LogProbe) String

func (p LogProbe) String() string

String is for error messages.

type MountSpec

type MountSpec struct {
	Bind     bool
	Source   string
	Target   string
	ReadOnly bool
}

MountSpec is a volume (Source is the volume name) or a host directory (Source is the path).

type NetworkSpec

type NetworkSpec struct {
	Name     string
	Internal bool
	Identity engine.Identity `json:"-"`
}

type NotUpError

type NotUpError struct{ Sidecar, State string }

NotUpError means the infrastructure a spawn needs is not running.

func (*NotUpError) Error

func (e *NotUpError) Error() string

type Observed

type Observed struct {
	Resources []Resource
	// Ignored is what carries the project's label but labels egzo never writes (engine.IdentityOf): it is not the project's, and
	// nothing is done to it. Each says what and why.
	Ignored []string
}

Observed is everything that exists on the engine for a project.

func Observe

func Observe(ctx context.Context, c *engine.Client, project string) (Observed, error)

Observe lists every container, network and volume labelled as belonging to project.

func (Observed) Instance

func (o Observed) Instance(name string) (Instance, bool)

Instance finds one instance by name.

func (Observed) InstanceNames

func (o Observed) InstanceNames() []string

InstanceNames lists the names of the instances.

func (Observed) Instances

func (o Observed) Instances() []Instance

Instances lists the instances of the project, sorted by name: the containers labelled as an agent with an instance name.

type Options

type Options struct {
	DryRun   bool
	Recreate bool
	Image    string
	// HarnessPrefix overrides where harness images are pulled from (EGZO_HARNESS_PREFIX).
	HarnessPrefix string
	// Warnings is where what went wrong without failing `up` is written (a base clone that could not be made).
	Warnings io.Writer
}

Options are the flags of `egzo project up`.

type PassError

type PassError struct{ Message string }

PassError is a failure of `pass show` itself; Message is the first line pass printed on stderr.

func (*PassError) Error

func (e *PassError) Error() string

type PrepEnv

type PrepEnv struct {
	Image string
	User  string
}

PrepEnv is what a prep container needs: the egzo image it runs and the "uid:gid" that owns the volumes (empty when the engine maps users itself).

type PrepSpec

type PrepSpec struct {
	Image    string
	Cmd      []string
	User     string // "" runs as the image's user (root)
	CapAdd   []string
	Env      []string
	Mounts   []MountSpec
	Network  string // "" has no network at all
	Identity engine.Identity
	Timeout  time.Duration
}

PrepSpec is a short-lived container that does one job for the CLI and is removed afterwards: cloning a repository, handing a volume to the agent's user, checking a clone before it is deleted.

type Published

type Published struct {
	Version int
	Project string
	Dir     string
	// Image is the all-in-one egzo image: the prep containers use it.
	Image string
	// User is the "uid:gid" instances run as: the user who ran `up`.
	User      string
	Templates map[string]Template
}

Published is what `up` leaves in the control sidecar for spawn: the templates, and what is needed to run an instance as `up` would have run it.

func ParsePublished

func ParsePublished(data []byte) (Published, error)

ParsePublished reads what Marshal wrote.

func Publish

func Publish(project *config.Resolved, dir, image, harnessPrefix, user string) (Published, error)

Publish resolves the templates of a project. It reads the prompt files: the text travels in the template, so a spawn needs no file, and a changed prompt makes its instances stale.

func PublishWith

func PublishWith(project *config.Resolved, dir, image, harnessPrefix, user string, placeholders map[string]string) (Published, error)

PublishWith is Publish with the placeholders (by secret reference) the agents get.

func ReadPublished

func ReadPublished(ctx context.Context, c *engine.Client, project string) (Published, error)

ReadPublished asks the control sidecar for the templates `up` last published.

func (Published) AsProject

func (p Published) AsProject(file *config.Resolved) *config.Resolved

AsProject is the project as the published templates describe it, each template an agent under its own name: what restarting the proxy builds its policy from, so a file edited since `up` changes nothing. The secrets and the secret key are the file's (nil for none), since the templates hold references and never where a secret lives.

func (Published) Marshal

func (p Published) Marshal() ([]byte, error)

Marshal is the form the templates are stored in.

func (Published) Names

func (p Published) Names() []string

Names lists the templates, sorted.

func (Published) View

func (p Published) View(instances map[string]string) *config.Resolved

View is the project as one or more instances see it: the agents are the given instances (name to template), each a copy of its template under its own name, with the image resolved. The functions that compute an agent's resources work on it unchanged.

type Report

type Report struct {
	Status   string
	Activity string
	Open     int  // requests the agent has fetched and not resolved
	Waiting  bool // it has asked a question nobody has answered
}

Report is what an agent last said about itself and what it is doing, as the control sidecar knows it.

type Resource

type Resource struct {
	Type       string // container, network or volume
	ID         string
	Name       string
	State      string   // containers only
	Health     string   // containers only
	Networks   []string // containers only: names of the networks it is attached to
	Service    string
	Kind       string
	ConfigHash string
	ProjectDir string
	// Workspace is the workspace a volume belongs to.
	Workspace string
	// Instance, Actor and TemplateHash come from the labels of what belongs to an instance.
	Instance     string
	Actor        string
	TemplateHash string
	InstanceID   string    // on the container and the network of an instance
	Created      time.Time // containers only
}

Resource is one existing engine resource that belongs to a project.

type Row

type Row struct {
	Name     string    `json:"name"`
	ID       string    `json:"id,omitempty"` // an instance's id; a sidecar has none
	Service  string    `json:"service"`
	Kind     string    `json:"kind"`
	State    string    `json:"state"`
	Health   string    `json:"health"`
	Activity string    `json:"activity"`
	Open     int       `json:"open"`
	Waiting  bool      `json:"waiting"`
	Status   string    `json:"status"`
	Actor    string    `json:"actor"`
	Created  time.Time `json:"created"`
	Stale    bool      `json:"stale"`
}

Row is one container of a project as `egzo ps` shows it.

func Rows

func Rows(observed Observed, reported map[string]Report, published *Published) []Row

Rows describes a project's containers. reported holds what the control sidecar knows of each agent, by instance name; published, when the templates could be read, says which instances are stale.

type ShortSecretKeyError

type ShortSecretKeyError struct{ Bytes int }

ShortSecretKeyError is a project secret key that is too short to be one. It never holds the value.

func (*ShortSecretKeyError) Error

func (e *ShortSecretKeyError) Error() string

type Snapshot

type Snapshot struct {
	CreatedBy    string            `yaml:"created-by"`
	SpecVersion  string            `yaml:"spec-version"`
	ConfigHashes map[string]string `yaml:"config-hashes"`
	Config       *config.Resolved  `yaml:"config"`
}

Snapshot is the resolved project as it was applied: what the control sidecar keeps on its volume, keyed by hash, so any tool with engine access can show what a project runs under. It holds references to secrets, never their values, and the container config hashes so a stale snapshot is detectable against the labels.

type SpawnRequest

type SpawnRequest struct {
	Template string
	// Name is the instance's name; empty gives `<template>-<n>`.
	Name string
	// Actor is who asks: "operator" for the CLI, "user:<id>" or "service:<name>" for another tool.
	Actor string
	// NoFetch makes the worktrees from the base clones as they are, without fetching first.
	NoFetch bool
	// Reuse continues with a worktree or a branch an earlier instance of the name left, instead of refusing it.
	Reuse bool
}

SpawnRequest says what to spawn.

type Spawned

type Spawned struct {
	Name      string
	ID        string
	Template  string
	Container string
	Actor     string
	// TemplateHash is the hash of the template the instance was made from.
	TemplateHash string
}

Spawned is the instance a spawn made.

func Spawn

func Spawn(ctx context.Context, c *engine.Client, project, dir string, req SpawnRequest, out io.Writer) (Spawned, error)

Spawn makes an instance from a template `up` published. It never reads the project file and never reads a secret: the proxy already holds the profiles, and the instance is only bound to one. A spawn that fails removes what it created, and never a worktree that holds work.

type Template

type Template struct {
	Agent      config.ResolvedAgent
	Profile    *config.ResolvedProfile
	Workspaces map[string]config.ResolvedWorkspace // the declared workspaces its mounts name
	// PromptText is the text of the agent's prompt file, read when `up` ran: an instance needs nothing on the host.
	PromptText string
	// Image is the harness image, resolved when `up` ran, or the image it built.
	Image string
	// Placeholders maps each variable the agent gets to its placeholder text. A placeholder is not a
	// secret. The text is made once and never changes, so the hash leaves it out: what decides whether
	// an instance is stale is the profile's service, which names the variable and the secret.
	Placeholders map[string]string `json:",omitempty"`
	// Hash fingerprints all of the above. An instance carries the hash of the template it was spawned
	// from; when the template's hash moves, the instance is stale.
	Hash string
}

Template is one agent of the file as a spawn instantiates it: everything that decides what the instance is, resolved by `up`, so that a spawn needs neither the file nor any secret.

type VolumeSpec

type VolumeSpec struct {
	Name     string
	Identity engine.Identity `json:"-"`
}

type WorkspaceRow

type WorkspaceRow struct {
	Name      string   `json:"name"`
	Kind      string   `json:"kind"`   // directory or git
	Volume    string   `json:"volume"` // the directory's volume, or the base clone's
	State     string   `json:"state"`  // a directory: exists or missing; a git workspace: cloned or not cloned
	Worktrees []string `json:"worktrees"`
}

WorkspaceRow is a workspace as `egzo workspace ls` shows it.

func WorkspaceRows

func WorkspaceRows(project *config.Resolved, observed Observed) []WorkspaceRow

WorkspaceRows describes the declared workspaces of a project as the engine holds them.

type Worktree

type Worktree struct {
	Workspace string
	Instance  string
	Volume    string // the worktree's volume
	Base      string // the base's volume
	URL       string
	Branch    string
}

Worktree is the worktree a git workspace needs for an instance.

func PlanWorktrees

func PlanWorktrees(project *config.Resolved, instance string) []Worktree

PlanWorktrees lists the worktrees instance needs, one per git workspace it lists.

func (Worktree) String

func (c Worktree) String() string

type WorktreeOptions

type WorktreeOptions struct {
	NoFetch bool
	Reuse   bool
}

WorktreeOptions are what `spawn` may say about the worktrees it makes.

Jump to

Keyboard shortcuts

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