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
- Variables
- func EncodeSnapshot(s *Snapshot) ([]byte, error)
- func Open(b []byte, resolveEnc func(*Ref) (encrypt.Encrypter, error)) ([]byte, error)
- func Seal(body []byte, enc encrypt.Encrypter) ([]byte, error)
- type Backend
- type BackendType
- type Entry
- type EntryType
- type Envelope
- type FactoryInfo
- type Lock
- type Ref
- type Selector
- type Snapshot
Constants ¶
const CurrentFormatVersion = 1
CurrentFormatVersion is the schema version this package reads and writes for snapshots. Older versions error on read.
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 ¶
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 ¶
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
Open reads an envelope and returns the decrypted inner body. resolveEnc builds or selects an encrypter from the envelope's ref; it receives nil when the envelope has no encrypter 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.Registration
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:"entry-kind"`
Kind string `json:"node-kind,omitempty"`
Selector *Selector `json:"selector,omitempty"`
SchemaVersion int `json:"schema-version,omitempty"`
SensitiveInputs []string `json:"sensitive-inputs,omitempty"`
SensitiveOutputs []string `json:"sensitive-outputs,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 is the entry discriminator. Kind is the graph node kind for resource, data, action, and composite entries. Selector names the implementation used by that entry.
SensitiveInputs and SensitiveOutputs name the kebab-case fields whose values came from a sensitive source. Renderers mask the matching entries when printing.
func (*Entry) MarshalJSON ¶
func (*Entry) UnmarshalJSON ¶
type EntryType ¶
type EntryType string
EntryType discriminates the records a snapshot can hold.
const ( EntryLeaf EntryType = "leaf" EntryLibraryCall EntryType = "library-call" EntryAction EntryType = "action" // EntryData records what a data source read during the last // apply. Nothing in the world belongs to it, so removing the node // removes the record without a destroy. EntryData EntryType = "data" )
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; its Encrypter ref records which key source sealed the inner body and the non-secret configuration (env-var name, KMS key ARN, region) needed to decrypt it, so a state file found long after the config that wrote it still says how to get back to plaintext. Key material is never on disk; the operator must have it available through the encrypter's own channel.
The envelope is not authenticated, so a reader with its own configuration must not let the file choose the key: state backends decrypt with the encrypter resolved from the stack file and treat the recorded ref as information for operators and error messages.
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
Ref names an entry in the fixed backend or encrypter registry. Name is the bare state or encryption selector from the stack file; Body is the 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 the stack file, and every envelope records an Encrypter ref naming the key source that sealed it.
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 ¶
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.