diff --git a/command/push.go b/command/push.go index 8625a0e29..a02553c21 100644 --- a/command/push.go +++ b/command/push.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/hashicorp/terraform/remote" + "github.com/hashicorp/terraform/state" ) type PushCommand struct { @@ -22,31 +22,52 @@ func (c *PushCommand) Run(args []string) int { return 1 } - // Check for a remote state file - local, _, err := remote.ReadLocalState() + // Read out our state + s, err := c.State() if err != nil { - c.Ui.Error(fmt.Sprintf("%s", err)) + c.Ui.Error(fmt.Sprintf("Failed to read state: %s", err)) return 1 } - if local == nil || local.Remote == nil { + localState := s.State() + + // If remote state isn't enabled, it is a problem. + if !localState.IsRemote() { c.Ui.Error("Remote state not enabled!") return 1 } - // Attempt to push the state - change, err := remote.PushState(local.Remote, force) - if err != nil { - c.Ui.Error(fmt.Sprintf("Failed to push state: %v", err)) + // We need the CacheState structure in order to do anything + var cache *state.CacheState + if bs, ok := s.(*state.BackupState); ok { + if cs, ok := bs.Real.(*state.CacheState); ok { + cache = cs + } + } + if cache == nil { + c.Ui.Error(fmt.Sprintf( + "Failed to extract internal CacheState from remote state.\n" + + "This is an internal error, please report it as a bug.")) return 1 } - // Use an error exit code if the update was not a success - if !change.SuccessfulPush() { - c.Ui.Error(fmt.Sprintf("%s", change)) + // Refresh the cache state + if err := cache.Cache.RefreshState(); err != nil { + c.Ui.Error(fmt.Sprintf( + "Failed to refresh from remote state: %s", err)) return 1 - } else { - c.Ui.Output(fmt.Sprintf("%s", change)) } + + // Write it to the real storage + remote := cache.Durable + if err := remote.WriteState(cache.Cache.State()); err != nil { + c.Ui.Error(fmt.Sprintf("Error writing state: %s", err)) + return 1 + } + if err := remote.PersistState(); err != nil { + c.Ui.Error(fmt.Sprintf("Error saving state: %s", err)) + return 1 + } + return 0 } diff --git a/command/push_test.go b/command/push_test.go index a9709d829..59c1c834e 100644 --- a/command/push_test.go +++ b/command/push_test.go @@ -1,10 +1,10 @@ package command import ( - "bytes" + "os" + "path/filepath" "testing" - "github.com/hashicorp/terraform/remote" "github.com/hashicorp/terraform/terraform" "github.com/mitchellh/cli" ) @@ -41,10 +41,19 @@ func TestPush_local(t *testing.T) { s.Remote = conf // Store the local state - buf := bytes.NewBuffer(nil) - terraform.WriteState(s, buf) - remote.EnsureDirectory() - remote.Persist(buf) + statePath := filepath.Join(tmp, DefaultDataDir, DefaultStateFilename) + if err := os.MkdirAll(filepath.Dir(statePath), 0755); err != nil { + t.Fatalf("err: %s", err) + } + f, err := os.Create(statePath) + if err != nil { + t.Fatalf("err: %s", err) + } + err = terraform.WriteState(s, f) + f.Close() + if err != nil { + t.Fatalf("err: %s", err) + } ui := new(cli.MockUi) c := &PushCommand{