Repository: helm/helm
Pull request #10568 (2022-01-17 14:45:12)

HTTPGetter: Reuse http transport
The `HTTPGetter` makes a new instance of the `http.Transport` on each HTTP request, which according to the docs should be avoided.

From the go docs (https://github.com/golang/go/blob/master/src/net/http/client.go#L32 and https://github.com/golang/go/blob/master/src/net/http/transport.go#L68)
```
The Client's Transport typically has internal state (cached TCP connections)
...
Transports should be reused instead of created as needed.
```

In polling clients which make use of this `HTTPGetter` like https://github.com/fluxcd/source-controller this can cause problems as for every request a new TCP connection is created and never closed, which in our case went to thousands of open TCP connections from this polling client.

This PR makes a single transport per `HTTPGetter` client and reuses it for future requests.

**Special notes for your reviewer**:

**If applicable**:
- [x] this PR contains documentation
- [x] this PR contains unit tests
- [x] this PR has been tested for backwards compatibility



Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 7a9c4874d..f3599607b 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -13,7 +13,7 @@ jobs:
 
     environment:
       GOCACHE: "/tmp/go/cache"
-      GOLANGCI_LINT_VERSION: "1.43.0"
+      GOLANGCI_LINT_VERSION: "1.36.0"
 
     steps:
       - checkout
diff --git a/.golangci.yml b/.golangci.yml
index 2807ede34..5c2445711 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -8,12 +8,12 @@ linters:
     - dupl
     - gofmt
     - goimports
+    - golint
     - gosimple
     - govet
     - ineffassign
     - misspell
     - nakedret
-    - revive
     - structcheck
     - unused
     - varcheck
diff --git a/cmd/helm/flags.go b/cmd/helm/flags.go
index 0cc0564e2..6a59101b7 100644
--- a/cmd/helm/flags.go
+++ b/cmd/helm/flags.go
@@ -36,11 +36,8 @@ import (
 	"helm.sh/helm/v3/pkg/repo"
 )
 
-const (
-	outputFlag         = "output"
-	postRenderFlag     = "post-renderer"
-	postRenderArgsFlag = "post-renderer-args"
-)
+const outputFlag = "output"
+const postRenderFlag = "post-renderer"
 
 func addValueOptionsFlags(f *pflag.FlagSet, v *values.Options) {
 	f.StringSliceVarP(&v.ValueFiles, "values", "f", []string{}, "specify values in a YAML file or a URL (can specify multiple)")
@@ -113,85 +110,33 @@ func (o *outputValue) Set(s string) error {
 }
 
 func bindPostRenderFlag(cmd *cobra.Command, varRef *postrender.PostRenderer) {
-	p := &postRendererOptions{varRef, "", []string{}}
-	cmd.Flags().Var(&postRendererString{p}, postRenderFlag, "the path to an executable to be used for post rendering. If it exists in $PATH, the binary will be used, otherwise it will try to look for the executable at the given path")
-	cmd.Flags().Var(&postRendererArgsSlice{p}, postRenderArgsFlag, "an argument to the post-renderer (can specify multiple)")
-}
-
-type postRendererOptions struct {
-	renderer   *postrender.PostRenderer
-	binaryPath string
-	args       []string
+	cmd.Flags().Var(&postRenderer{varRef}, postRenderFlag, "the path to an executable to be used for post rendering. If it exists in $PATH, the binary will be used, otherwise it will try to look for the executable at the given path")
 }
 
-type postRendererString struct {
-	options *postRendererOptions
+type postRenderer struct {
+	renderer *postrender.PostRenderer
 }
 
-func (p *postRendererString) String() string {
-	return p.options.binaryPath
+func (p postRenderer) String() string {
+	return "exec"
 }
 
-func (p *postRendererString) Type() string {
-	return "postRendererString"
+func (p postRenderer) Type() string {
+	return "postrenderer"
 }
 
-func (p *postRendererString) Set(val string) error {
-	if val == "" {
+func (p postRenderer) Set(s string) error {
+	if s == "" {
 		return nil
 	}
-	p.options.binaryPath = val
-	pr, err := postrender.NewExec(p.options.binaryPath, p.options.args...)
+	pr, err := postrender.NewExec(s)
 	if err != nil {
 		return err
 	}
-	*p.options.renderer = pr
+	*p.renderer = pr
 	return nil
 }
 
-type postRendererArgsSlice struct {
-	options *postRendererOptions
-}
-
-func (p *postRendererArgsSlice) String() string {
-	return "[" + strings.Join(p.options.args, ",") + "]"
-}
-
-func (p *postRendererArgsSlice) Type() string {
-	return "postRendererArgsSlice"
-}
-
-func (p *postRendererArgsSlice) Set(val string) error {
-
-	// a post-renderer defined by a user may accept empty arguments
-	p.options.args = append(p.options.args, val)
-
-	if p.options.binaryPath == "" {
-		return nil
-	}
-	// overwrite if already create PostRenderer by `post-renderer` flags
-	pr, err := postrender.NewExec(p.options.binaryPath, p.options.args...)
-	if err != nil {
-		return err
-	}
-	*p.options.renderer = pr
-	return nil
-}
-
-func (p *postRendererArgsSlice) Append(val string) error {
-	p.options.args = append(p.options.args, val)
-	return nil
-}
-
-func (p *postRendererArgsSlice) Replace(val []string) error {
-	p.options.args = val
-	return nil
-}
-
-func (p *postRendererArgsSlice) GetSlice() []string {
-	return p.options.args
-}
-
 func compVersionFlag(chartRef string, toComplete string) ([]string, cobra.ShellCompDirective) {
 	chartInfo := strings.Split(chartRef, "/")
 	if len(chartInfo) != 2 {
diff --git a/cmd/helm/load_plugins.go b/cmd/helm/load_plugins.go
index a97d49a93..70002b0b0 100644
--- a/cmd/helm/load_plugins.go
+++ b/cmd/helm/load_plugins.go
@@ -313,7 +313,7 @@ func loadFile(path string) (*pluginCommand, error) {
 	cmds := new(pluginCommand)
 	b, err := ioutil.ReadFile(path)
 	if err != nil {
-		return cmds, fmt.Errorf("file (%s) not provided by plugin. No plugin auto-completion possible", path)
+		return cmds, errors.New(fmt.Sprintf("File (%s) not provided by plugin. No plugin auto-completion possible.", path))
 	}
 
 	err = yaml.Unmarshal(b, cmds)
diff --git a/cmd/helm/push.go b/cmd/helm/push.go
index d2cf2693e..ed5d1699a 100644
--- a/cmd/helm/push.go
+++ b/cmd/helm/push.go
@@ -24,7 +24,6 @@ import (
 
 	"helm.sh/helm/v3/cmd/helm/require"
 	"helm.sh/helm/v3/pkg/action"
-	"helm.sh/helm/v3/pkg/pusher"
 )
 
 const pushDesc = `
@@ -42,23 +41,6 @@ func newPushCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 		Short: "push a chart to remote",
 		Long:  pushDesc,
 		Args:  require.MinimumNArgs(2),
-		ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
-			if len(args) == 0 {
-				// Do file completion for the chart file to push
-				return nil, cobra.ShellCompDirectiveDefault
-			}
-			if len(args) == 1 {
-				providers := []pusher.Provider(pusher.All(settings))
-				var comps []string
-				for _, p := range providers {
-					for _, scheme := range p.Schemes {
-						comps = append(comps, fmt.Sprintf("%s://", scheme))
-					}
-				}
-				return comps, cobra.ShellCompDirectiveNoFileComp | cobra.ShellCompDirectiveNoSpace
-			}
-			return nil, cobra.ShellCompDirectiveNoFileComp
-		},
 		RunE: func(cmd *cobra.Command, args []string) error {
 			chartRef := args[0]
 			remote := args[1]
diff --git a/cmd/helm/registry_login.go b/cmd/helm/registry_login.go
index 8abf91e77..84f9f27b5 100644
--- a/cmd/helm/registry_login.go
+++ b/cmd/helm/registry_login.go
@@ -41,11 +41,10 @@ func newRegistryLoginCmd(cfg *action.Configuration, out io.Writer) *cobra.Comman
 	var passwordFromStdinOpt, insecureOpt bool
 
 	cmd := &cobra.Command{
-		Use:               "login [host]",
-		Short:             "login to a registry",
-		Long:              registryLoginDesc,
-		Args:              require.MinimumNArgs(1),
-		ValidArgsFunction: noCompletions,
+		Use:   "login [host]",
+		Short: "login to a registry",
+		Long:  registryLoginDesc,
+		Args:  require.MinimumNArgs(1),
 		RunE: func(cmd *cobra.Command, args []string) error {
 			hostname := args[0]
 
diff --git a/cmd/helm/registry_logout.go b/cmd/helm/registry_logout.go
index 0084f8c09..8d6a54d97 100644
--- a/cmd/helm/registry_logout.go
+++ b/cmd/helm/registry_logout.go
@@ -31,11 +31,10 @@ Remove credentials stored for a remote registry.
 
 func newRegistryLogoutCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
 	return &cobra.Command{
-		Use:               "logout [host]",
-		Short:             "logout from a registry",
-		Long:              registryLogoutDesc,
-		Args:              require.MinimumNArgs(1),
-		ValidArgsFunction: noCompletions,
+		Use:   "logout [host]",
+		Short: "logout from a registry",
+		Long:  registryLogoutDesc,
+		Args:  require.MinimumNArgs(1),
 		RunE: func(cmd *cobra.Command, args []string) error {
 			hostname := args[0]
 			return action.NewRegistryLogout(cfg).Run(out, hostname)
diff --git a/cmd/helm/repo_update.go b/cmd/helm/repo_update.go
index 27661674c..ae09f9195 100644
--- a/cmd/helm/repo_update.go
+++ b/cmd/helm/repo_update.go
@@ -133,8 +133,8 @@ func updateCharts(repos []*repo.ChartRepository, out io.Writer, failOnRepoUpdate
 	wg.Wait()
 
 	if len(repoFailList) > 0 && failOnRepoUpdateFail {
-		return fmt.Errorf("Failed to update the following repositories: %s",
-			repoFailList)
+		return errors.New(fmt.Sprintf("Failed to update the following repositories: %s",
+			repoFailList))
 	}
 
 	fmt.Fprintln(out, "Update Complete. ⎈Happy Helming!⎈")
diff --git a/cmd/helm/search_repo.go b/cmd/helm/search_repo.go
index f794f6bca..34232fcfa 100644
--- a/cmd/helm/search_repo.go
+++ b/cmd/helm/search_repo.go
@@ -326,7 +326,7 @@ func compListCharts(toComplete string, includeFiles bool) ([]string, cobra.Shell
 	cobra.CompDebugln(fmt.Sprintf("Completions after repos: %v", completions), settings.Debug)
 
 	// Now handle completions for url prefixes
-	for _, url := range []string{"oci://\tChart OCI prefix", "https://\tChart URL prefix", "http://\tChart URL prefix", "file://\tChart local URL prefix"} {
+	for _, url := range []string{"https://\tChart URL prefix", "http://\tChart URL prefix", "file://\tChart local URL prefix"} {
 		if strings.HasPrefix(toComplete, url) {
 			// The user already put in the full url prefix; we don't have
 			// anything to add, but make sure the shell does not default
diff --git a/go.mod b/go.mod
index 0bf334e09..49f96ea97 100644
--- a/go.mod
+++ b/go.mod
@@ -25,22 +25,23 @@ require (
 	github.com/opencontainers/image-spec v1.0.2
 	github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
 	github.com/pkg/errors v0.9.1
-	github.com/rubenv/sql-migrate v1.1.1
+	github.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc
 	github.com/sirupsen/logrus v1.8.1
 	github.com/spf13/cobra v1.3.0
 	github.com/spf13/pflag v1.0.5
 	github.com/stretchr/testify v1.7.0
 	github.com/xeipuuv/gojsonschema v1.2.0
+	github.com/ziutek/mymysql v1.5.4 // indirect
 	golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
-	golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
-	k8s.io/api v0.23.3
-	k8s.io/apiextensions-apiserver v0.23.3
-	k8s.io/apimachinery v0.23.3
-	k8s.io/apiserver v0.23.3
-	k8s.io/cli-runtime v0.23.3
-	k8s.io/client-go v0.23.3
+	golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b
+	k8s.io/api v0.23.1
+	k8s.io/apiextensions-apiserver v0.23.1
+	k8s.io/apimachinery v0.23.1
+	k8s.io/apiserver v0.23.1
+	k8s.io/cli-runtime v0.23.1
+	k8s.io/client-go v0.23.1
 	k8s.io/klog/v2 v2.30.0
-	k8s.io/kubectl v0.23.3
+	k8s.io/kubectl v0.23.1
 	oras.land/oras-go v1.1.0
 	sigs.k8s.io/yaml v1.3.0
 )
diff --git a/go.sum b/go.sum
index 7664d4399..88da64deb 100644
--- a/go.sum
+++ b/go.sum
@@ -430,8 +430,6 @@ github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-gorp/gorp/v3 v3.0.2 h1:ULqJXIekoqMx29FI5ekXXFoH1dT2Vc8UhnRzBg+Emz4=
-github.com/go-gorp/gorp/v3 v3.0.2/go.mod h1:BJ3q1ejpV8cVALtcXvXaXyTOlMmJhWDxTmncaR6rwBY=
 github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@@ -461,16 +459,15 @@ github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
 github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
 github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
-github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
 github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU=
-github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs=
-github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0=
-github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY=
-github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY=
-github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc=
+github.com/gobuffalo/logger v1.0.3 h1:YaXOTHNPCvkqqA7w05A4v0k2tCdpr+sgFlgINbQ6gqc=
+github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM=
+github.com/gobuffalo/packd v1.0.0 h1:6ERZvJHfe24rfFmA9OaoKBdC7+c9sydrytMg8SdFGBM=
+github.com/gobuffalo/packd v1.0.0/go.mod h1:6VTc4htmJRFB7u1m/4LeMTWjFoYrUiBkU9Fdec9hrhI=
+github.com/gobuffalo/packr/v2 v2.8.1 h1:tkQpju6i3EtMXJ9uoF5GT6kB+LMTimDWD8Xvbz6zDVA=
+github.com/gobuffalo/packr/v2 v2.8.1/go.mod h1:c/PLlOuTU+p3SybaJATW3H6lX/iK7xEz5OeMf+NnJpg=
 github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
 github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
 github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
@@ -691,8 +688,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
-github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
-github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
+github.com/karrick/godirwalk v1.15.8 h1:7+rWAZPn9zuRxaIqqT8Ohs2Q2Ac0msBqwRdxNCr2VVs=
+github.com/karrick/godirwalk v1.15.8/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
@@ -768,7 +765,6 @@ github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vq
 github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
 github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
 github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
-github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
 github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -896,7 +892,6 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
-github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -907,8 +902,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
 github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
-github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1 h1:oL4IBbcqwhhNWh31bjOX8C/OCy0zs9906d/VUru+bqg=
-github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU=
 github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
 github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@@ -951,9 +944,9 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
-github.com/rubenv/sql-migrate v1.1.1 h1:haR5Hn8hbW9/SpAICrXoZqXnywS7Q5WijwkQENPeNWY=
-github.com/rubenv/sql-migrate v1.1.1/go.mod h1:/7TZymwxN8VWumcIxw1jjHEcR1djpdkMHQPT4FWdnbQ=
+github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc h1:BD7uZqkN8CpjJtN/tScAKiccBikU4dlqe/gNrkRaPY4=
+github.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc/go.mod h1:HFLT6i9iR4QBOF5rdCyjddC9t59ArqWJV2xx+jwcCMo=
 github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
 github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -996,6 +989,7 @@ github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
 github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
+github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
 github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
 github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
 github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
@@ -1135,6 +1129,7 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -1383,9 +1378,8 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE=
 golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1446,6 +1440,7 @@ golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapK
 golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
 golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
 golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
 golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -1472,7 +1467,6 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM=
-golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1654,6 +1648,8 @@ gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
+gopkg.in/gorp.v1 v1.7.2 h1:j3DWlAyGVv8whO7AcIWznQ2Yj7yJkn34B8s63GViAAw=
+gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
@@ -1695,35 +1691,35 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
 k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
 k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
 k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
-k8s.io/api v0.23.3 h1:KNrME8KHGr12Ozjf8ytOewKzZh6hl/hHUZeHddT3a38=
-k8s.io/api v0.23.3/go.mod h1:w258XdGyvCmnBj/vGzQMj6kzdufJZVUwEM1U2fRJwSQ=
-k8s.io/apiextensions-apiserver v0.23.3 h1:JvPJA7hSEAqMRteveq4aj9semilAZYcJv+9HHFWfUdM=
-k8s.io/apiextensions-apiserver v0.23.3/go.mod h1:/ZpRXdgKZA6DvIVPEmXDCZJN53YIQEUDF+hrpIQJL38=
+k8s.io/api v0.23.1 h1:ncu/qfBfUoClqwkTGbeRqqOqBCRoUAflMuOaOD7J0c8=
+k8s.io/api v0.23.1/go.mod h1:WfXnOnwSqNtG62Y1CdjoMxh7r7u9QXGCkA1u0na2jgo=
+k8s.io/apiextensions-apiserver v0.23.1 h1:xxE0q1vLOVZiWORu1KwNRQFsGWtImueOrqSl13sS5EU=
+k8s.io/apiextensions-apiserver v0.23.1/go.mod h1:0qz4fPaHHsVhRApbtk3MGXNn2Q9M/cVWWhfHdY2SxiM=
 k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
 k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
 k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
-k8s.io/apimachinery v0.23.3 h1:7IW6jxNzrXTsP0c8yXz2E5Yx/WTzVPTsHIx/2Vm0cIk=
-k8s.io/apimachinery v0.23.3/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM=
+k8s.io/apimachinery v0.23.1 h1:sfBjlDFwj2onG0Ijx5C+SrAoeUscPrmghm7wHP+uXlo=
+k8s.io/apimachinery v0.23.1/go.mod h1:SADt2Kl8/sttJ62RRsi9MIV4o8f5S3coArm0Iu3fBno=
 k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
 k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
 k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
-k8s.io/apiserver v0.23.3 h1:gWY1DmA0AdAGR/H+Q/1FtyGkFq8xqSaZOw7oLopmO8k=
-k8s.io/apiserver v0.23.3/go.mod h1:3HhsTmC+Pn+Jctw+Ow0LHA4dQ4oXrQ4XJDzrVDG64T4=
-k8s.io/cli-runtime v0.23.3 h1:aJiediw+uUbxkfO6BNulcAMTUoU9Om43g3R7rIkYqcw=
-k8s.io/cli-runtime v0.23.3/go.mod h1:yA00O5pDqnjkBh8fkuugBbfIfjB1nOpz+aYLotbnOfc=
+k8s.io/apiserver v0.23.1 h1:vWGf8LcV9Pk/z5rdLmCiBDqE21ccbe930dzrtVMhw9g=
+k8s.io/apiserver v0.23.1/go.mod h1:Bqt0gWbeM2NefS8CjWswwd2VNAKN6lUKR85Ft4gippY=
+k8s.io/cli-runtime v0.23.1 h1:vHUZrq1Oejs0WaJnxs09mLHKScvIIl2hMSthhS8o8Yo=
+k8s.io/cli-runtime v0.23.1/go.mod h1:r9r8H/qfXo9w+69vwUL7LokKlLRKW5D6A8vUKCx+YL0=
 k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
 k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
 k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
-k8s.io/client-go v0.23.3 h1:23QYUmCQ/W6hW78xIwm3XqZrrKZM+LWDqW2zfo+szJs=
-k8s.io/client-go v0.23.3/go.mod h1:47oMd+YvAOqZM7pcQ6neJtBiFH7alOyfunYN48VsmwE=
+k8s.io/client-go v0.23.1 h1:Ma4Fhf/p07Nmj9yAB1H7UwbFHEBrSPg8lviR24U2GiQ=
+k8s.io/client-go v0.23.1/go.mod h1:6QSI8fEuqD4zgFK0xbdwfB/PthBsIxCJMa3s17WlcO0=
 k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0=
-k8s.io/code-generator v0.23.3/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk=
+k8s.io/code-generator v0.23.1/go.mod h1:V7yn6VNTCWW8GqodYCESVo95fuiEg713S8B7WacWZDA=
 k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
 k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
 k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
-k8s.io/component-base v0.23.3 h1:q+epprVdylgecijVGVdf4MbizEL2feW4ssd7cdo6LVY=
-k8s.io/component-base v0.23.3/go.mod h1:1Smc4C60rWG7d3HjSYpIwEbySQ3YWg0uzH5a2AtaTLg=
-k8s.io/component-helpers v0.23.3/go.mod h1:SH+W/WPTaTenbWyDEeY7iytAQiMh45aqKxkvlqQ57cg=
+k8s.io/component-base v0.23.1 h1:j/BqdZUWeWKCy2v/jcgnOJAzpRYWSbGcjGVYICko8Uc=
+k8s.io/component-base v0.23.1/go.mod h1:6llmap8QtJIXGDd4uIWJhAq0Op8AtQo6bDW2RrNMTeo=
+k8s.io/component-helpers v0.23.1/go.mod h1:ZK24U+2oXnBPcas2KolLigVVN9g5zOzaHLkHiQMFGr0=
 k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=
 k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
 k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
@@ -1742,14 +1738,14 @@ k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAG
 k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
 k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4=
 k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=
-k8s.io/kubectl v0.23.3 h1:gJsF7cahkWDPYlNvYKK+OrBZLAJUBzCym+Zsi+dfi1E=
-k8s.io/kubectl v0.23.3/go.mod h1:VBeeXNgLhSabu4/k0O7Q0YujgnA3+CLTUE0RcmF73yY=
+k8s.io/kubectl v0.23.1 h1:gmscOiV4Y4XIRIn14gQBBADoyyVrDZPbxRCTDga4RSA=
+k8s.io/kubectl v0.23.1/go.mod h1:Ui7dJKdUludF8yWAOSN7JZEkOuYixX5yF6E6NjoukKE=
 k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
-k8s.io/metrics v0.23.3/go.mod h1:Ut8TvkbsO4oMVeUzaTArvPrcw9QRFLs2XNzUlORjdYE=
+k8s.io/metrics v0.23.1/go.mod h1:qXvsM1KANrc+ZZeFwj6Phvf0NLiC+d3RwcsLcdGc+xs=
 k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
 k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-k8s.io/utils v0.0.0-20211116205334-6203023598ed h1:ck1fRPWPJWsMd8ZRFsWc6mh/zHp5fZ/shhbrgPUxDAE=
-k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
+k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b h1:wxEMGetGMur3J1xuGLQY7GEQYg9bZxKn3tKo5k/eYcs=
+k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
 oras.land/oras-go v1.1.0 h1:tfWM1RT7PzUwWphqHU6ptPU3ZhwVnSw/9nEGf519rYg=
 oras.land/oras-go v1.1.0/go.mod h1:1A7vR/0KknT2UkJVWh+xMi95I/AhK8ZrxrnUSmXN0bQ=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
@@ -1757,7 +1753,7 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.27/go.mod h1:tq2nT0Kx7W+/f2JVE+zxYtUhdjuELJkVpNz+x/QN5R4=
+sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.25/go.mod h1:Mlj9PNLmG9bZ6BHFwFKDo5afkpWyUISkb9Me0GnK66I=
 sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s=
 sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs=
 sigs.k8s.io/kustomize/api v0.10.1 h1:KgU7hfYoscuqag84kxtzKdEC3mKMb99DPI3a0eaV1d0=
@@ -1769,8 +1765,8 @@ sigs.k8s.io/kustomize/kyaml v0.13.0/go.mod h1:FTJxEZ86ScK184NpGSAQcfEqee0nul8oLC
 sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
 sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
 sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
-sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
-sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
+sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno=
+sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
 sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
 sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
 sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
diff --git a/internal/version/version.go b/internal/version/version.go
index edf8546f0..201eee359 100644
--- a/internal/version/version.go
+++ b/internal/version/version.go
@@ -29,7 +29,7 @@ var (
 	//
 	// Increment major number for new feature additions and behavioral changes.
 	// Increment minor number for bug fixes and performance enhancements.
-	version = "v3.8"
+	version = "v3.7"
 
 	// metadata is extra build time data
 	metadata = ""
diff --git a/pkg/action/install.go b/pkg/action/install.go
index 3872ed5c9..32be904b4 100644
--- a/pkg/action/install.go
+++ b/pkg/action/install.go
@@ -344,10 +344,8 @@ func (i *Install) RunWithContext(ctx context.Context, chrt *chart.Chart, vals ma
 		return rel, err
 	}
 	rChan := make(chan resultMessage)
-	doneChan := make(chan struct{})
-	defer close(doneChan)
 	go i.performInstall(rChan, rel, toBeAdopted, resources)
-	go i.handleContext(ctx, rChan, doneChan, rel)
+	go i.handleContext(ctx, rChan, rel)
 	result := <-rChan
 	//start preformInstall go routine
 	return result.r, result.e
@@ -418,14 +416,12 @@ func (i *Install) performInstall(c chan<- resultMessage, rel *release.Release, t
 
 	i.reportToRun(c, rel, nil)
 }
-func (i *Install) handleContext(ctx context.Context, c chan<- resultMessage, done chan struct{}, rel *release.Release) {
-	select {
-	case <-ctx.Done():
+func (i *Install) handleContext(ctx context.Context, c chan<- resultMessage, rel *release.Release) {
+	go func() {
+		<-ctx.Done()
 		err := ctx.Err()
 		i.reportToRun(c, rel, err)
-	case <-done:
-		return
-	}
+	}()
 }
 func (i *Install) reportToRun(c chan<- resultMessage, rel *release.Release, err error) {
 	i.Lock.Lock()
diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go
index c98b524bc..e228f52dc 100644
--- a/pkg/action/upgrade.go
+++ b/pkg/action/upgrade.go
@@ -326,11 +326,11 @@ func (u *Upgrade) performUpgrade(ctx context.Context, originalRelease, upgradedR
 	rChan := make(chan resultMessage)
 	ctxChan := make(chan resultMessage)
 	doneChan := make(chan interface{})
-	defer close(doneChan)
 	go u.releasingUpgrade(rChan, upgradedRelease, current, target, originalRelease)
 	go u.handleContext(ctx, doneChan, ctxChan, upgradedRelease)
 	select {
 	case result := <-rChan:
+		doneChan <- true
 		return result.r, result.e
 	case result := <-ctxChan:
 		return result.r, result.e
@@ -351,15 +351,17 @@ func (u *Upgrade) reportToPerformUpgrade(c chan<- resultMessage, rel *release.Re
 
 // Setup listener for SIGINT and SIGTERM
 func (u *Upgrade) handleContext(ctx context.Context, done chan interface{}, c chan<- resultMessage, upgradedRelease *release.Release) {
-	select {
-	case <-ctx.Done():
-		err := ctx.Err()
-
-		// when the atomic flag is set the ongoing release finish first and doesn't give time for the rollback happens.
-		u.reportToPerformUpgrade(c, upgradedRelease, kube.ResourceList{}, err)
-	case <-done:
-		return
-	}
+	go func() {
+		select {
+		case <-ctx.Done():
+			err := ctx.Err()
+
+			// when the atomic flag is set the ongoing release finish first and doesn't give time for the rollback happens.
+			u.reportToPerformUpgrade(c, upgradedRelease, kube.ResourceList{}, err)
+		case <-done:
+			return
+		}
+	}()
 }
 func (u *Upgrade) releasingUpgrade(c chan<- resultMessage, upgradedRelease *release.Release, current kube.ResourceList, target kube.ResourceList, originalRelease *release.Release) {
 	// pre-upgrade hooks
diff --git a/pkg/chartutil/validate_name.go b/pkg/chartutil/validate_name.go
index 05c090cb6..8c45d533b 100644
--- a/pkg/chartutil/validate_name.go
+++ b/pkg/chartutil/validate_name.go
@@ -40,15 +40,15 @@ var (
 	errMissingName = errors.New("no name provided")
 
 	// errInvalidName indicates that an invalid release name was provided
-	errInvalidName = fmt.Errorf(
+	errInvalidName = errors.New(fmt.Sprintf(
 		"invalid release name, must match regex %s and the length must not be longer than 53",
-		validName.String())
+		validName.String()))
 
 	// errInvalidKubernetesName indicates that the name does not meet the Kubernetes
 	// restrictions on metadata names.
-	errInvalidKubernetesName = fmt.Errorf(
+	errInvalidKubernetesName = errors.New(fmt.Sprintf(
 		"invalid metadata name, must match regex %s and the length must not be longer than 253",
-		validName.String())
+		validName.String()))
 )
 
 const (
diff --git a/pkg/downloader/chart_downloader.go b/pkg/downloader/chart_downloader.go
index 3feb5b702..ea228d9e6 100644
--- a/pkg/downloader/chart_downloader.go
+++ b/pkg/downloader/chart_downloader.go
@@ -23,7 +23,6 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/Masterminds/semver/v3"
 	"github.com/pkg/errors"
 
 	"helm.sh/helm/v3/internal/fileutil"
@@ -142,31 +141,22 @@ func (c *ChartDownloader) DownloadTo(ref, version, dest string) (string, *proven
 }
 
 func (c *ChartDownloader) getOciURI(ref, version string, u *url.URL) (*url.URL, error) {
-	var tag string
-	var err error
-
-	// Evaluate whether an explicit version has been provided. Otherwise, determine version to use
-	_, errSemVer := semver.NewVersion(version)
-	if errSemVer == nil {
-		tag = version
-	} else {
-		// Retrieve list of repository tags
-		tags, err := c.RegistryClient.Tags(strings.TrimPrefix(ref, fmt.Sprintf("%s://", registry.OCIScheme)))
-		if err != nil {
-			return nil, err
-		}
-		if len(tags) == 0 {
-			return nil, errors.Errorf("Unable to locate any tags in provided repository: %s", ref)
-		}
+	// Retrieve list of repository tags
+	tags, err := c.RegistryClient.Tags(strings.TrimPrefix(ref, fmt.Sprintf("%s://", registry.OCIScheme)))
+	if err != nil {
+		return nil, err
+	}
+	if len(tags) == 0 {
+		return nil, errors.Errorf("Unable to locate any tags in provided repository: %s", ref)
+	}
 
-		// Determine if version provided
-		// If empty, try to get the highest available tag
-		// If exact version, try to find it
-		// If semver constraint string, try to find a match
-		tag, err = registry.GetTagMatchingVersionOrConstraint(tags, version)
-		if err != nil {
-			return nil, err
-		}
+	// Determine if version provided
+	// If empty, try to get the highest available tag
+	// If exact version, try to find it
+	// If semver constraint string, try to find a match
+	tag, err := registry.GetTagMatchingVersionOrConstraint(tags, version)
+	if err != nil {
+		return nil, err
 	}
 
 	u.Path = fmt.Sprintf("%s:%s", u.Path, tag)
diff --git a/pkg/downloader/manager.go b/pkg/downloader/manager.go
index 18b28dde1..535ef387d 100644
--- a/pkg/downloader/manager.go
+++ b/pkg/downloader/manager.go
@@ -400,12 +400,12 @@ func parseOCIRef(chartRef string) (string, string, error) {
 func (m *Manager) safeMoveDeps(deps []*chart.Dependency, source, dest string) error {
 	existsInSourceDirectory := map[string]bool{}
 	isLocalDependency := map[string]bool{}
-	sourceFiles, err := os.ReadDir(source)
+	sourceFiles, err := ioutil.ReadDir(source)
 	if err != nil {
 		return err
 	}
 	// attempt to read destFiles; fail fast if we can't
-	destFiles, err := os.ReadDir(dest)
+	destFiles, err := ioutil.ReadDir(dest)
 	if err != nil {
 		return err
 	}
@@ -436,7 +436,7 @@ func (m *Manager) safeMoveDeps(deps []*chart.Dependency, source, dest string) er
 	}
 
 	fmt.Fprintln(m.Out, "Deleting outdated charts")
-	// find all files that exist in dest that do not exist in source; delete them (outdated dependencies)
+	// find all files that exist in dest that do not exist in source; delete them (outdated dependendencies)
 	for _, file := range destFiles {
 		if !file.IsDir() && !existsInSourceDirectory[file.Name()] {
 			fname := filepath.Join(dest, file.Name())
diff --git a/pkg/getter/getter.go b/pkg/getter/getter.go
index 7f830bac7..653b032fe 100644
--- a/pkg/getter/getter.go
+++ b/pkg/getter/getter.go
@@ -18,6 +18,7 @@ package getter
 
 import (
 	"bytes"
+	"net/http"
 	"time"
 
 	"github.com/pkg/errors"
@@ -43,6 +44,7 @@ type options struct {
 	version               string
 	registryClient        *registry.Client
 	timeout               time.Duration
+	transport             *http.Transport
 }
 
 // Option allows specifying various settings configurable by the user for overriding the defaults
@@ -119,6 +121,13 @@ func WithUntar() Option {
 	}
 }
 
+// WithTransport sets the http.Transport to allow overwriting the HTTPGetter default.
+func WithTransport(transport *http.Transport) Option {
+	return func(opts *options) {
+		opts.transport = transport
+	}
+}
+
 // Getter is an interface to support GET to the specified URL.
 type Getter interface {
 	// Get file content by url string
diff --git a/pkg/getter/httpgetter.go b/pkg/getter/httpgetter.go
index 454eb6eb6..6fe1aa71f 100644
--- a/pkg/getter/httpgetter.go
+++ b/pkg/getter/httpgetter.go
@@ -21,6 +21,7 @@ import (
 	"io"
 	"net/http"
 	"net/url"
+	"sync"
 
 	"github.com/pkg/errors"
 
@@ -31,7 +32,9 @@ import (
 
 // HTTPGetter is the default HTTP(/S) backend handler
 type HTTPGetter struct {
-	opts options
+	opts      options
+	transport *http.Transport
+	once      sync.Once
 }
 
 // Get performs a Get from repo.Getter and returns the body.
@@ -106,10 +109,20 @@ func NewHTTPGetter(options ...Option) (Getter, error) {
 }
 
 func (g *HTTPGetter) httpClient() (*http.Client, error) {
-	transport := &http.Transport{
-		DisableCompression: true,
-		Proxy:              http.ProxyFromEnvironment,
+	if g.opts.transport != nil {
+		return &http.Client{
+			Transport: g.opts.transport,
+			Timeout:   g.opts.timeout,
+		}, nil
 	}
+
+	g.once.Do(func() {
+		g.transport = &http.Transport{
+			DisableCompression: true,
+			Proxy:              http.ProxyFromEnvironment,
+		}
+	})
+
 	if (g.opts.certFile != "" && g.opts.keyFile != "") || g.opts.caFile != "" {
 		tlsConf, err := tlsutil.NewClientTLS(g.opts.certFile, g.opts.keyFile, g.opts.caFile)
 		if err != nil {
@@ -123,21 +136,21 @@ func (g *HTTPGetter) httpClient() (*http.Client, error) {
 		}
 		tlsConf.ServerName = sni
 
-		transport.TLSClientConfig = tlsConf
+		g.transport.TLSClientConfig = tlsConf
 	}
 
 	if g.opts.insecureSkipVerifyTLS {
-		if transport.TLSClientConfig == nil {
-			transport.TLSClientConfig = &tls.Config{
+		if g.transport.TLSClientConfig == nil {
+			g.transport.TLSClientConfig = &tls.Config{
 				InsecureSkipVerify: true,
 			}
 		} else {
-			transport.TLSClientConfig.InsecureSkipVerify = true
+			g.transport.TLSClientConfig.InsecureSkipVerify = true
 		}
 	}
 
 	client := &http.Client{
-		Transport: transport,
+		Transport: g.transport,
 		Timeout:   g.opts.timeout,
 	}
 
diff --git a/pkg/postrender/exec.go b/pkg/postrender/exec.go
index 167e737d6..1de70b024 100644
--- a/pkg/postrender/exec.go
+++ b/pkg/postrender/exec.go
@@ -27,24 +27,23 @@ import (
 
 type execRender struct {
 	binaryPath string
-	args       []string
 }
 
 // NewExec returns a PostRenderer implementation that calls the provided binary.
 // It returns an error if the binary cannot be found. If the path does not
 // contain any separators, it will search in $PATH, otherwise it will resolve
 // any relative paths to a fully qualified path
-func NewExec(binaryPath string, args ...string) (PostRenderer, error) {
+func NewExec(binaryPath string) (PostRenderer, error) {
 	fullPath, err := getFullPath(binaryPath)
 	if err != nil {
 		return nil, err
 	}
-	return &execRender{fullPath, args}, nil
+	return &execRender{fullPath}, nil
 }
 
 // Run the configured binary for the post render
 func (p *execRender) Run(renderedManifests *bytes.Buffer) (*bytes.Buffer, error) {
-	cmd := exec.Command(p.binaryPath, p.args...)
+	cmd := exec.Command(p.binaryPath)
 	stdin, err := cmd.StdinPipe()
 	if err != nil {
 		return nil, err
diff --git a/pkg/registry/client.go b/pkg/registry/client.go
index 0107136d3..213a9dc49 100644
--- a/pkg/registry/client.go
+++ b/pkg/registry/client.go
@@ -112,13 +112,6 @@ func NewClient(options ...ClientOption) (*Client, error) {
 					return registryauth.EmptyCredential, errors.New("unable to retrieve credentials")
 				}
 
-				// A blank returned username and password value is a bearer token
-				if username == "" && password != "" {
-					return registryauth.Credential{
-						RefreshToken: password,
-					}, nil
-				}
-
 				return registryauth.Credential{
 					Username: username,
 					Password: password,
@@ -303,8 +296,9 @@ func (c *Client) Pull(ref string, options ...PullOption) (*PullResult, error) {
 
 	numDescriptors := len(descriptors)
 	if numDescriptors < minNumDescriptors {
-		return nil, fmt.Errorf("manifest does not contain minimum number of descriptors (%d), descriptors found: %d",
-			minNumDescriptors, numDescriptors)
+		return nil, errors.New(
+			fmt.Sprintf("manifest does not contain minimum number of descriptors (%d), descriptors found: %d",
+				minNumDescriptors, numDescriptors))
 	}
 	var configDescriptor *ocispec.Descriptor
 	var chartDescriptor *ocispec.Descriptor
@@ -324,19 +318,22 @@ func (c *Client) Pull(ref string, options ...PullOption) (*PullResult, error) {
 		}
 	}
 	if configDescriptor == nil {
-		return nil, fmt.Errorf("could not load config with mediatype %s", ConfigMediaType)
+		return nil, errors.New(
+			fmt.Sprintf("could not load config with mediatype %s", ConfigMediaType))
 	}
 	if operation.withChart && chartDescriptor == nil {
-		return nil, fmt.Errorf("manifest does not contain a layer with mediatype %s",
-			ChartLayerMediaType)
+		return nil, errors.New(
+			fmt.Sprintf("manifest does not contain a layer with mediatype %s",
+				ChartLayerMediaType))
 	}
 	var provMissing bool
 	if operation.withProv && provDescriptor == nil {
 		if operation.ignoreMissingProv {
 			provMissing = true
 		} else {
-			return nil, fmt.Errorf("manifest does not contain a layer with mediatype %s",
-				ProvLayerMediaType)
+			return nil, errors.New(
+				fmt.Sprintf("manifest does not contain a layer with mediatype %s",
+					ProvLayerMediaType))
 		}
 	}
 	result := &PullResult{
diff --git a/pkg/releaseutil/kind_sorter.go b/pkg/releaseutil/kind_sorter.go
index 1d1874cfa..a340dfc29 100644
--- a/pkg/releaseutil/kind_sorter.go
+++ b/pkg/releaseutil/kind_sorter.go
@@ -61,7 +61,6 @@ var InstallOrder KindSortOrder = []string{
 	"StatefulSet",
 	"Job",
 	"CronJob",
-	"IngressClass",
 	"Ingress",
 	"APIService",
 }
@@ -72,7 +71,6 @@ var InstallOrder KindSortOrder = []string{
 var UninstallOrder KindSortOrder = []string{
 	"APIService",
 	"Ingress",
-	"IngressClass",
 	"Service",
 	"CronJob",
 	"Job",
diff --git a/pkg/uploader/chart_uploader.go b/pkg/uploader/chart_uploader.go
index d7e940406..2aa04937a 100644
--- a/pkg/uploader/chart_uploader.go
+++ b/pkg/uploader/chart_uploader.go
@@ -46,7 +46,7 @@ func (c *ChartUploader) UploadTo(ref, remote string) error {
 	}
 
 	if u.Scheme == "" {
-		return fmt.Errorf("scheme prefix missing from remote (e.g. \"%s://\")", registry.OCIScheme)
+		return errors.New(fmt.Sprintf("scheme prefix missing from remote (e.g. \"%s://\")", registry.OCIScheme))
 	}
 
 	p, err := c.Pushers.ByScheme(u.Scheme)


Test patch:
diff --git a/cmd/helm/completion_test.go b/cmd/helm/completion_test.go
index 1143d6445..6d53616d0 100644
--- a/cmd/helm/completion_test.go
+++ b/cmd/helm/completion_test.go
@@ -47,10 +47,10 @@ func checkFileCompletion(t *testing.T, cmdName string, shouldBePerformed bool) {
 	}
 	if !strings.Contains(out, "ShellCompDirectiveNoFileComp") != shouldBePerformed {
 		if shouldBePerformed {
-			t.Errorf("Unexpected directive ShellCompDirectiveNoFileComp when completing '%s'", cmdName)
+			t.Error(fmt.Sprintf("Unexpected directive ShellCompDirectiveNoFileComp when completing '%s'", cmdName))
 		} else {
 
-			t.Errorf("Did not receive directive ShellCompDirectiveNoFileComp when completing '%s'", cmdName)
+			t.Error(fmt.Sprintf("Did not receive directive ShellCompDirectiveNoFileComp when completing '%s'", cmdName))
 		}
 		t.Log(out)
 	}
diff --git a/cmd/helm/push_test.go b/cmd/helm/push_test.go
deleted file mode 100644
index 8e56d99dc..000000000
--- a/cmd/helm/push_test.go
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-Copyright The Helm Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package main
-
-import (
-	"testing"
-)
-
-func TestPushFileCompletion(t *testing.T) {
-	checkFileCompletion(t, "push", true)
-	checkFileCompletion(t, "push package.tgz", false)
-	checkFileCompletion(t, "push package.tgz oci://localhost:5000", false)
-}
diff --git a/cmd/helm/registry_login_test.go b/cmd/helm/registry_login_test.go
deleted file mode 100644
index 517fe08e1..000000000
--- a/cmd/helm/registry_login_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-Copyright The Helm Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package main
-
-import (
-	"testing"
-)
-
-func TestRegistryLoginFileCompletion(t *testing.T) {
-	checkFileCompletion(t, "registry login", false)
-}
diff --git a/cmd/helm/registry_logout_test.go b/cmd/helm/registry_logout_test.go
deleted file mode 100644
index 31f716725..000000000
--- a/cmd/helm/registry_logout_test.go
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-Copyright The Helm Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package main
-
-import (
-	"testing"
-)
-
-func TestRegistryLogoutFileCompletion(t *testing.T) {
-	checkFileCompletion(t, "registry logout", false)
-}
diff --git a/cmd/helm/root_unix_test.go b/cmd/helm/root_unix_test.go
index c253fb81e..36abc0184 100644
--- a/cmd/helm/root_unix_test.go
+++ b/cmd/helm/root_unix_test.go
@@ -22,6 +22,7 @@ package main
 import (
 	"bytes"
 	"io"
+	"io/ioutil"
 	"os"
 	"path/filepath"
 	"strings"
@@ -49,7 +50,11 @@ func checkPermsStderr() (string, error) {
 }
 
 func TestCheckPerms(t *testing.T) {
-	tdir := t.TempDir()
+	tdir, err := ioutil.TempDir("", "helmtest")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tdir)
 	tfile := filepath.Join(tdir, "testconfig")
 	fh, err := os.OpenFile(tfile, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0440)
 	if err != nil {
diff --git a/cmd/helm/testdata/output/version-client-shorthand.txt b/cmd/helm/testdata/output/version-client-shorthand.txt
index 3d82b4b9e..80be7bced 100644
--- a/cmd/helm/testdata/output/version-client-shorthand.txt
+++ b/cmd/helm/testdata/output/version-client-shorthand.txt
@@ -1,1 +1,1 @@
-version.BuildInfo{Version:"v3.8", GitCommit:"", GitTreeState:"", GoVersion:""}
+version.BuildInfo{Version:"v3.7", GitCommit:"", GitTreeState:"", GoVersion:""}
diff --git a/cmd/helm/testdata/output/version-client.txt b/cmd/helm/testdata/output/version-client.txt
index 3d82b4b9e..80be7bced 100644
--- a/cmd/helm/testdata/output/version-client.txt
+++ b/cmd/helm/testdata/output/version-client.txt
@@ -1,1 +1,1 @@
-version.BuildInfo{Version:"v3.8", GitCommit:"", GitTreeState:"", GoVersion:""}
+version.BuildInfo{Version:"v3.7", GitCommit:"", GitTreeState:"", GoVersion:""}
diff --git a/cmd/helm/testdata/output/version-short.txt b/cmd/helm/testdata/output/version-short.txt
index 872da761f..5a2f3db22 100644
--- a/cmd/helm/testdata/output/version-short.txt
+++ b/cmd/helm/testdata/output/version-short.txt
@@ -1,1 +1,1 @@
-v3.8
+v3.7
diff --git a/cmd/helm/testdata/output/version-template.txt b/cmd/helm/testdata/output/version-template.txt
index c1c5a5604..c501b0bab 100644
--- a/cmd/helm/testdata/output/version-template.txt
+++ b/cmd/helm/testdata/output/version-template.txt
@@ -1,1 +1,1 @@
-Version: v3.8
\ No newline at end of file
+Version: v3.7
\ No newline at end of file
diff --git a/cmd/helm/testdata/output/version.txt b/cmd/helm/testdata/output/version.txt
index 3d82b4b9e..80be7bced 100644
--- a/cmd/helm/testdata/output/version.txt
+++ b/cmd/helm/testdata/output/version.txt
@@ -1,1 +1,1 @@
-version.BuildInfo{Version:"v3.8", GitCommit:"", GitTreeState:"", GoVersion:""}
+version.BuildInfo{Version:"v3.7", GitCommit:"", GitTreeState:"", GoVersion:""}
diff --git a/internal/fileutil/fileutil_test.go b/internal/fileutil/fileutil_test.go
index 76cd8f074..9a4bc32c9 100644
--- a/internal/fileutil/fileutil_test.go
+++ b/internal/fileutil/fileutil_test.go
@@ -25,14 +25,18 @@ import (
 )
 
 func TestAtomicWriteFile(t *testing.T) {
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helm-tmp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	testpath := filepath.Join(dir, "test")
 	stringContent := "Test content"
 	reader := bytes.NewReader([]byte(stringContent))
 	mode := os.FileMode(0644)
 
-	err := AtomicWriteFile(testpath, reader, mode)
+	err = AtomicWriteFile(testpath, reader, mode)
 	if err != nil {
 		t.Errorf("AtomicWriteFile error: %s", err)
 	}
diff --git a/internal/third_party/dep/fs/fs_test.go b/internal/third_party/dep/fs/fs_test.go
index c9e6ce65b..98a31aec6 100644
--- a/internal/third_party/dep/fs/fs_test.go
+++ b/internal/third_party/dep/fs/fs_test.go
@@ -46,9 +46,13 @@ var (
 )
 
 func TestRenameWithFallback(t *testing.T) {
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helm-tmp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
-	if err := RenameWithFallback(filepath.Join(dir, "does_not_exists"), filepath.Join(dir, "dst")); err == nil {
+	if err = RenameWithFallback(filepath.Join(dir, "does_not_exists"), filepath.Join(dir, "dst")); err == nil {
 		t.Fatal("expected an error for non existing file, but got nil")
 	}
 
@@ -60,27 +64,31 @@ func TestRenameWithFallback(t *testing.T) {
 		srcf.Close()
 	}
 
-	if err := RenameWithFallback(srcpath, filepath.Join(dir, "dst")); err != nil {
+	if err = RenameWithFallback(srcpath, filepath.Join(dir, "dst")); err != nil {
 		t.Fatal(err)
 	}
 
 	srcpath = filepath.Join(dir, "a")
-	if err := os.MkdirAll(srcpath, 0777); err != nil {
+	if err = os.MkdirAll(srcpath, 0777); err != nil {
 		t.Fatal(err)
 	}
 
 	dstpath := filepath.Join(dir, "b")
-	if err := os.MkdirAll(dstpath, 0777); err != nil {
+	if err = os.MkdirAll(dstpath, 0777); err != nil {
 		t.Fatal(err)
 	}
 
-	if err := RenameWithFallback(srcpath, dstpath); err == nil {
+	if err = RenameWithFallback(srcpath, dstpath); err == nil {
 		t.Fatal("expected an error if dst is an existing directory, but got nil")
 	}
 }
 
 func TestCopyDir(t *testing.T) {
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helm-tmp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	srcdir := filepath.Join(dir, "src")
 	if err := os.MkdirAll(srcdir, 0755); err != nil {
@@ -100,7 +108,7 @@ func TestCopyDir(t *testing.T) {
 	for i, file := range files {
 		fn := filepath.Join(srcdir, file.path)
 		dn := filepath.Dir(fn)
-		if err := os.MkdirAll(dn, 0755); err != nil {
+		if err = os.MkdirAll(dn, 0755); err != nil {
 			t.Fatal(err)
 		}
 
@@ -181,10 +189,14 @@ func TestCopyDirFail_SrcInaccessible(t *testing.T) {
 	})
 	defer cleanup()
 
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helm-tmp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	dstdir = filepath.Join(dir, "dst")
-	if err := CopyDir(srcdir, dstdir); err == nil {
+	if err = CopyDir(srcdir, dstdir); err == nil {
 		t.Fatalf("expected error for CopyDir(%s, %s), got none", srcdir, dstdir)
 	}
 }
@@ -206,10 +218,14 @@ func TestCopyDirFail_DstInaccessible(t *testing.T) {
 
 	var srcdir, dstdir string
 
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helm-tmp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	srcdir = filepath.Join(dir, "src")
-	if err := os.MkdirAll(srcdir, 0755); err != nil {
+	if err = os.MkdirAll(srcdir, 0755); err != nil {
 		t.Fatal(err)
 	}
 
@@ -226,9 +242,12 @@ func TestCopyDirFail_DstInaccessible(t *testing.T) {
 
 func TestCopyDirFail_SrcIsNotDir(t *testing.T) {
 	var srcdir, dstdir string
-	var err error
 
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helm-tmp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	srcdir = filepath.Join(dir, "src")
 	if _, err = os.Create(srcdir); err != nil {
@@ -249,9 +268,12 @@ func TestCopyDirFail_SrcIsNotDir(t *testing.T) {
 
 func TestCopyDirFail_DstExists(t *testing.T) {
 	var srcdir, dstdir string
-	var err error
 
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helm-tmp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	srcdir = filepath.Join(dir, "src")
 	if err = os.MkdirAll(srcdir, 0755); err != nil {
@@ -292,10 +314,14 @@ func TestCopyDirFailOpen(t *testing.T) {
 
 	var srcdir, dstdir string
 
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helm-tmp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	srcdir = filepath.Join(dir, "src")
-	if err := os.MkdirAll(srcdir, 0755); err != nil {
+	if err = os.MkdirAll(srcdir, 0755); err != nil {
 		t.Fatal(err)
 	}
 
@@ -319,7 +345,11 @@ func TestCopyDirFailOpen(t *testing.T) {
 }
 
 func TestCopyFile(t *testing.T) {
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helm-tmp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	srcf, err := os.Create(filepath.Join(dir, "srcfile"))
 	if err != nil {
@@ -375,7 +405,13 @@ func cleanUpDir(dir string) {
 }
 
 func TestCopyFileSymlink(t *testing.T) {
-	tempdir := t.TempDir()
+	var tempdir, err = ioutil.TempDir("", "gotest")
+
+	if err != nil {
+		t.Fatalf("failed to create directory: %s", err)
+	}
+
+	defer cleanUpDir(tempdir)
 
 	testcases := map[string]string{
 		filepath.Join("./testdata/symlinks/file-symlink"):         filepath.Join(tempdir, "dst-file"),
@@ -441,7 +477,11 @@ func TestCopyFileFail(t *testing.T) {
 		t.Skip("Skipping for root user")
 	}
 
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helm-tmp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	srcf, err := os.Create(filepath.Join(dir, "srcfile"))
 	if err != nil {
@@ -477,7 +517,11 @@ func TestCopyFileFail(t *testing.T) {
 // files this function creates. It is the caller's responsibility to call
 // this function before the test is done running, whether there's an error or not.
 func setupInaccessibleDir(t *testing.T, op func(dir string) error) func() {
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helm-tmp")
+	if err != nil {
+		t.Fatal(err)
+		return nil // keep compiler happy
+	}
 
 	subdir := filepath.Join(dir, "dir")
 
@@ -485,6 +529,9 @@ func setupInaccessibleDir(t *testing.T, op func(dir string) error) func() {
 		if err := os.Chmod(subdir, 0777); err != nil {
 			t.Error(err)
 		}
+		if err := os.RemoveAll(dir); err != nil {
+			t.Error(err)
+		}
 	}
 
 	if err := os.Mkdir(subdir, 0777); err != nil {
@@ -570,10 +617,14 @@ func TestIsSymlink(t *testing.T) {
 		t.Skip("Skipping for root user")
 	}
 
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helm-tmp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	dirPath := filepath.Join(dir, "directory")
-	if err := os.MkdirAll(dirPath, 0777); err != nil {
+	if err = os.MkdirAll(dirPath, 0777); err != nil {
 		t.Fatal(err)
 	}
 
diff --git a/pkg/action/action_test.go b/pkg/action/action_test.go
index c816c84af..190d00cae 100644
--- a/pkg/action/action_test.go
+++ b/pkg/action/action_test.go
@@ -18,6 +18,7 @@ package action
 import (
 	"flag"
 	"io/ioutil"
+	"os"
 	"testing"
 
 	fakeclientset "k8s.io/client-go/kubernetes/fake"
@@ -37,6 +38,13 @@ var verbose = flag.Bool("test.log", false, "enable test logging")
 func actionConfigFixture(t *testing.T) *Configuration {
 	t.Helper()
 
+	tdir, err := ioutil.TempDir("", "helm-action-test")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	t.Cleanup(func() { os.RemoveAll(tdir) })
+
 	registryClient, err := registry.NewClient()
 	if err != nil {
 		t.Fatal(err)
diff --git a/pkg/action/dependency_test.go b/pkg/action/dependency_test.go
index 0f35a0614..b5032a377 100644
--- a/pkg/action/dependency_test.go
+++ b/pkg/action/dependency_test.go
@@ -18,6 +18,7 @@ package action
 
 import (
 	"bytes"
+	"io/ioutil"
 	"os"
 	"path/filepath"
 	"testing"
@@ -67,7 +68,11 @@ func TestList(t *testing.T) {
 // chart names do not cause resolution problems.
 func TestDependencyStatus_Dashes(t *testing.T) {
 	// Make a temp dir
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helmtest-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	chartpath := filepath.Join(dir, "charts")
 	if err := os.MkdirAll(chartpath, 0700); err != nil {
@@ -76,7 +81,7 @@ func TestDependencyStatus_Dashes(t *testing.T) {
 
 	// Add some fake charts
 	first := buildChart(withName("first-chart"))
-	_, err := chartutil.Save(first, chartpath)
+	_, err = chartutil.Save(first, chartpath)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -101,7 +106,11 @@ func TestDependencyStatus_Dashes(t *testing.T) {
 
 func TestStatArchiveForStatus(t *testing.T) {
 	// Make a temp dir
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helmtest-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	chartpath := filepath.Join(dir, "charts")
 	if err := os.MkdirAll(chartpath, 0700); err != nil {
diff --git a/pkg/action/install_test.go b/pkg/action/install_test.go
index 45e5a2670..3d08d7889 100644
--- a/pkg/action/install_test.go
+++ b/pkg/action/install_test.go
@@ -20,6 +20,7 @@ import (
 	"context"
 	"fmt"
 	"io/ioutil"
+	"log"
 	"os"
 	"path/filepath"
 	"regexp"
@@ -28,7 +29,6 @@ import (
 	"time"
 
 	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 
 	"helm.sh/helm/v3/internal/test"
 	"helm.sh/helm/v3/pkg/chart"
@@ -56,12 +56,9 @@ func installAction(t *testing.T) *Install {
 
 func TestInstallRelease(t *testing.T) {
 	is := assert.New(t)
-	req := require.New(t)
-
 	instAction := installAction(t)
 	vals := map[string]interface{}{}
-	ctx, done := context.WithCancel(context.Background())
-	res, err := instAction.RunWithContext(ctx, buildChart(), vals)
+	res, err := instAction.Run(buildChart(), vals)
 	if err != nil {
 		t.Fatalf("Failed install: %s", err)
 	}
@@ -80,14 +77,6 @@ func TestInstallRelease(t *testing.T) {
 	is.NotEqual(len(rel.Manifest), 0)
 	is.Contains(rel.Manifest, "---\n# Source: hello/templates/hello\nhello: world")
 	is.Equal(rel.Info.Description, "Install complete")
-
-	// Detecting previous bug where context termination after successful release
-	// caused release to fail.
-	done()
-	time.Sleep(time.Millisecond * 100)
-	lastRelease, err := instAction.cfg.Releases.Last(rel.Name)
-	req.NoError(err)
-	is.Equal(lastRelease.Info.Status, release.StatusDeployed)
 }
 
 func TestInstallReleaseWithValues(t *testing.T) {
@@ -551,11 +540,15 @@ func TestInstallReleaseOutputDir(t *testing.T) {
 	instAction := installAction(t)
 	vals := map[string]interface{}{}
 
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "output-dir")
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	instAction.OutputDir = dir
 
-	_, err := instAction.Run(buildChart(withSampleTemplates(), withMultipleManifestTemplate()), vals)
+	_, err = instAction.Run(buildChart(withSampleTemplates(), withMultipleManifestTemplate()), vals)
 	if err != nil {
 		t.Fatalf("Failed install: %s", err)
 	}
@@ -583,7 +576,11 @@ func TestInstallOutputDirWithReleaseName(t *testing.T) {
 	instAction := installAction(t)
 	vals := map[string]interface{}{}
 
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "output-dir")
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	instAction.OutputDir = dir
 	instAction.UseReleaseName = true
@@ -591,7 +588,7 @@ func TestInstallOutputDirWithReleaseName(t *testing.T) {
 
 	newDir := filepath.Join(dir, instAction.ReleaseName)
 
-	_, err := instAction.Run(buildChart(withSampleTemplates(), withMultipleManifestTemplate()), vals)
+	_, err = instAction.Run(buildChart(withSampleTemplates(), withMultipleManifestTemplate()), vals)
 	if err != nil {
 		t.Fatalf("Failed install: %s", err)
 	}
diff --git a/pkg/action/upgrade_test.go b/pkg/action/upgrade_test.go
index 62922b373..7c286093e 100644
--- a/pkg/action/upgrade_test.go
+++ b/pkg/action/upgrade_test.go
@@ -40,33 +40,6 @@ func upgradeAction(t *testing.T) *Upgrade {
 	return upAction
 }
 
-func TestUpgradeRelease_Success(t *testing.T) {
-	is := assert.New(t)
-	req := require.New(t)
-
-	upAction := upgradeAction(t)
-	rel := releaseStub()
-	rel.Name = "previous-release"
-	rel.Info.Status = release.StatusDeployed
-	req.NoError(upAction.cfg.Releases.Create(rel))
-
-	upAction.Wait = true
-	vals := map[string]interface{}{}
-
-	ctx, done := context.WithCancel(context.Background())
-	res, err := upAction.RunWithContext(ctx, rel.Name, buildChart(), vals)
-	done()
-	req.NoError(err)
-	is.Equal(res.Info.Status, release.StatusDeployed)
-
-	// Detecting previous bug where context termination after successful release
-	// caused release to fail.
-	time.Sleep(time.Millisecond * 100)
-	lastRelease, err := upAction.cfg.Releases.Last(rel.Name)
-	req.NoError(err)
-	is.Equal(lastRelease.Info.Status, release.StatusDeployed)
-}
-
 func TestUpgradeRelease_Wait(t *testing.T) {
 	is := assert.New(t)
 	req := require.New(t)
diff --git a/pkg/chart/loader/load_test.go b/pkg/chart/loader/load_test.go
index a737098b4..9605b3152 100644
--- a/pkg/chart/loader/load_test.go
+++ b/pkg/chart/loader/load_test.go
@@ -403,7 +403,11 @@ func TestLoadV2WithReqs(t *testing.T) {
 }
 
 func TestLoadInvalidArchive(t *testing.T) {
-	tmpdir := t.TempDir()
+	tmpdir, err := ioutil.TempDir("", "helm-test-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmpdir)
 
 	writeTar := func(filename, internalPath string, body []byte) {
 		dest, err := os.Create(filename)
@@ -455,7 +459,7 @@ func TestLoadInvalidArchive(t *testing.T) {
 	} {
 		illegalChart := filepath.Join(tmpdir, tt.chartname)
 		writeTar(illegalChart, tt.internal, []byte("hello: world"))
-		_, err := Load(illegalChart)
+		_, err = Load(illegalChart)
 		if err == nil {
 			t.Fatal("expected error when unpacking illegal files")
 		}
@@ -467,7 +471,7 @@ func TestLoadInvalidArchive(t *testing.T) {
 	// Make sure that absolute path gets interpreted as relative
 	illegalChart := filepath.Join(tmpdir, "abs-path.tgz")
 	writeTar(illegalChart, "/Chart.yaml", []byte("hello: world"))
-	_, err := Load(illegalChart)
+	_, err = Load(illegalChart)
 	if err.Error() != "validation: chart.metadata.name is required" {
 		t.Error(err)
 	}
diff --git a/pkg/chartutil/capabilities_test.go b/pkg/chartutil/capabilities_test.go
index ebc84aadb..c14b6620b 100644
--- a/pkg/chartutil/capabilities_test.go
+++ b/pkg/chartutil/capabilities_test.go
@@ -62,8 +62,8 @@ func TestDefaultCapabilities(t *testing.T) {
 func TestDefaultCapabilitiesHelmVersion(t *testing.T) {
 	hv := DefaultCapabilities.HelmVersion
 
-	if hv.Version != "v3.8" {
-		t.Errorf("Expected default HelmVersion to be v3.8, got %q", hv.Version)
+	if hv.Version != "v3.7" {
+		t.Errorf("Expected default HelmVersion to be v3.7, got %q", hv.Version)
 	}
 }
 
diff --git a/pkg/chartutil/create_test.go b/pkg/chartutil/create_test.go
index f123a37cd..9a473fc59 100644
--- a/pkg/chartutil/create_test.go
+++ b/pkg/chartutil/create_test.go
@@ -28,7 +28,11 @@ import (
 )
 
 func TestCreate(t *testing.T) {
-	tdir := t.TempDir()
+	tdir, err := ioutil.TempDir("", "helm-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tdir)
 
 	c, err := Create("foo", tdir)
 	if err != nil {
@@ -66,7 +70,11 @@ func TestCreate(t *testing.T) {
 }
 
 func TestCreateFrom(t *testing.T) {
-	tdir := t.TempDir()
+	tdir, err := ioutil.TempDir("", "helm-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tdir)
 
 	cf := &chart.Metadata{
 		APIVersion: chart.APIVersionV1,
@@ -112,7 +120,11 @@ func TestCreateFrom(t *testing.T) {
 
 // TestCreate_Overwrite is a regression test for making sure that files are overwritten.
 func TestCreate_Overwrite(t *testing.T) {
-	tdir := t.TempDir()
+	tdir, err := ioutil.TempDir("", "helm-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tdir)
 
 	var errlog bytes.Buffer
 
diff --git a/pkg/chartutil/expand_test.go b/pkg/chartutil/expand_test.go
index f31a3d290..9a85e3247 100644
--- a/pkg/chartutil/expand_test.go
+++ b/pkg/chartutil/expand_test.go
@@ -17,13 +17,18 @@ limitations under the License.
 package chartutil
 
 import (
+	"io/ioutil"
 	"os"
 	"path/filepath"
 	"testing"
 )
 
 func TestExpand(t *testing.T) {
-	dest := t.TempDir()
+	dest, err := ioutil.TempDir("", "helm-testing-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dest)
 
 	reader, err := os.Open("testdata/frobnitz-1.2.3.tgz")
 	if err != nil {
@@ -76,7 +81,11 @@ func TestExpand(t *testing.T) {
 }
 
 func TestExpandFile(t *testing.T) {
-	dest := t.TempDir()
+	dest, err := ioutil.TempDir("", "helm-testing-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dest)
 
 	if err := ExpandFile(dest, "testdata/frobnitz-1.2.3.tgz"); err != nil {
 		t.Fatal(err)
diff --git a/pkg/chartutil/save_test.go b/pkg/chartutil/save_test.go
index 6914cd200..b4951535a 100644
--- a/pkg/chartutil/save_test.go
+++ b/pkg/chartutil/save_test.go
@@ -21,6 +21,7 @@ import (
 	"bytes"
 	"compress/gzip"
 	"io"
+	"io/ioutil"
 	"os"
 	"path"
 	"path/filepath"
@@ -128,7 +129,11 @@ func TestSavePreservesTimestamps(t *testing.T) {
 	// written timestamp for the files.
 	initialCreateTime := time.Now().Add(-1 * time.Second)
 
-	tmp := t.TempDir()
+	tmp, err := ioutil.TempDir("", "helm-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmp)
 
 	c := &chart.Chart{
 		Metadata: &chart.Metadata{
@@ -198,7 +203,11 @@ func retrieveAllHeadersFromTar(path string) ([]*tar.Header, error) {
 }
 
 func TestSaveDir(t *testing.T) {
-	tmp := t.TempDir()
+	tmp, err := ioutil.TempDir("", "helm-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmp)
 
 	c := &chart.Chart{
 		Metadata: &chart.Metadata{
diff --git a/pkg/cli/environment_test.go b/pkg/cli/environment_test.go
index d2affa79d..1c3dc815e 100644
--- a/pkg/cli/environment_test.go
+++ b/pkg/cli/environment_test.go
@@ -51,9 +51,9 @@ func TestEnvSettings(t *testing.T) {
 		ns, kcontext string
 		debug        bool
 		maxhistory   int
-		kubeAsUser   string
-		kubeAsGroups []string
-		kubeCaFile   string
+		kAsUser      string
+		kAsGroups    []string
+		kCaFile      string
 	}{
 		{
 			name:       "defaults",
@@ -61,35 +61,35 @@ func TestEnvSettings(t *testing.T) {
 			maxhistory: defaultMaxHistory,
 		},
 		{
-			name:         "with flags set",
-			args:         "--debug --namespace=myns --kube-as-user=poro --kube-as-group=admins --kube-as-group=teatime --kube-as-group=snackeaters --kube-ca-file=/tmp/ca.crt",
-			ns:           "myns",
-			debug:        true,
-			maxhistory:   defaultMaxHistory,
-			kubeAsUser:   "poro",
-			kubeAsGroups: []string{"admins", "teatime", "snackeaters"},
-			kubeCaFile:   "/tmp/ca.crt",
+			name:       "with flags set",
+			args:       "--debug --namespace=myns --kube-as-user=poro --kube-as-group=admins --kube-as-group=teatime --kube-as-group=snackeaters --kube-ca-file=/tmp/ca.crt",
+			ns:         "myns",
+			debug:      true,
+			maxhistory: defaultMaxHistory,
+			kAsUser:    "poro",
+			kAsGroups:  []string{"admins", "teatime", "snackeaters"},
+			kCaFile:    "/tmp/ca.crt",
 		},
 		{
-			name:         "with envvars set",
-			envvars:      map[string]string{"HELM_DEBUG": "1", "HELM_NAMESPACE": "yourns", "HELM_KUBEASUSER": "pikachu", "HELM_KUBEASGROUPS": ",,,operators,snackeaters,partyanimals", "HELM_MAX_HISTORY": "5", "HELM_KUBECAFILE": "/tmp/ca.crt"},
-			ns:           "yourns",
-			maxhistory:   5,
-			debug:        true,
-			kubeAsUser:   "pikachu",
-			kubeAsGroups: []string{"operators", "snackeaters", "partyanimals"},
-			kubeCaFile:   "/tmp/ca.crt",
+			name:       "with envvars set",
+			envvars:    map[string]string{"HELM_DEBUG": "1", "HELM_NAMESPACE": "yourns", "HELM_KUBEASUSER": "pikachu", "HELM_KUBEASGROUPS": ",,,operators,snackeaters,partyanimals", "HELM_MAX_HISTORY": "5", "HELM_KUBECAFILE": "/tmp/ca.crt"},
+			ns:         "yourns",
+			maxhistory: 5,
+			debug:      true,
+			kAsUser:    "pikachu",
+			kAsGroups:  []string{"operators", "snackeaters", "partyanimals"},
+			kCaFile:    "/tmp/ca.crt",
 		},
 		{
-			name:         "with flags and envvars set",
-			args:         "--debug --namespace=myns --kube-as-user=poro --kube-as-group=admins --kube-as-group=teatime --kube-as-group=snackeaters --kube-ca-file=/my/ca.crt",
-			envvars:      map[string]string{"HELM_DEBUG": "1", "HELM_NAMESPACE": "yourns", "HELM_KUBEASUSER": "pikachu", "HELM_KUBEASGROUPS": ",,,operators,snackeaters,partyanimals", "HELM_MAX_HISTORY": "5", "HELM_KUBECAFILE": "/tmp/ca.crt"},
-			ns:           "myns",
-			debug:        true,
-			maxhistory:   5,
-			kubeAsUser:   "poro",
-			kubeAsGroups: []string{"admins", "teatime", "snackeaters"},
-			kubeCaFile:   "/my/ca.crt",
+			name:       "with flags and envvars set",
+			args:       "--debug --namespace=myns --kube-as-user=poro --kube-as-group=admins --kube-as-group=teatime --kube-as-group=snackeaters --kube-ca-file=/my/ca.crt",
+			envvars:    map[string]string{"HELM_DEBUG": "1", "HELM_NAMESPACE": "yourns", "HELM_KUBEASUSER": "pikachu", "HELM_KUBEASGROUPS": ",,,operators,snackeaters,partyanimals", "HELM_MAX_HISTORY": "5", "HELM_KUBECAFILE": "/tmp/ca.crt"},
+			ns:         "myns",
+			debug:      true,
+			maxhistory: 5,
+			kAsUser:    "poro",
+			kAsGroups:  []string{"admins", "teatime", "snackeaters"},
+			kCaFile:    "/my/ca.crt",
 		},
 	}
 
@@ -119,14 +119,14 @@ func TestEnvSettings(t *testing.T) {
 			if settings.MaxHistory != tt.maxhistory {
 				t.Errorf("expected maxHistory %d, got %d", tt.maxhistory, settings.MaxHistory)
 			}
-			if tt.kubeAsUser != settings.KubeAsUser {
-				t.Errorf("expected kAsUser %q, got %q", tt.kubeAsUser, settings.KubeAsUser)
+			if tt.kAsUser != settings.KubeAsUser {
+				t.Errorf("expected kAsUser %q, got %q", tt.kAsUser, settings.KubeAsUser)
 			}
-			if !reflect.DeepEqual(tt.kubeAsGroups, settings.KubeAsGroups) {
-				t.Errorf("expected kAsGroups %+v, got %+v", len(tt.kubeAsGroups), len(settings.KubeAsGroups))
+			if !reflect.DeepEqual(tt.kAsGroups, settings.KubeAsGroups) {
+				t.Errorf("expected kAsGroups %+v, got %+v", len(tt.kAsGroups), len(settings.KubeAsGroups))
 			}
-			if tt.kubeCaFile != settings.KubeCaFile {
-				t.Errorf("expected kCaFile %q, got %q", tt.kubeCaFile, settings.KubeCaFile)
+			if tt.kCaFile != settings.KubeCaFile {
+				t.Errorf("expected kCaFile %q, got %q", tt.kCaFile, settings.KubeCaFile)
 			}
 		})
 	}
diff --git a/pkg/downloader/manager_test.go b/pkg/downloader/manager_test.go
index f7ab1a568..4aa0fe11b 100644
--- a/pkg/downloader/manager_test.go
+++ b/pkg/downloader/manager_test.go
@@ -17,6 +17,7 @@ package downloader
 
 import (
 	"bytes"
+	"io/ioutil"
 	"os"
 	"path/filepath"
 	"reflect"
@@ -217,7 +218,11 @@ func TestGetRepoNames(t *testing.T) {
 }
 
 func TestDownloadAll(t *testing.T) {
-	chartPath := t.TempDir()
+	chartPath, err := ioutil.TempDir("", "test-downloadall")
+	if err != nil {
+		t.Fatalf("could not create tempdir: %v", err)
+	}
+	defer os.RemoveAll(chartPath)
 	m := &Manager{
 		Out:              new(bytes.Buffer),
 		RepositoryConfig: repoConfig,
diff --git a/pkg/getter/httpgetter_test.go b/pkg/getter/httpgetter_test.go
index d823aec0d..140b2c714 100644
--- a/pkg/getter/httpgetter_test.go
+++ b/pkg/getter/httpgetter_test.go
@@ -50,6 +50,7 @@ func TestHTTPGetter(t *testing.T) {
 	ca, pub, priv := join(cd, "rootca.crt"), join(cd, "crt.pem"), join(cd, "key.pem")
 	insecure := false
 	timeout := time.Second * 5
+	transport := &http.Transport{}
 
 	// Test with options
 	g, err = NewHTTPGetter(
@@ -59,6 +60,7 @@ func TestHTTPGetter(t *testing.T) {
 		WithTLSClientConfig(pub, priv, ca),
 		WithInsecureSkipVerifyTLS(insecure),
 		WithTimeout(timeout),
+		WithTransport(transport),
 	)
 	if err != nil {
 		t.Fatal(err)
@@ -105,6 +107,10 @@ func TestHTTPGetter(t *testing.T) {
 		t.Errorf("Expected NewHTTPGetter to contain %s as Timeout flag, got %s", timeout, hg.opts.timeout)
 	}
 
+	if hg.opts.transport != transport {
+		t.Errorf("Expected NewHTTPGetter to contain %p as Transport, got %p", transport, hg.opts.transport)
+	}
+
 	// Test if setting insecureSkipVerifyTLS is being passed to the ops
 	insecure = true
 
@@ -396,24 +402,24 @@ func TestHTTPGetterTarDownload(t *testing.T) {
 func TestHttpClientInsecureSkipVerify(t *testing.T) {
 	g := HTTPGetter{}
 	g.opts.url = "https://localhost"
-	verifyInsecureSkipVerify(t, g, "Blank HTTPGetter", false)
+	verifyInsecureSkipVerify(t, &g, "Blank HTTPGetter", false)
 
 	g = HTTPGetter{}
 	g.opts.url = "https://localhost"
 	g.opts.caFile = "testdata/ca.crt"
-	verifyInsecureSkipVerify(t, g, "HTTPGetter with ca file", false)
+	verifyInsecureSkipVerify(t, &g, "HTTPGetter with ca file", false)
 
 	g = HTTPGetter{}
 	g.opts.url = "https://localhost"
 	g.opts.insecureSkipVerifyTLS = true
-	verifyInsecureSkipVerify(t, g, "HTTPGetter with skip cert verification only", true)
+	verifyInsecureSkipVerify(t, &g, "HTTPGetter with skip cert verification only", true)
 
 	g = HTTPGetter{}
 	g.opts.url = "https://localhost"
 	g.opts.certFile = "testdata/client.crt"
 	g.opts.keyFile = "testdata/client.key"
 	g.opts.insecureSkipVerifyTLS = true
-	transport := verifyInsecureSkipVerify(t, g, "HTTPGetter with 2 way ssl", true)
+	transport := verifyInsecureSkipVerify(t, &g, "HTTPGetter with 2 way ssl", true)
 	if len(transport.TLSClientConfig.Certificates) <= 0 {
 		t.Fatal("transport.TLSClientConfig.Certificates is not present")
 	}
@@ -422,7 +428,7 @@ func TestHttpClientInsecureSkipVerify(t *testing.T) {
 	}
 }
 
-func verifyInsecureSkipVerify(t *testing.T, g HTTPGetter, caseName string, expectedValue bool) *http.Transport {
+func verifyInsecureSkipVerify(t *testing.T, g *HTTPGetter, caseName string, expectedValue bool) *http.Transport {
 	returnVal, err := g.httpClient()
 
 	if err != nil {
@@ -443,3 +449,84 @@ func verifyInsecureSkipVerify(t *testing.T, g HTTPGetter, caseName string, expec
 	}
 	return transport
 }
+
+func TestDefaultHTTPTransportReuse(t *testing.T) {
+	g := HTTPGetter{}
+
+	httpClient1, err := g.httpClient()
+
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if httpClient1 == nil {
+		t.Fatalf("Expected non nil value for http client")
+	}
+
+	transport1 := (httpClient1.Transport).(*http.Transport)
+
+	httpClient2, err := g.httpClient()
+
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if httpClient2 == nil {
+		t.Fatalf("Expected non nil value for http client")
+	}
+
+	transport2 := (httpClient2.Transport).(*http.Transport)
+
+	if transport1 != transport2 {
+		t.Fatalf("Expected default transport to be reused")
+	}
+}
+
+func TestHTTPTransportOption(t *testing.T) {
+	transport := &http.Transport{}
+
+	g := HTTPGetter{}
+	g.opts.transport = transport
+	httpClient1, err := g.httpClient()
+
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if httpClient1 == nil {
+		t.Fatalf("Expected non nil value for http client")
+	}
+
+	transport1 := (httpClient1.Transport).(*http.Transport)
+
+	if transport1 != transport {
+		t.Fatalf("Expected transport option to be applied")
+	}
+
+	httpClient2, err := g.httpClient()
+
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if httpClient2 == nil {
+		t.Fatalf("Expected non nil value for http client")
+	}
+
+	transport2 := (httpClient2.Transport).(*http.Transport)
+
+	if transport1 != transport2 {
+		t.Fatalf("Expected applied transport to be reused")
+	}
+
+	g = HTTPGetter{}
+	g.opts.url = "https://localhost"
+	g.opts.certFile = "testdata/client.crt"
+	g.opts.keyFile = "testdata/client.key"
+	g.opts.insecureSkipVerifyTLS = true
+	g.opts.transport = transport
+	usedTransport := verifyInsecureSkipVerify(t, &g, "HTTPGetter with 2 way ssl", false)
+	if usedTransport.TLSClientConfig != nil {
+		t.Fatal("transport.TLSClientConfig should not be set")
+	}
+}
diff --git a/pkg/lint/lint_test.go b/pkg/lint/lint_test.go
index 0e5d42391..210e2349f 100644
--- a/pkg/lint/lint_test.go
+++ b/pkg/lint/lint_test.go
@@ -17,6 +17,8 @@ limitations under the License.
 package lint
 
 import (
+	"io/ioutil"
+	"os"
 	"strings"
 	"testing"
 
@@ -118,7 +120,11 @@ func TestGoodChart(t *testing.T) {
 //
 // See https://github.com/helm/helm/issues/7923
 func TestHelmCreateChart(t *testing.T) {
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "-helm-test")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 
 	createdChart, err := chartutil.Create("testhelmcreatepasseslint", dir)
 	if err != nil {
diff --git a/pkg/plugin/installer/http_installer_test.go b/pkg/plugin/installer/http_installer_test.go
index 165007af0..e89fea29d 100644
--- a/pkg/plugin/installer/http_installer_test.go
+++ b/pkg/plugin/installer/http_installer_test.go
@@ -21,6 +21,7 @@ import (
 	"compress/gzip"
 	"encoding/base64"
 	"fmt"
+	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
 	"os"
@@ -208,7 +209,11 @@ func TestHTTPInstallerUpdate(t *testing.T) {
 func TestExtract(t *testing.T) {
 	source := "https://repo.localdomain/plugins/fake-plugin-0.0.1.tar.gz"
 
-	tempDir := t.TempDir()
+	tempDir, err := ioutil.TempDir("", "")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tempDir)
 
 	// Set the umask to default open permissions so we can actually test
 	oldmask := syscall.Umask(0000)
diff --git a/pkg/plugin/installer/local_installer_test.go b/pkg/plugin/installer/local_installer_test.go
index 9b5cbf59e..0d3de11d1 100644
--- a/pkg/plugin/installer/local_installer_test.go
+++ b/pkg/plugin/installer/local_installer_test.go
@@ -28,7 +28,11 @@ var _ Installer = new(LocalInstaller)
 
 func TestLocalInstaller(t *testing.T) {
 	// Make a temp dir
-	tdir := t.TempDir()
+	tdir, err := ioutil.TempDir("", "helm-installer-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tdir)
 	if err := ioutil.WriteFile(filepath.Join(tdir, "plugin.yaml"), []byte{}, 0644); err != nil {
 		t.Fatal(err)
 	}
diff --git a/pkg/postrender/exec_test.go b/pkg/postrender/exec_test.go
index 9788ed56e..ef0956949 100644
--- a/pkg/postrender/exec_test.go
+++ b/pkg/postrender/exec_test.go
@@ -31,11 +31,7 @@ import (
 )
 
 const testingScript = `#!/bin/sh
-if [ $# -eq 0 ]; then
 sed s/FOOTEST/BARTEST/g <&0
-else
-sed s/FOOTEST/"$*"/g <&0
-fi
 `
 
 func TestGetFullPath(t *testing.T) {
@@ -128,40 +124,6 @@ func TestExecRun(t *testing.T) {
 	is.Contains(output.String(), "BARTEST")
 }
 
-func TestNewExecWithOneArgsRun(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		// the actual Run test uses a basic sed example, so skip this test on windows
-		t.Skip("skipping on windows")
-	}
-	is := assert.New(t)
-	testpath, cleanup := setupTestingScript(t)
-	defer cleanup()
-
-	renderer, err := NewExec(testpath, "ARG1")
-	require.NoError(t, err)
-
-	output, err := renderer.Run(bytes.NewBufferString("FOOTEST"))
-	is.NoError(err)
-	is.Contains(output.String(), "ARG1")
-}
-
-func TestNewExecWithTwoArgsRun(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		// the actual Run test uses a basic sed example, so skip this test on windows
-		t.Skip("skipping on windows")
-	}
-	is := assert.New(t)
-	testpath, cleanup := setupTestingScript(t)
-	defer cleanup()
-
-	renderer, err := NewExec(testpath, "ARG1", "ARG2")
-	require.NoError(t, err)
-
-	output, err := renderer.Run(bytes.NewBufferString("FOOTEST"))
-	is.NoError(err)
-	is.Contains(output.String(), "ARG1 ARG2")
-}
-
 func setupTestingScript(t *testing.T) (filepath string, cleanup func()) {
 	t.Helper()
 
diff --git a/pkg/releaseutil/kind_sorter_test.go b/pkg/releaseutil/kind_sorter_test.go
index afcae6d16..71d355210 100644
--- a/pkg/releaseutil/kind_sorter_test.go
+++ b/pkg/releaseutil/kind_sorter_test.go
@@ -25,10 +25,6 @@ import (
 
 func TestKindSorter(t *testing.T) {
 	manifests := []Manifest{
-		{
-			Name: "U",
-			Head: &SimpleHead{Kind: "IngressClass"},
-		},
 		{
 			Name: "E",
 			Head: &SimpleHead{Kind: "SecretList"},
@@ -176,8 +172,8 @@ func TestKindSorter(t *testing.T) {
 		order       KindSortOrder
 		expected    string
 	}{
-		{"install", InstallOrder, "aAbcC3deEf1gh2iIjJkKlLmnopqrxstuUvw!"},
-		{"uninstall", UninstallOrder, "wvUmutsxrqponLlKkJjIi2hg1fEed3CcbAa!"},
+		{"install", InstallOrder, "aAbcC3deEf1gh2iIjJkKlLmnopqrxstuvw!"},
+		{"uninstall", UninstallOrder, "wvmutsxrqponLlKkJjIi2hg1fEed3CcbAa!"},
 	} {
 		var buf bytes.Buffer
 		t.Run(test.description, func(t *testing.T) {
diff --git a/pkg/repo/index_test.go b/pkg/repo/index_test.go
index 51c31fab7..292856527 100644
--- a/pkg/repo/index_test.go
+++ b/pkg/repo/index_test.go
@@ -513,7 +513,11 @@ func TestIndexWrite(t *testing.T) {
 	if err := i.MustAdd(&chart.Metadata{APIVersion: "v2", Name: "clipper", Version: "0.1.0"}, "clipper-0.1.0.tgz", "http://example.com/charts", "sha256:1234567890"); err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
-	dir := t.TempDir()
+	dir, err := ioutil.TempDir("", "helm-tmp")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir)
 	testpath := filepath.Join(dir, "test")
 	i.WriteFile(testpath, 0600)