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 ¶
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.
- Acquire lockfile from instance metadata.
- Fetch all layers in parallel and verify SHA256.
- Verify Sigstore bundles (when Verifier and BundleFetcher are configured).
- Assemble the OverlayFS.
- Write environment config files.
- 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 ¶
func (f *FakeLayerFetcher) Fetch(_ context.Context, layer spec.ResolvedLayer) (string, error)
Fetch returns the path for layer.ID from Paths, or Err if set.
type FakeLockfileSource ¶
FakeLockfileSource returns a pre-configured lockfile or error. Use it in tests to avoid EC2 metadata or S3 dependencies.
type FakeMounter ¶
FakeMounter returns a pre-built Overlay or error. Use it in tests to avoid Linux OverlayFS syscalls.
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 ¶
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 ¶
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 ¶
LockfileSource provides the lockfile from instance metadata. Implementations check user-data, S3, and EC2 instance tags in priority order.
type Mounter ¶
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.