don't load the backend when -state is provided

When using a `state` command, if the `-state` flag is provided we do not
want to modify the Backend state. In this case we should always create a
local state instance.

The backup flag was also being ignored, and some tests were relying on
that, which have been fixed.
This commit is contained in:
James Bardin 2017-06-23 14:41:49 -04:00
parent 5f939b42fe
commit 6e7baaaeff
3 changed files with 51 additions and 44 deletions

View File

@ -18,46 +18,63 @@ type StateMeta struct{}
// backups to be timestamped rather than just the original state path plus a // backups to be timestamped rather than just the original state path plus a
// backup path. // backup path.
func (c *StateMeta) State(m *Meta) (state.State, error) { func (c *StateMeta) State(m *Meta) (state.State, error) {
// Load the backend var realState state.State
b, err := m.Backend(nil) backupPath := m.backupPath
if err != nil { stateOutPath := m.statePath
return nil, err
// use the specified state
if m.statePath != "" {
realState = &state.LocalState{
Path: m.statePath,
}
} else {
// Load the backend
b, err := m.Backend(nil)
if err != nil {
return nil, err
}
env := m.Workspace()
// Get the state
s, err := b.State(env)
if err != nil {
return nil, err
}
// Get a local backend
localRaw, err := m.Backend(&BackendOpts{ForceLocal: true})
if err != nil {
// This should never fail
panic(err)
}
localB := localRaw.(*backendlocal.Local)
_, stateOutPath, _ = localB.StatePaths(env)
if err != nil {
return nil, err
}
realState = s
} }
env := m.Workspace() // We always backup state commands, so set the back if none was specified
// Get the state // (the default is "-", but some tests bypass the flag parsing).
s, err := b.State(env) if backupPath == "-" || backupPath == "" {
if err != nil { // Determine the backup path. stateOutPath is set to the resulting
return nil, err // file where state is written (cached in the case of remote state)
backupPath = fmt.Sprintf(
"%s.%d%s",
stateOutPath,
time.Now().UTC().Unix(),
DefaultBackupExtension)
} }
// Get a local backend
localRaw, err := m.Backend(&BackendOpts{ForceLocal: true})
if err != nil {
// This should never fail
panic(err)
}
localB := localRaw.(*backendlocal.Local)
_, stateOutPath, _ := localB.StatePaths(env)
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",
stateOutPath,
time.Now().UTC().Unix(),
DefaultBackupExtension)
// Wrap it for backups // Wrap it for backups
s = &state.BackupState{ realState = &state.BackupState{
Real: s, Real: realState,
Path: backupPath, Path: backupPath,
} }
return s, nil return realState, nil
} }
// filterInstance filters a single instance out of filter results. // filterInstance filters a single instance out of filter results.

View File

@ -213,12 +213,7 @@ func TestStateMv_backupExplicit(t *testing.T) {
// Test it is correct // Test it is correct
testStateOutput(t, statePath, testStateMvOutput) testStateOutput(t, statePath, testStateMvOutput)
// Test we have backups // Test backup
backups := testStateBackups(t, filepath.Dir(statePath))
if len(backups) != 1 {
t.Fatalf("bad: %#v", backups)
}
testStateOutput(t, backups[0], testStateMvOutputOriginal)
testStateOutput(t, backupPath, testStateMvOutputOriginal) testStateOutput(t, backupPath, testStateMvOutputOriginal)
} }

View File

@ -130,12 +130,7 @@ func TestStateRm_backupExplicit(t *testing.T) {
// Test it is correct // Test it is correct
testStateOutput(t, statePath, testStateRmOutput) testStateOutput(t, statePath, testStateRmOutput)
// Test we have backups // Test backup
backups := testStateBackups(t, filepath.Dir(statePath))
if len(backups) != 1 {
t.Fatalf("bad: %#v", backups)
}
testStateOutput(t, backups[0], testStateRmOutputOriginal)
testStateOutput(t, backupPath, testStateRmOutputOriginal) testStateOutput(t, backupPath, testStateRmOutputOriginal)
} }