registry: configurable client timeout (#24259)

* registry: configurable client timeout

* Update registry/client_test.go

    Fix env test cleanup

    Co-Authored-By: Alisdair McDiarmid <alisdair@users.noreply.github.com>
This commit is contained in:
Kim Ngo 2020-03-05 10:37:06 -06:00 committed by GitHub
parent 8f5159ad54
commit d88729d922
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 3 deletions

View File

@ -26,7 +26,6 @@ import (
const ( const (
xTerraformGet = "X-Terraform-Get" xTerraformGet = "X-Terraform-Get"
xTerraformVersion = "X-Terraform-Version" xTerraformVersion = "X-Terraform-Version"
requestTimeout = 10 * time.Second
modulesServiceID = "modules.v1" modulesServiceID = "modules.v1"
providersServiceID = "providers.v1" providersServiceID = "providers.v1"
@ -35,14 +34,27 @@ const (
// discovery requests with the remote registry. // discovery requests with the remote registry.
registryDiscoveryRetryEnvName = "TF_REGISTRY_DISCOVERY_RETRY" registryDiscoveryRetryEnvName = "TF_REGISTRY_DISCOVERY_RETRY"
defaultRetry = 1 defaultRetry = 1
// registryClientTimeoutEnvName is the name of the environment variable that
// can be configured to customize the timeout duration (seconds) for module
// and provider discovery with the remote registry.
registryClientTimeoutEnvName = "TF_REGISTRY_CLIENT_TIMEOUT"
// defaultRequestTimeout is the default timeout duration for requests to the
// remote registry.
defaultRequestTimeout = 10 * time.Second
) )
var discoveryRetry int var (
tfVersion = version.String()
var tfVersion = version.String() discoveryRetry int
requestTimeout time.Duration
)
func init() { func init() {
configureDiscoveryRetry() configureDiscoveryRetry()
configureRequestTimeout()
} }
// Client provides methods to query Terraform Registries. // Client provides methods to query Terraform Registries.
@ -411,3 +423,16 @@ func maxRetryErrorHandler(resp *http.Response, err error, numTries int) (*http.R
} }
return resp, fmt.Errorf("the request failed, please try again later: %d%s", resp.StatusCode, errMsg) return resp, fmt.Errorf("the request failed, please try again later: %d%s", resp.StatusCode, errMsg)
} }
// configureRequestTimeout configures the registry client request timeout from
// environment variables
func configureRequestTimeout() {
requestTimeout = defaultRequestTimeout
if v := os.Getenv(registryClientTimeoutEnvName); v != "" {
timeout, err := strconv.Atoi(v)
if err == nil && timeout > 0 {
requestTimeout = time.Duration(timeout) * time.Second
}
}
}

View File

@ -7,6 +7,7 @@ import (
"os" "os"
"strings" "strings"
"testing" "testing"
"time"
version "github.com/hashicorp/go-version" version "github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-svchost/disco" "github.com/hashicorp/terraform-svchost/disco"
@ -51,6 +52,42 @@ func TestConfigureDiscoveryRetry(t *testing.T) {
}) })
} }
func TestConfigureRegistryClientTimeout(t *testing.T) {
t.Run("default timeout", func(t *testing.T) {
if requestTimeout != defaultRequestTimeout {
t.Fatalf("expected timeout %q, got %q",
defaultRequestTimeout.String(), requestTimeout.String())
}
rc := NewClient(nil, nil)
if rc.client.HTTPClient.Timeout != defaultRequestTimeout {
t.Fatalf("expected client timeout %q, got %q",
defaultRequestTimeout.String(), rc.client.HTTPClient.Timeout.String())
}
})
t.Run("configured timeout", func(t *testing.T) {
defer func(timeoutEnv string) {
os.Setenv(registryClientTimeoutEnvName, timeoutEnv)
requestTimeout = defaultRequestTimeout
}(os.Getenv(registryClientTimeoutEnvName))
os.Setenv(registryClientTimeoutEnvName, "20")
configureRequestTimeout()
expected := 20 * time.Second
if requestTimeout != expected {
t.Fatalf("expected timeout %q, got %q",
expected, requestTimeout.String())
}
rc := NewClient(nil, nil)
if rc.client.HTTPClient.Timeout != expected {
t.Fatalf("expected client timeout %q, got %q",
expected, rc.client.HTTPClient.Timeout.String())
}
})
}
func TestLookupModuleVersions(t *testing.T) { func TestLookupModuleVersions(t *testing.T) {
server := test.Registry() server := test.Registry()
defer server.Close() defer server.Close()

View File

@ -120,6 +120,14 @@ Set `TF_REGISTRY_DISCOVERY_RETRY` to configure the max number of request retries
the remote registry client will attempt for client connection errors or the remote registry client will attempt for client connection errors or
500-range responses that are safe to retry. 500-range responses that are safe to retry.
## TF_REGISTRY_CLIENT_TIMEOUT
The default client timeout for requests to the remote registry is 10s. `TF_REGISTRY_CLIENT_TIMEOUT` can be configured and increased during extraneous circumstances.
```shell
export TF_REGISTRY_CLIENT_TIMEOUT=15
```
## TF_CLI_CONFIG_FILE ## TF_CLI_CONFIG_FILE
The location of the [Terraform CLI configuration file](/docs/commands/cli-config.html). The location of the [Terraform CLI configuration file](/docs/commands/cli-config.html).