runner

package
v0.44.1 Latest Latest
Warning

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

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

Documentation

Overview

Package runner is the CI-side driver: it invokes the same terramate scripts a human runs, captures per-stack output, renders + classifies in-process, and reports progress to the control-plane server over the typed events protocol.

This file is the server client. All reporting is best-effort by design — a down or absent server degrades the build to "no live progress", never to failure — except the apply-time gate check (see gate.go), which is fail-closed. An empty server URL disables the client entirely, so local runs and the no-op `run tick` need no server.

Index

Constants

View Source
const (
	EnvServer      = "TFSTACKPLAN_SERVER"      // control-plane base URL ("" = offline, no-op)
	EnvAudience    = "TFSTACKPLAN_AUDIENCE"    // OIDC ID-token audience; set = authenticate via Google ADC
	EnvExecution   = "TFSTACKPLAN_EXECUTION"   // execution id this run reports under
	EnvStack       = "TFSTACKPLAN_STACK"       // current stack path (fallback for `run tick --stack`)
	EnvEnvironment = "TFSTACKPLAN_ENVIRONMENT" // deployment environment for the execution
)

Environment variables the orchestrator (`run plan`/`run apply`) sets and the per-stack `run tick` reads, so progress reporting needs no flags threaded through the terramate scripts. Empty TFSTACKPLAN_SERVER disables reporting.

Variables

This section is empty.

Functions

func APITokenFunc added in v0.21.0

func APITokenFunc(audience string) (gauth.TokenFunc, error)

APITokenFunc returns the /api/* bearer source: a non-empty audience selects Google OIDC ID tokens from Application Default Credentials — with discovery (which can hit the network) bounded to 10s; an empty audience → nil (unauthenticated). OIDC is deliberately opt-in via the audience: a token-less environment must not probe ambient machine credentials, hard-fail on a stale ADC file, or send a replayable ID token to whatever host the server URL happens to name.

func NormalizeEdges added in v0.38.0

func NormalizeEdges(stacks []string, edges []events.Edge) []events.Edge

NormalizeEdges maps run-graph edge endpoints onto the listed stack namespace and drops edges touching stacks outside the set. The two commands live in different namespaces: `terramate list` under --dir <tier> yields tier-relative paths (cluster/x) while `experimental run-graph` labels nodes project-root- relative (stacks/nonprod/cluster/x). An exact match wins; otherwise an endpoint matches the unique listed stack it path-suffixes ("…/"+stack). Always returns a non-nil slice.

func ParseLine added in v0.43.0

func ParseLine(line string) events.ChangeReason

Types

type Client

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

Client posts execution lifecycle events to the control-plane server. It wraps the OpenAPI-generated client (internal/api — the wire contract lives in api/openapi.yaml) with the runner's calling conventions: disabled on an empty URL, best-effort bearer minting, and non-2xx collapsed to errors.

func ClientForEnvironment added in v0.43.0

func ClientForEnvironment(env string) *Client

ClientForEnvironment builds a Client from TFSTACKPLAN_SERVER, matching the environment against local configuration if the env var is unset.

func ClientFromEnv

func ClientFromEnv() *Client

ClientFromEnv builds a Client from TFSTACKPLAN_SERVER. When the server var is empty the client is disabled (every call is a no-op). Auth comes from APITokenFunc over TFSTACKPLAN_AUDIENCE; when the audience is set but ADC is unavailable, a warning is printed and requests go unauthenticated (best-effort reporting degrades, the fail-closed gate check errors).

func NewClient

func NewClient(baseURL string) *Client

NewClient builds an unauthenticated client for the server at baseURL (empty disables it). Authenticated callers use NewClientTokenSource (Google OIDC). A short timeout keeps a slow/down server from stalling the build.

func NewClientTokenSource added in v0.21.0

func NewClientTokenSource(baseURL string, token gauth.TokenFunc) *Client

NewClientTokenSource builds a client whose requests carry bearer tokens from token — the Google OIDC path (ID tokens minted from ambient credentials).

func (*Client) AdminChecksOverride added in v0.28.0

func (c *Client) AdminChecksOverride(ctx context.Context, pr int, env, check, conclusion, reason string) error

AdminChecksOverride requests the server to override a check conclusion.

func (*Client) AdminExecutionsCancel added in v0.28.0

func (c *Client) AdminExecutionsCancel(ctx context.Context, id, reason string) error

AdminExecutionsCancel requests the server to cancel/abort a running execution.

func (*Client) AdminGatesSatisfy added in v0.28.0

func (c *Client) AdminGatesSatisfy(ctx context.Context, pr int, env, class, target, reason string) error

AdminGatesSatisfy requests the server to satisfy a gate target manually.

func (*Client) AdminGrantsRelease added in v0.28.0

func (c *Client) AdminGrantsRelease(ctx context.Context, pr int, env, class, target, reason string) error

AdminGrantsRelease requests the server to release/revoke a gate target.

func (*Client) ClaimsList added in v0.15.0

func (c *Client) ClaimsList(ctx context.Context, env string) ([]events.Claim, error)

ClaimsList returns the current apply-lock claims for an environment. Returns nil (no error) when the client is disabled.

func (*Client) ClaimsRelease added in v0.15.0

func (c *Client) ClaimsRelease(ctx context.Context, env string, pr int, stack string) error

ClaimsRelease asks the server to release one stack's claim (stack != "") or all of a PR's claims in env (stack == ""). Best-effort; callers may ignore the error.

func (*Client) Enabled

func (c *Client) Enabled() bool

Enabled reports whether a server is configured. When false, every call is a no-op returning nil.

func (*Client) Finalize

func (c *Client) Finalize(ctx context.Context, f events.Finalize) error

Finalize records the terminal plan state (report, gates, moving/failed).

func (*Client) GateCheck

func (c *Client) GateCheck(ctx context.Context, g events.GateCheck) GateVerdict

GateCheck is the apply-time, fail-closed gate pre-check. No server configured ⇒ Satisfied (nothing gates). A transport failure ⇒ Unreachable. A non-2xx ⇒ the verdict named by the response code (an unknown code fails closed as NotSatisfied). 200 ⇒ Satisfied with the leased requester.

func (*Client) GateRevoke

func (c *Client) GateRevoke(ctx context.Context, g events.GateRevoke) error

GateRevoke asks the server to revoke the grants it requested (best-effort post-apply cleanup).

func (*Client) Init

func (c *Client) Init(ctx context.Context, in events.Init) error

Init registers the execution and its changed subgraph.

func (*Client) LogChunk

func (c *Client) LogChunk(ctx context.Context, lc events.LogChunk) error

LogChunk streams a slice of one stack's output to the server (best-effort).

func (*Client) Phase

func (c *Client) Phase(ctx context.Context, p events.PhaseEvent) error

Phase narrates a lifecycle phase transition.

func (*Client) SetAudience added in v0.43.0

func (c *Client) SetAudience(aud string)

SetAudience sets the audience used for this client's token generation (for error reporting).

func (*Client) Update

func (c *Client) Update(ctx context.Context, u events.Update) error

Update ticks a single stack's status, retrying transport errors and 5xx (re-applying a tick is idempotent: the fold just sets the status again).

type GateVerdict added in v0.17.0

type GateVerdict struct {
	Kind      VerdictKind
	Requester string     // leased SA to impersonate; set only when Satisfied
	Code      codes.Code // server-reported code on a non-2xx (empty otherwise)
	Err       error      // underlying error, for logging
}

GateVerdict is the typed result of GateCheck. It replaces error-string matching: callers switch on Kind. Fail-closed by construction — Allowed() is true only for VerdictSatisfied.

func (GateVerdict) Allowed added in v0.17.0

func (v GateVerdict) Allowed() bool

Allowed reports whether the apply may proceed.

type LogPump

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

LogPump tails each stack's on-disk log file and posts newly-appended bytes to the server. It is the parallel-safe path to per-stack logs: terramate's combined `script run` stream interleaves stacks with no per-stack attribution, so by convention each stack's script writes its own file (`<root>/<stack>/<file>`, e.g. via `terraform plan ... 2>&1 | tee tfstackplan.log`) and the pump tails it. All posts are best-effort.

func NewLogPump

func NewLogPump(p logPoster, root, file, execID string) *LogPump

NewLogPump builds a pump that posts via p, reading the file named `file` in each stack dir under root, tagging chunks with execID.

func (*LogPump) Start

func (lp *LogPump) Start(stacks []string) (stop func())

Start begins tailing in the background and returns a stop function that does a final flush and waits for the goroutine to exit. The pump runs in a single goroutine, so offsets need no locking.

type ScriptRunOptions

type ScriptRunOptions struct {
	Script   string // the terramate script name (e.g. "plan")
	Changed  bool   // --changed: only changed stacks
	Parallel int    // --parallel N (0 = terramate default)
	Base     string // -B <ref> for change detection
}

ScriptRunOptions controls `terramate script run`.

type Terramate

type Terramate struct {
	Bin string // terramate binary; defaults to "terramate"
	Dir string // project root (process cwd for every invocation)
}

Terramate shells out to the terramate binary. Dir is the project root: it is set as the process working directory (so asdf resolves the project's .tool-versions and terramate operates on that tree) — no --chdir is used.

func (*Terramate) ChangedStacks

func (t *Terramate) ChangedStacks(ctx context.Context, base string) ([]string, error)

ChangedStacks returns the stacks changed relative to base (empty uses terramate's configured default).

func (*Terramate) List

func (t *Terramate) List(ctx context.Context) ([]string, error)

List returns every stack path in the project.

func (*Terramate) RunGraph

func (t *Terramate) RunGraph(ctx context.Context) ([]events.Edge, error)

RunGraph returns the stack dependency edges (From must run before To), derived from `terramate experimental run-graph -l stack.dir`.

func (*Terramate) ScriptRun

func (t *Terramate) ScriptRun(ctx context.Context, w io.Writer, o ScriptRunOptions) error

ScriptRun runs a terramate script across (changed) stacks, streaming combined output to w. It returns terramate's exit error (so a failed stack fails the run).

func (*Terramate) WhyChanged added in v0.31.0

func (t *Terramate) WhyChanged(ctx context.Context, base string) ([]events.ChangeReason, error)

WhyChanged returns the change reasons for each changed stack relative to base (empty uses terramate's configured default), using terramate list --changed --why.

type VerdictKind added in v0.17.0

type VerdictKind int

VerdictKind is the typed outcome of the apply-time gate pre-check.

const (
	VerdictSatisfied     VerdictKind = iota // apply may proceed (incl. "no server / nothing gates")
	VerdictNotClassified                    // the PR never finalized a plan
	VerdictNotSatisfied                     // a required grant is not yet active (or an unknown blocking code)
	VerdictUnconfirmable                    // gate state could not be freshly confirmed
	VerdictUnreachable                      // the approval server itself is unreachable
)

Jump to

Keyboard shortcuts

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