github.com/eliastor/durgaform@v0.0.0-20220816172711-d0ab2d17673e/internal/states/statemgr/persistent.go (about)

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