Help us shape the future of Go! Take the 2026 Go Developer Survey

agent

package
v0.29.0 Latest Latest
Warning

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

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

Documentation

Overview

Package agent implements the Strata instance bootstrap sequence.

The agent runs as a systemd service (strata-agent.service) at instance boot. It acquires the lockfile, verifies and fetches all layers, assembles the OverlayFS, writes environment config, and signals readiness. Any failure halts the instance — partial environments never run.

All external dependencies are expressed as interfaces so the boot sequence can be fully tested on any platform without Linux syscalls or AWS access.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Agent

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

Agent orchestrates the boot sequence for a Strata instance.

func New

func New(cfg Config) (*Agent, error)

New creates a new Agent, validating that required config fields are present. If Mounter is nil it is defaulted to the real overlay.Mount implementation.

func (*Agent) Run

func (a *Agent) Run(ctx context.Context) (*BootMetrics, error)

Run executes the 6-step boot sequence. On any failure, SignalFailed is called and the error is returned. On success, the overlay stays mounted until the process exits.

The returned *BootMetrics contains timing data for each step. FetchBytes, CachedLayers, and DownloadedLayers are left at zero — callers that have access to the LayerFetcher's stats should populate them after Run returns.

  1. Acquire lockfile from instance metadata.
  2. Fetch all layers in parallel and verify SHA256.
  3. Verify Sigstore bundles (when Verifier and BundleFetcher are configured).
  4. Assemble the OverlayFS.
  5. Write environment config files.
  6. Signal readiness.

type BootMetrics

type BootMetrics struct {
	StartedAt        time.Time `json:"started_at"`
	LockfileMs       int64     `json:"lockfile_ms"`       // step 1: acquire lockfile
	FetchMs          int64     `json:"fetch_ms"`          // step 3: parallel download
	FetchBytes       int64     `json:"fetch_bytes"`       // bytes downloaded (cache misses only)
	MountMs          int64     `json:"mount_ms"`          // step 4: OverlayFS assembly
	ConfigureMs      int64     `json:"configure_ms"`      // step 5: write env config files
	TotalMs          int64     `json:"total_ms"`          // wall time: start → ready
	LayerCount       int       `json:"layer_count"`       // layers in lockfile
	CachedLayers     int       `json:"cached_layers"`     // sqfs already in /strata/cache
	DownloadedLayers int       `json:"downloaded_layers"` // fetched from S3
}

BootMetrics records timing and transfer statistics for the strata-agent boot sequence. All duration fields are in milliseconds.

The caller of Run() is responsible for populating FetchBytes, CachedLayers, and DownloadedLayers from the LayerFetcher's stats after Run() returns.

type BundleFetcher

type BundleFetcher interface {
	FetchBundleJSON(ctx context.Context, layer spec.ResolvedLayer) ([]byte, error)
}

BundleFetcher downloads the Sigstore bundle JSON for a layer from the registry. Used alongside Verifier to perform cryptographic signature verification after layers are fetched.

An implementation may return (nil, nil) when layer.Bundle is empty, but must not rely on that being tolerated: with a Verifier configured, the agent refuses a layer that names no bundle before calling this, and treats an empty return for a layer that does name one as a verification failure. Returning no bytes is never a way to skip verification.

type Config

type Config struct {
	Source           LockfileSource
	Fetcher          LayerFetcher
	BundleFetcher    BundleFetcher  // optional; nil skips cosign bundle verification
	Verifier         trust.Verifier // optional; nil skips cosign bundle verification
	Signaler         ReadySignaler
	Mounter          Mounter          // optional; defaults to overlay.Mount
	PackageInstaller PackageInstaller // optional; nil skips package installation
	EnvRootDir       string           // defaults to "/" if empty

	// Warnings receives non-fatal agent diagnostics — notably the disclosure that
	// packages: entries are installed unattested (#139). Optional; nil discards.
	// cmd/strata-agent sets it to os.Stderr so the machine's boot log records that
	// the assembled environment left the attested set.
	Warnings io.Writer

	// MaxAge is the freshness bound (#224, threat T8): the agent refuses to boot a
	// lockfile resolved longer ago than this. Zero means no bound — the default,
	// so a frozen/cited environment of any age still boots and only its age is
	// surfaced. cmd/strata-agent sets it from STRATA_AGENT_MAX_AGE. The bound is
	// meaningful because resolved_at is inside the signed payload, so a replayed
	// stale-but-signed lockfile cannot be backdated past it (checked after the
	// signature verifies).
	MaxAge time.Duration

	// AllowUnverified permits booting when Verifier or BundleFetcher is nil.
	// Default false: the agent refuses to boot rather than mount layers whose
	// authenticity it cannot check (#93). Only a caller that has made the skip a
	// deliberate, logged choice sets this — cmd/strata-agent, under
	// STRATA_AGENT_ALLOW_UNVERIFIED. It has no effect when both Verifier and
	// BundleFetcher are set.
	AllowUnverified bool
}

Config holds all dependencies for the Agent. Verifier and BundleFetcher are optional; both must be non-nil to perform cosign bundle verification (only SHA256 content integrity is checked when either is nil). EnvRootDir defaults to "/" and is overridden in tests to a temp directory.

type ExecPackageInstaller

type ExecPackageInstaller struct{}

ExecPackageInstaller installs resolved package sets by executing pip, conda, and Rscript from the overlay's merged bin directories.

func (ExecPackageInstaller) Install

func (ExecPackageInstaller) Install(ctx context.Context, pkgs []spec.ResolvedPackageSet, mergedPath string) error

Install installs all package sets in pkgs into the overlay at mergedPath. It builds a PATH from the merged bin directories and dispatches to the appropriate installer for each package manager.

type FakeLayerFetcher

type FakeLayerFetcher struct {
	// Paths maps layer ID to local file path.
	Paths map[string]string
	// Err, if non-nil, is returned for every Fetch call.
	Err error
}

FakeLayerFetcher returns pre-configured local paths keyed by layer ID. Use it in tests to avoid S3 downloads.

func (*FakeLayerFetcher) Fetch

Fetch returns the path for layer.ID from Paths, or Err if set.

type FakeLockfileSource

type FakeLockfileSource struct {
	Lockfile *spec.LockFile
	Err      error
}

FakeLockfileSource returns a pre-configured lockfile or error. Use it in tests to avoid EC2 metadata or S3 dependencies.

func (*FakeLockfileSource) Acquire

Acquire returns the pre-configured Lockfile and Err.

type FakeMounter

type FakeMounter struct {
	Result *overlay.Overlay
	Err    error
}

FakeMounter returns a pre-built Overlay or error. Use it in tests to avoid Linux OverlayFS syscalls.

func (*FakeMounter) Mount

func (f *FakeMounter) Mount(_ []overlay.LayerPath) (*overlay.Overlay, error)

Mount returns the pre-configured Result and Err.

type FakePackageInstaller

type FakePackageInstaller struct {
	Called     bool
	MergedPath string
	Pkgs       []spec.ResolvedPackageSet
	Err        error
}

FakePackageInstaller records Install calls for assertion in tests. It never returns an error unless Err is set.

func (*FakePackageInstaller) Install

func (f *FakePackageInstaller) Install(_ context.Context, pkgs []spec.ResolvedPackageSet, mergedPath string) error

Install records the call and returns Err.

type FakeReadySignaler

type FakeReadySignaler struct {
	ReadyCalled  bool
	FailedCalled bool
	FailedReason error
}

FakeReadySignaler records calls to SignalReady and SignalFailed for assertion in tests. It never returns an error.

func (*FakeReadySignaler) SignalFailed

func (f *FakeReadySignaler) SignalFailed(_ context.Context, reason error) error

SignalFailed records the failure reason.

func (*FakeReadySignaler) SignalReady

func (f *FakeReadySignaler) SignalReady(_ context.Context, _ *spec.LockFile) error

SignalReady records that readiness was signaled.

type LayerFetcher

type LayerFetcher interface {
	Fetch(ctx context.Context, layer spec.ResolvedLayer) (localPath string, err error)
}

LayerFetcher downloads a layer to the local cache if not already present. It is responsible for cache lookup and download; SHA256 verification is performed by the agent after Fetch returns.

type LockfileSource

type LockfileSource interface {
	Acquire(ctx context.Context) (*spec.LockFile, error)
}

LockfileSource provides the lockfile from instance metadata. Implementations check user-data, S3, and EC2 instance tags in priority order.

type Mounter

type Mounter interface {
	Mount(layers []overlay.LayerPath) (*overlay.Overlay, error)
}

Mounter assembles the OverlayFS from a set of pulled layer paths. The default implementation calls overlay.Mount directly. FakeMounter is provided in fake.go for platform-neutral testing.

type PackageInstaller

type PackageInstaller interface {
	Install(ctx context.Context, pkgs []spec.ResolvedPackageSet, mergedPath string) error
}

PackageInstaller installs resolved package sets into the mounted overlay. The mergedPath argument is the OverlayFS merged view (e.g. /strata/env). A nil PackageInstaller skips installation; callers should check whether the lockfile has any Packages before wiring a non-nil installer.

type ReadySignaler

type ReadySignaler interface {
	SignalReady(ctx context.Context, lockfile *spec.LockFile) error
	SignalFailed(ctx context.Context, reason error) error
}

ReadySignaler reports success or failure to the outside world. Implementations write EC2 instance tags, CloudWatch events, and call sd_notify.

Jump to

Keyboard shortcuts

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