cli: Fix backend init failure with deleted cache
When an explicit backend is configured with a configuration which has not yet been initialized, running `terraform init` performs a state migration to fetch the remotely stored state in order to operate on it. Like the previous bug introduced by the recent provider diagnostics change, this code path was not correctly configured to enable init mode for the backend, which resulted in a fatal error during init when the cache dir is deleted. Setting the `Init` backend option allows this code path to continue without error when first initializing the backend for state migration. The new e2e test fails without this change.
This commit is contained in:
parent
5ca21afa75
commit
d42d83572b
|
@ -78,6 +78,42 @@ func TestProviderTampering(t *testing.T) {
|
|||
t.Fatalf("unexpected plan error: %s\nstderr:\n%s", err, stderr)
|
||||
}
|
||||
})
|
||||
t.Run("cache dir totally gone, explicit backend", func(t *testing.T) {
|
||||
tf := e2e.NewBinary(terraformBin, seedDir)
|
||||
defer tf.Close()
|
||||
workDir := tf.WorkDir()
|
||||
|
||||
err := ioutil.WriteFile(filepath.Join(workDir, "backend.tf"), []byte(localBackendConfig), 0600)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = os.RemoveAll(filepath.Join(workDir, ".terraform"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
stdout, stderr, err := tf.Run("plan")
|
||||
if err == nil {
|
||||
t.Fatalf("unexpected plan success\nstdout:\n%s", stdout)
|
||||
}
|
||||
if want := `Initial configuration of the requested backend "local"`; !strings.Contains(stderr, want) {
|
||||
t.Errorf("missing expected error message\nwant substring: %s\ngot:\n%s", want, stderr)
|
||||
}
|
||||
if want := `terraform init`; !strings.Contains(stderr, want) {
|
||||
t.Errorf("missing expected error message\nwant substring: %s\ngot:\n%s", want, stderr)
|
||||
}
|
||||
|
||||
// Running init as suggested resolves the problem
|
||||
_, stderr, err = tf.Run("init")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected init error: %s\nstderr:\n%s", err, stderr)
|
||||
}
|
||||
_, stderr, err = tf.Run("plan")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected plan error: %s\nstderr:\n%s", err, stderr)
|
||||
}
|
||||
})
|
||||
t.Run("null plugin package modified before plan", func(t *testing.T) {
|
||||
tf := e2e.NewBinary(terraformBin, seedDir)
|
||||
defer tf.Close()
|
||||
|
@ -229,3 +265,11 @@ func TestProviderTampering(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
const localBackendConfig = `
|
||||
terraform {
|
||||
backend "local" {
|
||||
path = "terraform.tfstate"
|
||||
}
|
||||
}
|
||||
`
|
||||
|
|
|
@ -745,7 +745,7 @@ func (m *Meta) backend_c_r_S(c *configs.Backend, cHash int, sMgr *clistate.Local
|
|||
m.Ui.Output(fmt.Sprintf(strings.TrimSpace(outputBackendMigrateLocal), s.Backend.Type))
|
||||
|
||||
// Grab a purely local backend to get the local state if it exists
|
||||
localB, diags := m.Backend(&BackendOpts{ForceLocal: true})
|
||||
localB, diags := m.Backend(&BackendOpts{ForceLocal: true, Init: true})
|
||||
if diags.HasErrors() {
|
||||
return nil, diags
|
||||
}
|
||||
|
@ -799,7 +799,7 @@ func (m *Meta) backend_C_r_s(c *configs.Backend, cHash int, sMgr *clistate.Local
|
|||
}
|
||||
|
||||
// Grab a purely local backend to get the local state if it exists
|
||||
localB, localBDiags := m.Backend(&BackendOpts{ForceLocal: true})
|
||||
localB, localBDiags := m.Backend(&BackendOpts{ForceLocal: true, Init: true})
|
||||
if localBDiags.HasErrors() {
|
||||
diags = diags.Append(localBDiags)
|
||||
return nil, diags
|
||||
|
|
Loading…
Reference in New Issue