terraform: first pass at state file upgrades

This commit is contained in:
Armon Dadgar 2014-09-17 18:24:53 -07:00
parent 18a91a87c9
commit 4db7282072
1 changed files with 45 additions and 4 deletions

View File

@ -6,6 +6,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"log"
"reflect" "reflect"
"sort" "sort"
@ -487,13 +488,11 @@ func ReadState(src io.Reader) (*State, error) {
} }
if string(start) == stateFormatMagic { if string(start) == stateFormatMagic {
// Read the old state // Read the old state
_, err := ReadStateV1(buf) old, err := ReadStateV1(buf)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return upgradeV1State(old)
// TODO: Handle V1 upgade
panic("Old state file upgrade not supported")
} }
// Otherwise, must be V2 // Otherwise, must be V2
@ -514,3 +513,45 @@ func WriteState(d *State, dst io.Writer) error {
} }
return nil return nil
} }
// upgradeV1State is used to upgrade a V1 state representation
// into a proper State representation.
func upgradeV1State(old *StateV1) (*State, error) {
s := &State{}
s.init()
// Old format had no modules, so we migrate everything
// directly into the root module.
root := s.RootModule()
// Copy the outputs
root.Outputs = old.Outputs
// Upgrade the resources
for id, rs := range old.Resources {
newRs := &ResourceState{
Type: rs.Type,
}
root.Resources[id] = newRs
// Migrate to an instance state
instance := &InstanceState{
ID: rs.ID,
Attributes: rs.Attributes,
}
// Check if this is the primary or tainted instance
if _, ok := old.Tainted[id]; ok {
newRs.Tainted = append(newRs.Tainted, instance)
} else {
newRs.Primary = instance
}
// Warn if the resource uses Extra, as there is
// no upgrade path for this! Now totally deprecated.
if len(rs.Extra) > 0 {
log.Printf("[WARN] Resource %s uses deprecated attribute storage, state file upgrade may be incomplete.")
}
}
return s, nil
}