command/init: Better error message for provider unsupported platform

As we add and remove support for different target platforms over time,
there will be transition periods where the available platforms for
each provider will be different than the available platforms for Terraform
CLI itself.

In recognition of that possibility, here we add a more specialized error
message for that situation which tries to explain the problem a little
more clearly than the generic error message that came before it.

In an ideal world we'd be able to detect situations where a newer or older
version has support in a similar vein to what we do with provider protocol
incompatibilities, but we don't currently have logic to fetch the data
necessary to implement that, so this is instead a presentation-only change
aimed at allowing some possible near-future changes to the supported
target platforms.
This commit is contained in:
Martin Atkins 2020-09-28 14:25:08 -07:00
parent f835841c28
commit f53264d378
1 changed files with 40 additions and 3 deletions

View File

@ -613,6 +613,7 @@ func (c *InitCommand) getProviders(config *configs.Config, state *states.State,
)) ))
}, },
FetchPackageFailure: func(provider addrs.Provider, version getproviders.Version, err error) { FetchPackageFailure: func(provider addrs.Provider, version getproviders.Version, err error) {
const summaryIncompatible = "Incompatible provider version"
switch err := err.(type) { switch err := err.(type) {
case getproviders.ErrProtocolNotSupported: case getproviders.ErrProtocolNotSupported:
closestAvailable := err.Suggestion closestAvailable := err.Suggestion
@ -620,13 +621,13 @@ func (c *InitCommand) getProviders(config *configs.Config, state *states.State,
case closestAvailable == getproviders.UnspecifiedVersion: case closestAvailable == getproviders.UnspecifiedVersion:
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
"Incompatible provider version", summaryIncompatible,
fmt.Sprintf(errProviderVersionIncompatible, provider.String()), fmt.Sprintf(errProviderVersionIncompatible, provider.String()),
)) ))
case version.GreaterThan(closestAvailable): case version.GreaterThan(closestAvailable):
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
"Incompatible provider version", summaryIncompatible,
fmt.Sprintf(providerProtocolTooNew, provider.ForDisplay(), fmt.Sprintf(providerProtocolTooNew, provider.ForDisplay(),
version, tfversion.String(), closestAvailable, closestAvailable, version, tfversion.String(), closestAvailable, closestAvailable,
getproviders.VersionConstraintsString(reqs[provider]), getproviders.VersionConstraintsString(reqs[provider]),
@ -635,18 +636,54 @@ func (c *InitCommand) getProviders(config *configs.Config, state *states.State,
default: // version is less than closestAvailable default: // version is less than closestAvailable
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
"Incompatible provider version", summaryIncompatible,
fmt.Sprintf(providerProtocolTooOld, provider.ForDisplay(), fmt.Sprintf(providerProtocolTooOld, provider.ForDisplay(),
version, tfversion.String(), closestAvailable, closestAvailable, version, tfversion.String(), closestAvailable, closestAvailable,
getproviders.VersionConstraintsString(reqs[provider]), getproviders.VersionConstraintsString(reqs[provider]),
), ),
)) ))
} }
case getproviders.ErrPlatformNotSupported:
switch {
case err.MirrorURL != nil:
// If we're installing from a mirror then it may just be
// the mirror lacking the package, rather than it being
// unavailable from upstream.
diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error,
summaryIncompatible,
fmt.Sprintf(
"Your chosen provider mirror at %s does not have a %s v%s package available for your current platform, %s.\n\nProvider releases are separate from Terraform CLI releases, so this provider might not support your current platform. Alternatively, the mirror itself might have only a subset of the plugin packages available in the origin registry, at %s.",
err.MirrorURL, err.Provider, err.Version, err.Platform,
err.Provider.Hostname,
),
))
default:
diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error,
summaryIncompatible,
fmt.Sprintf(
"Provider %s v%s does not have a package available for your current platform, %s.\n\nProvider releases are separate from Terraform CLI releases, so not all providers are available for all platforms. Other versions of this provider may have different platforms supported.",
err.Provider, err.Version, err.Platform,
),
))
}
case getproviders.ErrRequestCanceled: case getproviders.ErrRequestCanceled:
// We don't attribute cancellation to any particular operation, // We don't attribute cancellation to any particular operation,
// but rather just emit a single general message about it at // but rather just emit a single general message about it at
// the end, by checking ctx.Err(). // the end, by checking ctx.Err().
default: default:
// We can potentially end up in here under cancellation too,
// in spite of our getproviders.ErrRequestCanceled case above,
// because not all of the outgoing requests we do under the
// "fetch package" banner are source metadata requests.
// In that case we will emit a redundant error here about
// the request being cancelled, but we'll still detect it
// as a cancellation after the installer returns and do the
// normal cancellation handling.
diags = diags.Append(tfdiags.Sourceless( diags = diags.Append(tfdiags.Sourceless(
tfdiags.Error, tfdiags.Error,
"Failed to install provider", "Failed to install provider",