command: remove legacy remote state on migration

Fixes #12871

We were forgetting to remove the legacy remote state from the actual
state value when migrating. This only causes an issue when saving a plan
since the plan contains the state itself and causes an error where both
a backend + legacy state exist.

If saved plans aren't used this causes no noticable issue.

Due to buggy upgrades already existing in the wild, I also added code to
clear the remote section if it exists in a standard unchanged backend
This commit is contained in:
Mitchell Hashimoto 2017-03-20 10:05:24 -07:00
parent 19474ddb18
commit d01886a644
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
4 changed files with 29 additions and 1 deletions

View File

@ -110,6 +110,12 @@ func (b *Local) opPlan(
// Write the backend if we have one // Write the backend if we have one
plan.Backend = op.PlanOutBackend plan.Backend = op.PlanOutBackend
// This works around a bug (#12871) which is no longer possible to
// trigger but will exist for already corrupted upgrades.
if plan.Backend != nil && plan.State != nil {
plan.State.Remote = nil
}
log.Printf("[INFO] backend/local: writing plan output to: %s", path) log.Printf("[INFO] backend/local: writing plan output to: %s", path)
f, err := os.Create(path) f, err := os.Create(path)
if err == nil { if err == nil {

View File

@ -235,6 +235,15 @@ func (m *Meta) backendMigrateState_s_s(opts *backendMigrateOpts) error {
one := stateOne.State() one := stateOne.State()
two := stateTwo.State() two := stateTwo.State()
// Clear the legacy remote state in both cases. If we're at the migration
// step then this won't be used anymore.
if one != nil {
one.Remote = nil
}
if two != nil {
two.Remote = nil
}
var confirmFunc func(state.State, state.State, *backendMigrateOpts) (bool, error) var confirmFunc func(state.State, state.State, *backendMigrateOpts) (bool, error)
switch { switch {
// No migration necessary // No migration necessary

View File

@ -771,6 +771,13 @@ func TestMetaBackend_configureNewLegacyCopy(t *testing.T) {
} }
} }
// Verify we have no configured legacy in the state itself
{
if !state.Remote.Empty() {
t.Fatalf("legacy has remote state: %#v", state.Remote)
}
}
// Write some state // Write some state
state = terraform.NewState() state = terraform.NewState()
state.Lineage = "changing" state.Lineage = "changing"

View File

@ -2,5 +2,11 @@
"version": 3, "version": 3,
"terraform_version": "0.8.2", "terraform_version": "0.8.2",
"serial": 7, "serial": 7,
"lineage": "backend-new-legacy" "lineage": "backend-new-legacy",
"remote": {
"type": "local",
"config": {
"path": "local-state-old.tfstate"
}
}
} }