state

package
v0.6.0-6a Latest Latest
Warning

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

Go to latest
Published: Jun 5, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package state defines the contract a state backend implements.

A backend stores snapshots, advances a current pointer, and arbitrates a per-stack lock. A backend implementation satisfies the Backend interface and joins the fixed set in pkg/backends, where an operator selects it by name. Encryption is a separate concern; see the sibling pkg/sdk/encrypt package.

Index

Constants

View Source
const CurrentFormatVersion = 1

CurrentFormatVersion is the schema version this package reads and writes for snapshots. Older versions error on read.

View Source
const EnvelopeVersion = 1

EnvelopeVersion is the on-disk version of the envelope that wraps a plan or a state snapshot. Bump it when the envelope itself changes; the inner body keeps its own format version, which moves independently.

Variables

View Source
var ErrNoCurrent = errors.New("no current snapshot")

ErrNoCurrent is returned by Backend.Current and Backend.CurrentRev when no snapshot has been written for the stack yet.

Functions

func EncodeSnapshot

func EncodeSnapshot(s *Snapshot) ([]byte, error)

EncodeSnapshot serializes s as pretty-printed JSON with a trailing newline. Map keys are sorted by encoding/json so two encodes of the same snapshot produce identical bytes.

func Open added in v0.5.0

func Open(b []byte, resolveEnc func(*Ref) (encrypt.Encrypter, error)) ([]byte, error)

Open reads an envelope and returns the decrypted inner body. resolveEnc builds an encrypter from the envelope's ref; it receives nil when the envelope omitted the ref.

func Seal added in v0.5.0

func Seal(body []byte, encRef *Ref, enc encrypt.Encrypter) ([]byte, error)

Seal encrypts body with enc and wraps the result in an Envelope ready for atomic write. encRef names the encrypter that produced the ciphertext; pass nil when the reader resolves the encrypter by other means (a state backend already holds its encrypter, so it needs no ref).

Types

type Backend

type Backend interface {
	Stack() string
	Current() (*Snapshot, error)
	CurrentRev() (string, error)
	Get(rev string) (*Snapshot, error)
	Write(snap *Snapshot) (string, error)
	SetCurrent(rev string) error
	List() ([]string, error)
	Delete(rev string) error
	Lock(ctx context.Context) (Lock, error)
	ForceUnlock() error
}

Backend is the contract a state backend satisfies. The runtime reads and writes snapshots through it; concrete implementations decide where the bytes live. Apply and refresh acquire the stack's lock through Lock and release it through the returned Lock value. Plan is read-only and never locks. ForceUnlock is the escape hatch for a leaked lock.

type BackendType

type BackendType struct {
	Name          string
	Description   string
	Configuration *cfg.ConfigurationType
	New           func(config any, factory, stack string, enc encrypt.Encrypter) (Backend, error)
}

BackendType registers a state backend a provider library ships. Configuration describes the schema for the `state:` block fields the operator writes (e.g., path for the local backend, bucket and region for an S3 backend). New is the factory the runtime invokes once it has decoded the configuration against that schema; it returns a ready-to-use Backend.

type Entry

type Entry struct {
	Address string    `json:"address"`
	Type    EntryType `json:"type"`

	Kind             string   `json:"kind,omitempty"`
	SchemaVersion    int      `json:"schema-version,omitempty"`
	SensitiveInputs  []string `json:"sensitive-inputs,omitempty"`
	SensitiveOutputs []string `json:"sensitive-outputs,omitempty"`

	Library     string `json:"library,omitempty"`
	LibraryType string `json:"library-type,omitempty"`

	// Configuration names the library configuration the resource was
	// created against, as "<alias>.<configuration>". It is recorded only
	// when that differs from the import's own default, since destroy and
	// refresh need it to find the right credentials once the resource is
	// no longer described in source.
	Configuration string `json:"configuration,omitempty"`

	TriggerHash string `json:"trigger-hash,omitempty"`

	Inputs    map[string]any `json:"inputs,omitempty"`
	Outputs   map[string]any `json:"outputs,omitempty"`
	DependsOn []string       `json:"depends-on,omitempty"`
}

Entry is one record in a snapshot. Type discriminates the fields used: leaf entries hold a primitive resource's Kind, SchemaVersion, Inputs, and Outputs; library-call entries hold a composite type's Library, LibraryType, and call-site Inputs/Outputs.

SensitiveInputs and SensitiveOutputs name the kebab-case fields whose values came from a sensitive source. Renderers mask the matching entries when printing.

type EntryType

type EntryType string

EntryType discriminates the three records a snapshot can hold.

const (
	EntryLeaf        EntryType = "leaf"
	EntryLibraryCall EntryType = "library-call"
	EntryAction      EntryType = "action"
)

type Envelope added in v0.5.0

type Envelope struct {
	EnvelopeVersion int    `json:"envelope-version"`
	Encrypter       *Ref   `json:"encrypter,omitempty"`
	Ciphertext      []byte `json:"ciphertext"`
}

Envelope is the on-disk container for a plan or a state snapshot. The envelope is plaintext; it names which encrypter sealed the inner body so a reader can build the matching encrypter before opening it. The Encrypter ref holds only non-secret configuration (env-var name, KMS key id, region). Key material is never on disk; the operator must have it available through the encrypter's own channel.

type FactoryInfo

type FactoryInfo struct {
	Name            string `json:"name"`
	Version         string `json:"version"`
	ContentRevision string `json:"content-revision"`
}

FactoryInfo identifies the stack a snapshot belongs to. ContentRevision is the content-addressable hash the binary was compiled with.

type Lock

type Lock interface {
	Unlock() error
}

Lock is a held exclusion on one stack. Callers must invoke Unlock; a leaked lock blocks future apply and refresh runs until an operator calls ForceUnlock.

type Ref added in v0.5.0

type Ref struct {
	Name string         `json:"name"`
	Body map[string]any `json:"body,omitempty"`
}

Ref names an entry in the fixed backend or encrypter registry. Name is the bare name an operator selects with @backend or @key-source; Body is the operator-provided configuration the resolver decodes against that entry's schema.

A plan file records a Backend ref so apply can reconstruct the same backend without re-reading config.ub, and an Encrypter ref rides in the envelope so a reader can build the encrypter before opening the body.

type Snapshot

type Snapshot struct {
	FormatVersion int            `json:"format-version"`
	Factory       FactoryInfo    `json:"factory"`
	Stack         string         `json:"stack"`
	GeneratedAt   time.Time      `json:"generated-at"`
	Entries       []*Entry       `json:"entries"`
	Outputs       map[string]any `json:"outputs,omitempty"`
}

Snapshot is the in-memory record of one state file. The runtime reads the current snapshot at the start of plan or apply, and writes a fresh one after each successful resource action.

func DecodeSnapshot

func DecodeSnapshot(b []byte) (*Snapshot, error)

DecodeSnapshot parses a snapshot from JSON bytes.

func NewSnapshot

func NewSnapshot(factory FactoryInfo, stack string) *Snapshot

NewSnapshot returns an empty snapshot at the current schema version.

func (*Snapshot) Find

func (s *Snapshot) Find(address string) *Entry

Find returns the entry at address, or nil.

func (*Snapshot) Validate

func (s *Snapshot) Validate() error

Validate checks every entry's discriminator and required fields, and rejects duplicate addresses within a snapshot.

Jump to

Keyboard shortcuts

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