diff --git a/command/state_meta.go b/command/state_meta.go index c1af8b82e..7b6e13694 100644 --- a/command/state_meta.go +++ b/command/state_meta.go @@ -2,6 +2,8 @@ package command import ( "errors" + "fmt" + "time" "github.com/hashicorp/terraform/state" "github.com/hashicorp/terraform/terraform" @@ -10,9 +12,34 @@ import ( // StateMeta is the meta struct that should be embedded in state subcommands. type StateMeta struct{} -// State returns the state for this meta. -func (m *StateMeta) State(cm *Meta) (state.State, error) { - return cm.State() +// State returns the state for this meta. This is different then Meta.State +// in the way that backups are done. This configures backups to be timestamped +// rather than just the original state path plus a backup path. +func (c *StateMeta) State(m *Meta) (state.State, error) { + // Disable backups since we wrap it manually below + m.backupPath = "-" + + // Get the state (shouldn't be wrapped in a backup) + s, err := m.State() + if err != nil { + return nil, err + } + + // Determine the backup path. stateOutPath is set to the resulting + // file where state is written (cached in the case of remote state) + backupPath := fmt.Sprintf( + "%s.%d.%s", + m.stateOutPath, + time.Now().UTC().Unix(), + DefaultBackupExtension) + + // Wrap it for backups + s = &state.BackupState{ + Real: s, + Path: backupPath, + } + + return s, nil } // filterInstance filters a single instance out of filter results.