Merge pull request #29792 from hashicorp/alisdair/init-missing-cache
cli: Fix init failure with deleted cache
This commit is contained in:
commit
92a9aa9b39
|
@ -57,7 +57,7 @@ func TestProviderTampering(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, stderr, err := tf.Run("plan")
|
||||
stdout, stderr, err := tf.Run("plan")
|
||||
if err == nil {
|
||||
t.Fatalf("unexpected plan success\nstdout:\n%s", stdout)
|
||||
}
|
||||
|
@ -67,6 +67,16 @@ func TestProviderTampering(t *testing.T) {
|
|||
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)
|
||||
|
|
|
@ -238,7 +238,7 @@ func (c *InitCommand) Run(args []string) int {
|
|||
// by a previous run, so we must still expect that "back" may be nil
|
||||
// in code that follows.
|
||||
var backDiags tfdiags.Diagnostics
|
||||
back, backDiags = c.Backend(nil)
|
||||
back, backDiags = c.Backend(&BackendOpts{Init: true})
|
||||
if backDiags.HasErrors() {
|
||||
// This is fine. We'll proceed with no backend, then.
|
||||
back = nil
|
||||
|
|
|
@ -459,10 +459,8 @@ func (m *Meta) contextOpts() (*terraform.ContextOpts, error) {
|
|||
opts.Providers = m.testingOverrides.Providers
|
||||
opts.Provisioners = m.testingOverrides.Provisioners
|
||||
} else {
|
||||
providerFactories, err := m.providerFactories()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var providerFactories map[addrs.Provider]providers.Factory
|
||||
providerFactories, err = m.providerFactories()
|
||||
opts.Providers = providerFactories
|
||||
opts.Provisioners = m.provisionerFactories()
|
||||
}
|
||||
|
@ -472,7 +470,7 @@ func (m *Meta) contextOpts() (*terraform.ContextOpts, error) {
|
|||
OriginalWorkingDir: m.WorkingDir.OriginalWorkingDir(),
|
||||
}
|
||||
|
||||
return &opts, nil
|
||||
return &opts, err
|
||||
}
|
||||
|
||||
// defaultFlagSet creates a default flag set for commands.
|
||||
|
|
|
@ -112,28 +112,34 @@ func (m *Meta) Backend(opts *BackendOpts) (backend.Enhanced, tfdiags.Diagnostics
|
|||
// indicates one or more inconsistencies between the dependency
|
||||
// lock file and the provider plugins actually available in the
|
||||
// local cache directory.
|
||||
var buf bytes.Buffer
|
||||
for addr, err := range errs {
|
||||
fmt.Fprintf(&buf, "\n - %s: %s", addr, err)
|
||||
//
|
||||
// If initialization is allowed, we ignore this error, as it may
|
||||
// be resolved by the later step where providers are fetched.
|
||||
if !opts.Init {
|
||||
var buf bytes.Buffer
|
||||
for addr, err := range errs {
|
||||
fmt.Fprintf(&buf, "\n - %s: %s", addr, err)
|
||||
}
|
||||
suggestion := "To download the plugins required for this configuration, run:\n terraform init"
|
||||
if m.RunningInAutomation {
|
||||
// Don't mention "terraform init" specifically if we're running in an automation wrapper
|
||||
suggestion = "You must install the required plugins before running Terraform operations."
|
||||
}
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Required plugins are not installed",
|
||||
fmt.Sprintf(
|
||||
"The installed provider plugins are not consistent with the packages selected in the dependency lock file:%s\n\nTerraform uses external plugins to integrate with a variety of different infrastructure services. %s",
|
||||
buf.String(), suggestion,
|
||||
),
|
||||
))
|
||||
return nil, diags
|
||||
}
|
||||
suggestion := "To download the plugins required for this configuration, run:\n terraform init"
|
||||
if m.RunningInAutomation {
|
||||
// Don't mention "terraform init" specifically if we're running in an automation wrapper
|
||||
suggestion = "You must install the required plugins before running Terraform operations."
|
||||
}
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Required plugins are not installed",
|
||||
fmt.Sprintf(
|
||||
"The installed provider plugins are not consistent with the packages selected in the dependency lock file:%s\n\nTerraform uses external plugins to integrate with a variety of different infrastructure services. %s",
|
||||
buf.String(), suggestion,
|
||||
),
|
||||
))
|
||||
} else {
|
||||
// All other errors just get generic handling.
|
||||
diags = diags.Append(err)
|
||||
return nil, diags
|
||||
}
|
||||
return nil, diags
|
||||
}
|
||||
cliOpts.Validation = true
|
||||
|
||||
|
@ -337,7 +343,7 @@ func (m *Meta) BackendForPlan(settings plans.Backend) (backend.Enhanced, tfdiags
|
|||
// a backend that supports local CLI operations.
|
||||
func (m *Meta) backendCLIOpts() (*backend.CLIOpts, error) {
|
||||
contextOpts, err := m.contextOpts()
|
||||
if err != nil {
|
||||
if contextOpts == nil && err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &backend.CLIOpts{
|
||||
|
@ -350,7 +356,7 @@ func (m *Meta) backendCLIOpts() (*backend.CLIOpts, error) {
|
|||
ContextOpts: contextOpts,
|
||||
Input: m.Input(),
|
||||
RunningInAutomation: m.RunningInAutomation,
|
||||
}, nil
|
||||
}, err
|
||||
}
|
||||
|
||||
// Operation initializes a new backend.Operation struct.
|
||||
|
|
Loading…
Reference in New Issue