diff --git a/command/remote_pull_test.go b/command/remote_pull_test.go index 94b52ce2b..a867877e1 100644 --- a/command/remote_pull_test.go +++ b/command/remote_pull_test.go @@ -80,15 +80,6 @@ func testRemoteState(t *testing.T, s *terraform.State, c int) (*terraform.Remote var b64md5 string buf := bytes.NewBuffer(nil) - if s != nil { - enc := json.NewEncoder(buf) - if err := enc.Encode(s); err != nil { - t.Fatalf("err: %v", err) - } - md5 := md5.Sum(buf.Bytes()) - b64md5 = base64.StdEncoding.EncodeToString(md5[:16]) - } - cb := func(resp http.ResponseWriter, req *http.Request) { if req.Method == "PUT" { resp.WriteHeader(c) @@ -98,13 +89,28 @@ func testRemoteState(t *testing.T, s *terraform.State, c int) (*terraform.Remote resp.WriteHeader(404) return } + resp.Header().Set("Content-MD5", b64md5) resp.Write(buf.Bytes()) } + srv := httptest.NewServer(http.HandlerFunc(cb)) remote := &terraform.RemoteState{ Type: "http", Config: map[string]string{"address": srv.URL}, } + + if s != nil { + // Set the remote data + s.Remote = remote + + enc := json.NewEncoder(buf) + if err := enc.Encode(s); err != nil { + t.Fatalf("err: %v", err) + } + md5 := md5.Sum(buf.Bytes()) + b64md5 = base64.StdEncoding.EncodeToString(md5[:16]) + } + return remote, srv } diff --git a/command/state.go b/command/state.go index 20cb4c1e4..da34cfb2f 100644 --- a/command/state.go +++ b/command/state.go @@ -231,10 +231,20 @@ func remoteState( "Error reloading remote state: {{err}}", err) } switch cache.RefreshResult() { + // All the results below can be safely ignored since it means the + // pull was successful in some way. Noop = nothing happened. + // Init = both are empty. UpdateLocal = local state was older and + // updated. + // + // We don't have to do anything, the pull was successful. case state.CacheRefreshNoop: case state.CacheRefreshInit: - case state.CacheRefreshLocalNewer: case state.CacheRefreshUpdateLocal: + + // Our local state has a higher serial number than remote, so we + // want to explicitly sync the remote side with our local so that + // the remote gets the latest serial number. + case state.CacheRefreshLocalNewer: // Write our local state out to the durable storage to start. if err := cache.WriteState(local); err != nil { return nil, errwrap.Wrapf( diff --git a/terraform/state.go b/terraform/state.go index 1a1a28bea..258f3f034 100644 --- a/terraform/state.go +++ b/terraform/state.go @@ -344,6 +344,10 @@ func (r *RemoteState) Equals(other *RemoteState) bool { return true } +func (r *RemoteState) GoString() string { + return fmt.Sprintf("*%#v", *r) +} + // ModuleState is used to track all the state relevant to a single // module. Previous to Terraform 0.3, all state belonged to the "root" // module.