state

package
v1.12.0 Latest Latest
Warning

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

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

Documentation

Overview

Package state persists the snapshot that makes a fire reversible.

The ordering rule is absolute: the snapshot is written, and read back, before a single API call changes anything. If the write fails the fire is abandoned. An account that is still expensive is a problem; an account that is stopped with no record of how to start it is an outage of unknown length.

S3 is the intended home — it is in the never-touch set, so the kill switch cannot destroy its own restore — with a local copy alongside for the case where the reason you are firing is that something is wrong with the account.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotFound = errors.New("no snapshot with that plan id")

ErrNotFound is returned when a plan id has no snapshot. Callers match on it to tell "nothing to restore" from "the store is broken".

Functions

func From

func From(p model.Plan) model.Snapshot

From converts a plan into the record that will make it reversible.

func ParseURI

func ParseURI(uri string) (bucket, prefix string, ok bool)

ParseURI accepts s3://bucket/prefix.

func PutVerified

func PutVerified(ctx context.Context, s Store, snap model.Snapshot) error

PutVerified writes and reads back, comparing what returned against what was sent. A store that accepts a write and loses it is the one failure this tool cannot survive, and it is cheap to rule out.

Types

type Local

type Local struct{ Dir string }

Local is the on-disk store. It is always present, even when a durable store is configured: a laptop that loses its network mid-incident still has the record of what it stopped.

func (Local) Describe

func (l Local) Describe() string

Describe names this store in errors and in warnings.

func (Local) Get

func (l Local) Get(ctx context.Context, planID string) (model.Snapshot, error)

Get reads one snapshot. A corrupt file is reported as corrupt rather than as missing: those need different reactions.

func (Local) List

func (l Local) List(ctx context.Context) ([]model.Snapshot, error)

List returns the snapshots in the directory, newest first. A missing directory is an empty list, not an error: nothing has been fired yet.

func (Local) Put

func (l Local) Put(ctx context.Context, s model.Snapshot) error

Put writes the snapshot atomically -- temp file, sync, rename -- so a crash mid-write cannot leave a truncated record where a complete one used to be.

type Multi

type Multi struct{ Stores []Store }

Multi writes to every store and requires all of them to succeed, so the local copy and the durable copy cannot disagree about what was stopped.

func (Multi) Describe

func (m Multi) Describe() string

Describe names every underlying store, so an error says which of them the run was actually talking to.

func (Multi) Get

func (m Multi) Get(ctx context.Context, planID string) (model.Snapshot, error)

Get reads from the first store that has it. Order matters: the durable store should come first, since the local one may be on a machine that was rebuilt.

func (Multi) List

func (m Multi) List(ctx context.Context) ([]model.Snapshot, error)

List merges every store's listing, keeping the freshest copy of each plan. A store that cannot be read is skipped: half a listing beats none when someone is looking for what to restore.

func (Multi) Put

func (m Multi) Put(ctx context.Context, s model.Snapshot) error

Put writes to every store and fails if any of them does: a durable copy and a local copy that disagree are worse than one copy.

type S3

type S3 struct {
	Client *s3.Client
	Bucket string
	Prefix string
}

S3 is the durable home for snapshots.

S3 is in the never-touch set, which is not a coincidence: the kill switch must not be able to destroy its own restore record. Versioning on the bucket is worth turning on for the same reason.

func (S3) Describe

func (s S3) Describe() string

Describe names this store in errors and in the warning printed when there is no durable one.

func (S3) Get

func (s S3) Get(ctx context.Context, planID string) (model.Snapshot, error)

Get reads one snapshot. A missing object and a denied one both come back as ErrNotFound: from a restore's point of view the record is not there.

func (S3) List

func (s S3) List(ctx context.Context) ([]model.Snapshot, error)

List returns the snapshots under the prefix, newest first. An object that cannot be read is skipped rather than failing the listing -- one corrupt record must not hide the others.

func (S3) Put

func (s S3) Put(ctx context.Context, snap model.Snapshot) error

Put writes the snapshot, server-side encrypted. The bucket is in the never-touch set, so the kill switch cannot destroy its own restore record.

type Store

type Store interface {
	Put(ctx context.Context, s model.Snapshot) error
	Get(ctx context.Context, planID string) (model.Snapshot, error)
	List(ctx context.Context) ([]model.Snapshot, error)
	Describe() string
}

Store is where the record that makes a fire reversible lives. Every implementation must survive the machine that wrote it: a restore usually happens somewhere else, later, under pressure.

func Build added in v1.10.0

func Build(s3c *s3.Client, uri, localDir string) (Store, error)

Build assembles the store a run should use: the durable one first, so a rebuilt laptop still finds the record, with the local directory behind it.

localDir may be empty, which is the Lambda's case — there is no durable filesystem there, and a local copy that dies with the execution environment would be a restore record that does not exist.

Jump to

Keyboard shortcuts

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