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

runtime

package
v0.12.0 Latest Latest
Warning

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

Go to latest
Published: Sep 12, 2026 License: AGPL-3.0, AGPL-3.0-only Imports: 8 Imported by: 0

Documentation

Index

Constants

View Source
const (
	PhaseLoad     = "load"
	PhaseResolve  = "resolve"
	PhaseValidate = "validate"
	PhasePrepare  = "prepare"
	PhasePlan     = "plan"
	PhaseExecute  = "execute"
	PhaseReport   = "report"
	PhaseCleanup  = "cleanup"
)

Phase names — canonical, all modes.

Variables

This section is empty.

Functions

func HasCapability

func HasCapability(backend LifecycleBackend, cap Capability) bool

HasCapability checks if a backend declares a specific capability.

func Register

func Register(mode, name string, constructor func() LifecycleBackend)

Register adds a backend constructor to the global registry. Called from init() in each backend package. Key is (mode, name) — e.g. ("gitops", "flux").

func RunLifecycle

func RunLifecycle(ctx context.Context, cfg *config.Config, rctx *RuntimeContext) error

RunLifecycle is the single entrypoint for all lifecycle modes. CLI commands call this — they do NOT orchestrate phases themselves.

Phases execute in strict order:

Resolve → Validate → Prepare → Plan → [Execute] → Report → Cleanup

Load phase is the caller's responsibility (config is already loaded). Cleanup ALWAYS runs, even on error. Dry-run skips Execute and renders the Plan instead.

func RunLifecycleBackend added in v0.9.0

func RunLifecycleBackend(ctx context.Context, cfg *config.Config, rctx *RuntimeContext, mode, name string) error

RunLifecycleBackend runs the phase sequence against an explicitly named (mode, backend) pair, independent of cfg.Lifecycle.Mode. Presence-gated subsystems that coexist with the repo's primary mode (ansible convergence alongside gitops) dispatch through here; RunLifecycle is the mode-derived front door that delegates to it.

func RunLifecycleWith added in v0.9.0

func RunLifecycleWith(ctx context.Context, cfg *config.Config, rctx *RuntimeContext, mode string, backend LifecycleBackend) error

RunLifecycleWith runs the phase sequence against a caller-constructed backend instance — the seam for pre-phase scoping a registry constructor can't carry (e.g. `ansible run <id>` selecting one play before Validate).

func ValidateCapabilities

func ValidateCapabilities(backend LifecycleBackend, required []Capability) error

ValidateCapabilities checks that the backend supports all required capabilities. Called during the Validate phase — fails early, not at runtime.

Types

type ActionResult

type ActionResult struct {
	Name     string
	Success  bool
	Duration time.Duration
	Message  string
	Stderr   string // raw stderr for failure visibility — renderer tails this
}

ActionResult describes the outcome of a single executed action.

type Capability

type Capability string

Capability declares what a backend can do. The runtime validates required capabilities during the Validate phase.

const (
	CapReconcile          Capability = "reconcile"
	CapDryRun             Capability = "dry-run"
	CapImpactAnalysis     Capability = "impact-analysis"
	CapClusterAuth        Capability = "cluster-auth"
	CapForgeAuth          Capability = "forge-auth"
	CapStructuredProgress Capability = "structured-progress"
	CapPlanExecute        Capability = "plan-execute"
)

func DeriveRequired

func DeriveRequired(mode string, cfg *config.Config, rctx *RuntimeContext) []Capability

DeriveRequired determines which capabilities the RUNNING mode needs, given config and context. Phase ↔ Capability binding is enforced here.

type InvokerType

type InvokerType string

InvokerType identifies how StageFreight was invoked.

const (
	InvokerCI    InvokerType = "ci"
	InvokerLocal InvokerType = "local"
	InvokerAPI   InvokerType = "api" // future
)

func DetectInvoker

func DetectInvoker(ciCtx *ci.CIContext) InvokerType

DetectInvoker determines the invocation context from CIContext.

type LifecycleBackend

type LifecycleBackend interface {
	Name() string
	Capabilities() []Capability

	// Validate checks backend prerequisites (CLI availability, config completeness).
	Validate(ctx context.Context, cfg *config.Config, rctx *RuntimeContext) error

	// Prepare sets up the execution environment (kubeconfig, docker context, etc.).
	// Must register cleanup via rctx.Resolved.AddCleanup().
	Prepare(ctx context.Context, cfg *config.Config, rctx *RuntimeContext) error

	// Plan computes what will be done. Must be deterministic:
	// identical config + runtime inputs → identical output.
	Plan(ctx context.Context, cfg *config.Config, rctx *RuntimeContext) (*LifecyclePlan, error)

	// Execute dispatches planned actions. Must be idempotent for reconciliation backends:
	// repeated execution must converge to the same state without side effects.
	Execute(ctx context.Context, plan *LifecyclePlan, rctx *RuntimeContext) (*LifecycleResult, error)

	// Cleanup removes backend-specific ephemeral state.
	Cleanup(rctx *RuntimeContext)
}

LifecycleBackend is the full lifecycle contract. Backends participate in ALL phases — not just Execute.

Rules:

  1. Must not write to stdout/stderr — return LifecyclePlan/LifecycleResult instead.
  2. Must not mutate global state — all state goes through rctx.Resolved.
  3. Must register cleanup functions via rctx.Resolved.AddCleanup().

func ResolveBackend

func ResolveBackend(mode, name string) (LifecycleBackend, error)

ResolveBackend selects a backend by mode and name. Returns hard error for unknown/unimplemented combinations. Never silent fallback.

type LifecyclePlan

type LifecyclePlan struct {
	Mode    string
	Backend string
	Actions []PlannedAction
	// Declined are units the backend deliberately did NOT act on (e.g. Flux
	// kustomizations that failed audition validation under skip-invalid policy).
	// They are reported, not executed — Execute never touches them.
	Declined []PlannedAction
	DryRun   bool
	// Notes are backend-recorded run facts for the renderer (e.g. the resolved
	// auth method) — DATA, not output; presentation belongs to the cmd layer.
	Notes map[string]string
}

LifecyclePlan is the output of the Plan phase — what will be done. Dry-run renders this without calling Execute.

type LifecycleResult

type LifecycleResult struct {
	Actions []ActionResult
}

LifecycleResult is the output of the Execute phase.

type PlannedAction

type PlannedAction struct {
	Name        string // e.g. "reconcile flux-system/infrastructure" or "anchorage/grafana"
	Description string // human-readable reason (e.g. "IaC files changed since last deployment")
	Order       int
	Action      string            // intended action: "reconcile", "up", "noop", "error"
	Metadata    map[string]string // backend-specific detail (host, hash, drift tier, etc.)
}

PlannedAction describes a single action to be executed.

type ResolvedState

type ResolvedState struct {
	KubeconfigPath string // isolated tmpfile (gitops)
	CAPath         string // decoded CA tmpfile if from B64
	KubectlPath    string // resolved kubectl binary (cluster-identity queries)

	Backend LifecycleBackend // selected backend instance
	// contains filtered or unexported fields
}

ResolvedState holds ephemeral state created during the Prepare phase. Everything here is temporary and must be cleaned up.

func (*ResolvedState) AddCleanup

func (r *ResolvedState) AddCleanup(fn func())

AddCleanup registers a function to be called during Cleanup phase.

func (*ResolvedState) Cleanup

func (r *ResolvedState) Cleanup()

Cleanup runs all registered cleanup functions in reverse order.

type RuntimeContext

type RuntimeContext struct {
	CI       *ci.CIContext // existing CI/local detection
	Invoker  InvokerType   // ci | local | api
	RepoRoot string        // workspace root

	// DryRun controls whether Execute phase is skipped.
	DryRun bool

	// Resolved state — populated during Prepare phase, cleaned up after.
	Resolved ResolvedState
	// contains filtered or unexported fields
}

RuntimeContext holds all state for a lifecycle invocation. Three types of state are explicitly separated:

  • Declarative: from .stagefreight.yml (lives in config.Config)
  • Runtime: from environment variables (resolved during Prepare)
  • Resolved: computed ephemeral state (populated in Prepare, cleaned in Cleanup)

func (*RuntimeContext) Plan

func (r *RuntimeContext) Plan() *LifecyclePlan

Plan returns the lifecycle plan (output of Plan phase). Nil if not yet planned.

func (*RuntimeContext) Result

func (r *RuntimeContext) Result() *LifecycleResult

Result returns the lifecycle result (output of Execute phase). Nil on dry-run or error.

type RuntimeError

type RuntimeError struct {
	Phase   string
	Backend string
	Message string
	Cause   error
}

RuntimeError carries phase context through the error chain.

func (*RuntimeError) Error

func (e *RuntimeError) Error() string

func (*RuntimeError) Unwrap

func (e *RuntimeError) Unwrap() error

Jump to

Keyboard shortcuts

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