states/statemgr: don't panic if no state file is present on first write
This commit is contained in:
parent
5731703de5
commit
03e6771536
|
@ -123,6 +123,13 @@ func (s *Filesystem) WriteState(state *states.State) error {
|
|||
// writing to a temp file on the same filesystem, and renaming the file over
|
||||
// the original.
|
||||
|
||||
if s.readFile == nil {
|
||||
err := s.RefreshState()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
defer s.mutex()()
|
||||
|
||||
// We'll try to write our backup first, so we can be sure we've created
|
||||
|
@ -150,6 +157,9 @@ func (s *Filesystem) WriteState(state *states.State) error {
|
|||
defer s.stateFileOut.Sync()
|
||||
|
||||
s.file = s.file.DeepCopy()
|
||||
if s.file == nil {
|
||||
s.file = NewStateFile()
|
||||
}
|
||||
s.file.State = state.DeepCopy()
|
||||
|
||||
if _, err := s.stateFileOut.Seek(0, os.SEEK_SET); err != nil {
|
||||
|
@ -164,7 +174,7 @@ func (s *Filesystem) WriteState(state *states.State) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
if !statefile.StatesMarshalEqual(s.file.State, s.readFile.State) {
|
||||
if s.readFile == nil || !statefile.StatesMarshalEqual(s.file.State, s.readFile.State) {
|
||||
s.file.Serial++
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package statemgr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
uuid "github.com/hashicorp/go-uuid"
|
||||
|
||||
"github.com/hashicorp/terraform/states/statefile"
|
||||
"github.com/hashicorp/terraform/version"
|
||||
)
|
||||
|
||||
// NewLineage generates a new lineage identifier string. A lineage identifier
|
||||
// is an opaque string that is intended to be unique in space and time, chosen
|
||||
// when state is recorded at a location for the first time and then preserved
|
||||
// afterwards to allow Terraform to recognize when one state snapshot is a
|
||||
// predecessor or successor of another.
|
||||
func NewLineage() string {
|
||||
lineage, err := uuid.GenerateUUID()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Failed to generate lineage: %v", err))
|
||||
}
|
||||
return lineage
|
||||
}
|
||||
|
||||
// NewStateFile creates a new statefile.File object, with a newly-minted
|
||||
// lineage identifier and serial 0, and returns a pointer to it.
|
||||
func NewStateFile() *statefile.File {
|
||||
return &statefile.File{
|
||||
Lineage: NewLineage(),
|
||||
TerraformVersion: version.SemVer,
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue