github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/states/statefile/file.go (about)

     1  package statefile
     2  
     3  import (
     4  	"fmt"
     5  
     6  	version "github.com/hashicorp/go-version"
     7  
     8  	"github.com/hashicorp/terraform/states"
     9  	tfversion "github.com/hashicorp/terraform/version"
    10  )
    11  
    12  // File is the in-memory representation of a state file. It includes the state
    13  // itself along with various metadata used to track changing state files for
    14  // the same configuration over time.
    15  type File struct {
    16  	// TerraformVersion is the version of Terraform that wrote this state file.
    17  	TerraformVersion *version.Version
    18  
    19  	// Serial is incremented on any operation that modifies
    20  	// the State file. It is used to detect potentially conflicting
    21  	// updates.
    22  	Serial uint64
    23  
    24  	// Lineage is set when a new, blank state file is created and then
    25  	// never updated. This allows us to determine whether the serials
    26  	// of two states can be meaningfully compared.
    27  	// Apart from the guarantee that collisions between two lineages
    28  	// are very unlikely, this value is opaque and external callers
    29  	// should only compare lineage strings byte-for-byte for equality.
    30  	Lineage string
    31  
    32  	// State is the actual state represented by this file.
    33  	State *states.State
    34  }
    35  
    36  func New(state *states.State, lineage string, serial uint64) *File {
    37  	// To make life easier on callers, we'll accept a nil state here and just
    38  	// allocate an empty one, which is required for this file to be successfully
    39  	// written out.
    40  	if state == nil {
    41  		state = states.NewState()
    42  	}
    43  
    44  	return &File{
    45  		TerraformVersion: tfversion.SemVer,
    46  		State:            state,
    47  		Lineage:          lineage,
    48  		Serial:           serial,
    49  	}
    50  }
    51  
    52  // DeepCopy is a convenience method to create a new File object whose state
    53  // is a deep copy of the receiver's, as implemented by states.State.DeepCopy.
    54  func (f *File) DeepCopy() *File {
    55  	if f == nil {
    56  		return nil
    57  	}
    58  	return &File{
    59  		TerraformVersion: f.TerraformVersion,
    60  		Serial:           f.Serial,
    61  		Lineage:          f.Lineage,
    62  		State:            f.State.DeepCopy(),
    63  	}
    64  }
    65  
    66  func (f *File) CheckTerraformVersion() error {
    67  	if f.TerraformVersion != nil && f.TerraformVersion.GreaterThan(tfversion.SemVer) {
    68  		return fmt.Errorf(
    69  			"state snapshot was created by Terraform v%s, which is newer than current v%s; upgrade to Terraform v%s or greater to work with this state",
    70  			f.TerraformVersion,
    71  			tfversion.SemVer,
    72  			f.TerraformVersion,
    73  		)
    74  	}
    75  	return nil
    76  }