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