github.com/jrperritt/terraform@v0.1.1-0.20170525065507-96f391dafc38/state/backup.go (about) 1 package state 2 3 import "github.com/hashicorp/terraform/terraform" 4 5 // BackupState wraps a State that backs up the state on the first time that 6 // a WriteState or PersistState is called. 7 // 8 // If Path exists, it will be overwritten. 9 type BackupState struct { 10 Real State 11 Path string 12 13 done bool 14 } 15 16 func (s *BackupState) State() *terraform.State { 17 return s.Real.State() 18 } 19 20 func (s *BackupState) RefreshState() error { 21 return s.Real.RefreshState() 22 } 23 24 func (s *BackupState) WriteState(state *terraform.State) error { 25 if !s.done { 26 if err := s.backup(); err != nil { 27 return err 28 } 29 } 30 31 return s.Real.WriteState(state) 32 } 33 34 func (s *BackupState) PersistState() error { 35 if !s.done { 36 if err := s.backup(); err != nil { 37 return err 38 } 39 } 40 41 return s.Real.PersistState() 42 } 43 44 func (s *BackupState) Lock(info *LockInfo) (string, error) { 45 return s.Real.Lock(info) 46 } 47 48 func (s *BackupState) Unlock(id string) error { 49 return s.Real.Unlock(id) 50 } 51 52 func (s *BackupState) backup() error { 53 state := s.Real.State() 54 if state == nil { 55 if err := s.Real.RefreshState(); err != nil { 56 return err 57 } 58 59 state = s.Real.State() 60 } 61 62 // LocalState.WriteState ensures that a file always exists for locking 63 // purposes, but we don't need a backup or lock if the state is empty, so 64 // skip this with a nil state. 65 if state != nil { 66 ls := &LocalState{Path: s.Path} 67 if err := ls.WriteState(state); err != nil { 68 return err 69 } 70 } 71 72 s.done = true 73 return nil 74 }