diff --git a/command/init.go b/command/init.go index dbdc474dae..7b0ed1896b 100644 --- a/command/init.go +++ b/command/init.go @@ -2,12 +2,14 @@ package command import ( "fmt" + "log" "os" "path/filepath" "sort" "strings" getter "github.com/hashicorp/go-getter" + multierror "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform/backend" "github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/config/module" @@ -194,8 +196,8 @@ func (c *InitCommand) Run(args []string) int { err = c.getProviders(path, sMgr.State()) if err != nil { - c.Ui.Error(fmt.Sprintf( - "Error getting plugins: %s", err)) + // this function provides its own output + log.Printf("[ERROR] %s", err) return 1 } } @@ -211,14 +213,17 @@ func (c *InitCommand) Run(args []string) int { return 0 } -// load the complete module tree, and fetch any missing providers +// Load the complete module tree, and fetch any missing providers. +// This method outputs its own Ui. func (c *InitCommand) getProviders(path string, state *terraform.State) error { mod, err := c.Module(path) if err != nil { + c.Ui.Error(fmt.Sprintf("Error getting plugins: %s", err)) return err } if err := mod.Validate(); err != nil { + c.Ui.Error(fmt.Sprintf("Error getting plugins: %s", err)) return err } @@ -227,15 +232,21 @@ func (c *InitCommand) getProviders(path string, state *terraform.State) error { missing := c.missingPlugins(available, requirements) dst := c.pluginDir() + var errs error for provider, reqd := range missing { c.Ui.Output(fmt.Sprintf("- downloading plugin for provider %q...", provider)) err := c.getProvider(dst, provider, reqd.Versions, plugin.Handshake.ProtocolVersion) - // TODO: return all errors + if err != nil { - return err + c.Ui.Error(fmt.Sprintf(errProviderNotFound, err, provider, reqd.Versions)) + errs = multierror.Append(errs, err) } } + if errs != nil { + return errs + } + // With all the providers downloaded, we'll generate our lock file // that ensures the provider binaries remain unchanged until we init // again. If anything changes, other commands that use providers will @@ -246,13 +257,15 @@ func (c *InitCommand) getProviders(path string, state *terraform.State) error { for name, meta := range chosen { digest, err := meta.SHA256() if err != nil { - return fmt.Errorf("failed to read provider plugin %s: %s", meta.Path, err) + c.Ui.Error(fmt.Sprintf("failed to read provider plugin %s: %s", meta.Path, err)) + return err } digests[name] = digest } err = c.providerPluginsLock().Write(digests) if err != nil { - return fmt.Errorf("failed to save provider manifest: %s", err) + c.Ui.Error(fmt.Sprintf("failed to save provider manifest: %s", err)) + return err } // If any providers have "floating" versions (completely unconstrained) @@ -408,3 +421,15 @@ changes, it is recommended to add version = "..." constraints to the corresponding provider blocks in configuration, with the constraint strings suggested below. ` + +const errProviderNotFound = ` +[reset][red]%[1]s + +[reset][bold][red]Error: Satisfying %[2]q, provider not found + +[reset][red]A version of the %[2]q provider that satisfies all version +constraints could not be found. The requested version +constraints are shown below. + +%[2]s = %[3]q[reset] +`