github.com/jrasell/terraform@v0.6.17-0.20160523115548-2652f5232949/state/local.go (about) 1 package state 2 3 import ( 4 "os" 5 "path/filepath" 6 7 "github.com/hashicorp/terraform/terraform" 8 ) 9 10 // LocalState manages a state storage that is local to the filesystem. 11 type LocalState struct { 12 // Path is the path to read the state from. PathOut is the path to 13 // write the state to. If PathOut is not specified, Path will be used. 14 // If PathOut already exists, it will be overwritten. 15 Path string 16 PathOut string 17 18 state *terraform.State 19 readState *terraform.State 20 written bool 21 } 22 23 // SetState will force a specific state in-memory for this local state. 24 func (s *LocalState) SetState(state *terraform.State) { 25 s.state = state 26 s.readState = state 27 } 28 29 // StateReader impl. 30 func (s *LocalState) State() *terraform.State { 31 return s.state.DeepCopy() 32 } 33 34 // WriteState for LocalState always persists the state as well. 35 // 36 // StateWriter impl. 37 func (s *LocalState) WriteState(state *terraform.State) error { 38 s.state = state 39 40 path := s.PathOut 41 if path == "" { 42 path = s.Path 43 } 44 45 // If we don't have any state, we actually delete the file if it exists 46 if state == nil { 47 err := os.Remove(path) 48 if err != nil && os.IsNotExist(err) { 49 return nil 50 } 51 52 return err 53 } 54 55 // Create all the directories 56 if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { 57 return err 58 } 59 60 f, err := os.Create(path) 61 if err != nil { 62 return err 63 } 64 defer f.Close() 65 66 s.state.IncrementSerialMaybe(s.readState) 67 s.readState = s.state 68 69 if err := terraform.WriteState(s.state, f); err != nil { 70 return err 71 } 72 73 s.written = true 74 return nil 75 } 76 77 // PersistState for LocalState is a no-op since WriteState always persists. 78 // 79 // StatePersister impl. 80 func (s *LocalState) PersistState() error { 81 return nil 82 } 83 84 // StateRefresher impl. 85 func (s *LocalState) RefreshState() error { 86 // If we've never loaded before, read from Path, otherwise we 87 // read from PathOut. 88 path := s.Path 89 if s.written && s.PathOut != "" { 90 path = s.PathOut 91 } 92 93 f, err := os.Open(path) 94 if err != nil { 95 // It is okay if the file doesn't exist, we treat that as a nil state 96 if !os.IsNotExist(err) { 97 return err 98 } 99 100 f = nil 101 } 102 103 var state *terraform.State 104 if f != nil { 105 defer f.Close() 106 state, err = terraform.ReadState(f) 107 if err != nil { 108 return err 109 } 110 } 111 112 s.state = state 113 s.readState = state 114 return nil 115 }