1package statemgr
2
3import (
4	version "github.com/hashicorp/go-version"
5)
6
7// Persistent is a union of the Refresher and Persistent interfaces, for types
8// that deal with persistent snapshots.
9//
10// Persistent snapshots are ones that are retained in storage that will
11// outlive a particular Terraform process, and are shared with other Terraform
12// processes that have a similarly-configured state manager.
13//
14// A manager may also choose to retain historical persistent snapshots, but
15// that is an implementation detail and not visible via this API.
16type Persistent interface {
17	Refresher
18	Persister
19}
20
21// Refresher is the interface for managers that can read snapshots from
22// persistent storage.
23//
24// Refresher is usually implemented in conjunction with Reader, with
25// RefreshState copying the latest persistent snapshot into the latest
26// transient snapshot.
27//
28// For a type that implements both Refresher and Persister, RefreshState must
29// return the result of the most recently completed successful call to
30// PersistState, unless another concurrently-running process has persisted
31// another snapshot in the mean time.
32//
33// The Refresher implementation must guarantee that the snapshot is read
34// from persistent storage in a way that is safe under concurrent calls to
35// PersistState that may be happening in other processes.
36type Refresher interface {
37	// RefreshState retrieves a snapshot of state from persistent storage,
38	// returning an error if this is not possible.
39	//
40	// Types that implement RefreshState generally also implement a State
41	// method that returns the result of the latest successful refresh.
42	//
43	// Since only a subset of the data in a state is included when persisting,
44	// a round-trip through PersistState and then RefreshState will often
45	// return only a subset of what was written. Callers must assume that
46	// ephemeral portions of the state may be unpopulated after calling
47	// RefreshState.
48	RefreshState() error
49}
50
51// Persister is the interface for managers that can write snapshots to
52// persistent storage.
53//
54// Persister is usually implemented in conjunction with Writer, with
55// PersistState copying the latest transient snapshot to be the new latest
56// persistent snapshot.
57//
58// A Persister implementation must detect updates made by other processes
59// that may be running concurrently and avoid destroying those changes. This
60// is most commonly achieved by making use of atomic write capabilities on
61// the remote storage backend in conjunction with book-keeping with the
62// Serial and Lineage fields in the standard state file formats.
63type Persister interface {
64	PersistState() error
65}
66
67// PersistentMeta is an optional extension to Persistent that allows inspecting
68// the metadata associated with the snapshot that was most recently either
69// read by RefreshState or written by PersistState.
70type PersistentMeta interface {
71	// StateSnapshotMeta returns metadata about the state snapshot most
72	// recently created either by a call to PersistState or read by a call
73	// to RefreshState.
74	//
75	// If no persistent snapshot is yet available in the manager then
76	// the return value is meaningless. This method is primarily available
77	// for testing and logging purposes, and is of little use otherwise.
78	StateSnapshotMeta() SnapshotMeta
79}
80
81// SnapshotMeta contains metadata about a persisted state snapshot.
82//
83// This metadata is usually (but not necessarily) included as part of the
84// "header" of a state file, which is then written to a raw blob storage medium
85// by a persistent state manager.
86//
87// Not all state managers will have useful values for all fields in this
88// struct, so SnapshotMeta values are of little use beyond testing and logging
89// use-cases.
90type SnapshotMeta struct {
91	// Lineage and Serial can be used to understand the relationships between
92	// snapshots.
93	//
94	// If two snapshots both have an identical, non-empty Lineage
95	// then the one with the higher Serial is newer than the other.
96	// If the Lineage values are different or empty then the two snapshots
97	// are unrelated and cannot be compared for relative age.
98	Lineage string
99	Serial  uint64
100
101	// TerraformVersion is the number of the version of Terraform that created
102	// the snapshot.
103	TerraformVersion *version.Version
104}
105