decode backend hash as uint64

Older versions of terraform could save the backend hash number in a
value larger than an int.

While we could conditionally decode the state into an intermediary data
structure for upgrade, or detect the specific decode error and modify
the json, it seems simpler to just decode into the most flexible value
for now, which is a uint64.
This commit is contained in:
James Bardin 2018-12-18 17:50:42 -05:00
parent 9a34f14c60
commit 9667e06a03
3 changed files with 20 additions and 6 deletions

View File

@ -467,7 +467,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di
// settings in the configuration files are unchanged. (The only // settings in the configuration files are unchanged. (The only
// record we have of CLI overrides is in the settings cache in this // record we have of CLI overrides is in the settings cache in this
// case, so we have no other source to compare with. // case, so we have no other source to compare with.
if !opts.Init && cHash == s.Backend.Hash { if !opts.Init && uint64(cHash) == s.Backend.Hash {
log.Printf("[TRACE] Meta.Backend: using already-initialized, unchanged %q backend configuration", c.Type) log.Printf("[TRACE] Meta.Backend: using already-initialized, unchanged %q backend configuration", c.Type)
return m.backend_C_r_S_unchanged(c, cHash, sMgr) return m.backend_C_r_S_unchanged(c, cHash, sMgr)
} }
@ -714,7 +714,7 @@ func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *state.LocalSta
s.Backend = &terraform.BackendState{ s.Backend = &terraform.BackendState{
Type: c.Type, Type: c.Type,
ConfigRaw: json.RawMessage(configJSON), ConfigRaw: json.RawMessage(configJSON),
Hash: cHash, Hash: uint64(cHash),
} }
if err := sMgr.WriteState(s); err != nil { if err := sMgr.WriteState(s); err != nil {
@ -857,7 +857,7 @@ func (m *Meta) backend_C_r_S_changed(c *configs.Backend, cHash int, sMgr *state.
s.Backend = &terraform.BackendState{ s.Backend = &terraform.BackendState{
Type: c.Type, Type: c.Type,
ConfigRaw: json.RawMessage(configJSON), ConfigRaw: json.RawMessage(configJSON),
Hash: cHash, Hash: uint64(cHash),
} }
if err := sMgr.WriteState(s); err != nil { if err := sMgr.WriteState(s); err != nil {
@ -886,8 +886,8 @@ func (m *Meta) backend_C_r_S_unchanged(c *configs.Backend, cHash int, sMgr *stat
// it's possible for a backend to be unchanged, and the config itself to // it's possible for a backend to be unchanged, and the config itself to
// have changed by moving a parameter from the config to `-backend-config` // have changed by moving a parameter from the config to `-backend-config`
// In this case we only need to update the Hash. // In this case we only need to update the Hash.
if c != nil && s.Backend.Hash != cHash { if c != nil && s.Backend.Hash != uint64(cHash) {
s.Backend.Hash = cHash s.Backend.Hash = uint64(cHash)
if err := sMgr.WriteState(s); err != nil { if err := sMgr.WriteState(s); err != nil {
diags = diags.Append(err) diags = diags.Append(err)
return nil, diags return nil, diags

View File

@ -656,7 +656,7 @@ func (s *State) String() string {
type BackendState struct { type BackendState struct {
Type string `json:"type"` // Backend type Type string `json:"type"` // Backend type
ConfigRaw json.RawMessage `json:"config"` // Backend raw config ConfigRaw json.RawMessage `json:"config"` // Backend raw config
Hash int `json:"hash"` // Hash of portion of configuration from config files Hash uint64 `json:"hash"` // Hash of portion of configuration from config files
} }
// Empty returns true if BackendState has no state. // Empty returns true if BackendState has no state.

View File

@ -1561,6 +1561,20 @@ func TestReadState_pruneDependencies(t *testing.T) {
} }
} }
func TestReadState_bigHash(t *testing.T) {
expected := uint64(14885267135666261723)
s := strings.NewReader(`{"version": 3, "backend":{"hash":14885267135666261723}}`)
actual, err := ReadState(s)
if err != nil {
t.Fatal(err)
}
if actual.Backend.Hash != expected {
t.Fatalf("expected backend hash %d, got %d", expected, actual.Backend.Hash)
}
}
func TestResourceNameSort(t *testing.T) { func TestResourceNameSort(t *testing.T) {
names := []string{ names := []string{
"a", "a",