main: Pass untyped nil for missing creds source

If we are unable to create a credentials source for some reason, we can
rely on the disco object to nil-check it before calling any of its
methods. However to do this we must ensure that we pass untyped nil.
This commit rearranges the initialization to ensure that this happens.

The user-facing bug that triggered this work is that running init when
the HOME environment variable is unset would result in a panic on macOS.
This commit is contained in:
Alisdair McDiarmid 2020-06-03 09:43:24 -04:00
parent 6fbd3942ea
commit f1f24df7ff
1 changed files with 10 additions and 4 deletions

14
main.go
View File

@ -154,18 +154,24 @@ func wrappedMain() int {
} }
// Get any configured credentials from the config and initialize // Get any configured credentials from the config and initialize
// a service discovery object. // a service discovery object. The slightly awkward predeclaration of
// disco is required to allow us to pass untyped nil as the creds source
// when creating the source fails. Otherwise we pass a typed nil which
// breaks the nil checks in the disco object
var services *disco.Disco
credsSrc, err := credentialsSource(config) credsSrc, err := credentialsSource(config)
if err != nil { if err == nil {
services = disco.NewWithCredentialsSource(credsSrc)
} else {
// Most commands don't actually need credentials, and most situations // Most commands don't actually need credentials, and most situations
// that would get us here would already have been reported by the config // that would get us here would already have been reported by the config
// loading above, so we'll just log this one as an aid to debugging // loading above, so we'll just log this one as an aid to debugging
// in the unlikely event that it _does_ arise. // in the unlikely event that it _does_ arise.
log.Printf("[WARN] Cannot initialize remote host credentials manager: %s", err) log.Printf("[WARN] Cannot initialize remote host credentials manager: %s", err)
// credsSrc may be nil in this case, but that's okay because the disco // passing (untyped) nil as the creds source is okay because the disco
// object checks that and just acts as though no credentials are present. // object checks that and just acts as though no credentials are present.
services = disco.NewWithCredentialsSource(nil)
} }
services := disco.NewWithCredentialsSource(credsSrc)
services.SetUserAgent(httpclient.TerraformUserAgent(version.String())) services.SetUserAgent(httpclient.TerraformUserAgent(version.String()))
providerSrc, diags := providerSource(config.ProviderInstallation, services) providerSrc, diags := providerSource(config.ProviderInstallation, services)