From 9667e06a035fae111c1a709707250e2e47e96022 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Tue, 18 Dec 2018 17:50:42 -0500 Subject: [PATCH] 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. --- command/meta_backend.go | 10 +++++----- terraform/state.go | 2 +- terraform/state_test.go | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/command/meta_backend.go b/command/meta_backend.go index 4b69aa66a..c34d8ade4 100644 --- a/command/meta_backend.go +++ b/command/meta_backend.go @@ -467,7 +467,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, tfdiags.Di // settings in the configuration files are unchanged. (The only // record we have of CLI overrides is in the settings cache in this // 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) 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{ Type: c.Type, ConfigRaw: json.RawMessage(configJSON), - Hash: cHash, + Hash: uint64(cHash), } 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{ Type: c.Type, ConfigRaw: json.RawMessage(configJSON), - Hash: cHash, + Hash: uint64(cHash), } 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 // have changed by moving a parameter from the config to `-backend-config` // In this case we only need to update the Hash. - if c != nil && s.Backend.Hash != cHash { - s.Backend.Hash = cHash + if c != nil && s.Backend.Hash != uint64(cHash) { + s.Backend.Hash = uint64(cHash) if err := sMgr.WriteState(s); err != nil { diags = diags.Append(err) return nil, diags diff --git a/terraform/state.go b/terraform/state.go index eb8665ef0..2a08cb8ea 100644 --- a/terraform/state.go +++ b/terraform/state.go @@ -656,7 +656,7 @@ func (s *State) String() string { type BackendState struct { Type string `json:"type"` // Backend type 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. diff --git a/terraform/state_test.go b/terraform/state_test.go index c9f24994d..0db6c32e5 100644 --- a/terraform/state_test.go +++ b/terraform/state_test.go @@ -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) { names := []string{ "a",