@ -39,6 +39,10 @@ type LocalState struct {
// the file handle corresponding to PathOut
stateFileOut * os . File
// created is set to tru if stateFileOut didn't exist before we created it.
// This is mostly so we can clean up emtpy files during tests, but doesn't
// hurt to remove file we never wrote to.
created bool
state * terraform . State
readState * terraform . State
@ -75,8 +79,26 @@ func (s *LocalState) Lock(reason string) error {
}
func ( s * LocalState ) Unlock ( ) error {
// we can't be locked if we don't have a file
if s . stateFileOut == nil {
return nil
}
os . Remove ( s . lockInfoPath ( ) )
return s . unlock ( )
fileName := s . stateFileOut . Name ( )
unlockErr := s . unlock ( )
s . stateFileOut . Close ( )
s . stateFileOut = nil
// clean up the state file if we created it an never wrote to it
stat , err := os . Stat ( fileName )
if err == nil && stat . Size ( ) == 0 && s . created {
os . Remove ( fileName )
}
return unlockErr
}
// Open the state file, creating the directories and file as needed.
@ -85,26 +107,23 @@ func (s *LocalState) createStateFiles() error {
s . PathOut = s . Path
}
f , err := createFileAndDirs ( s . PathOut )
if err != nil {
return err
// yes this could race, but we only use it to clean up empty files
if _, err := os . Stat ( s . PathOut ) ; os . IsNotExist ( err ) {
s . created = true
}
s . stateFileOut = f
return nil
}
func createFileAndDirs ( path string ) ( * os . File , error ) {
// Create all the directories
if err := os . MkdirAll ( filepath . Dir ( path ) , 0755 ) ; err != nil {
return nil , err
if err := os . MkdirAll ( filepath . Dir ( s . PathOut ) , 0755 ) ; err != nil {
return err
}
f , err := os . OpenFile ( path , os . O_RDWR | os . O_CREATE , 0666 )
f , err := os . OpenFile ( s. PathOut , os . O_RDWR | os . O_CREATE , 0666 )
if err != nil {
return nil , err
return err
}
return f , nil
s . stateFileOut = f
return nil
}
// WriteState for LocalState always persists the state as well.