diff --git a/Gopkg.lock b/Gopkg.lock index 22f88edb..36bd88dc 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -41,6 +41,22 @@ revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" version = "v1.4.7" +[[projects]] + digest = "1:05334858a0cfb538622a066e065287f63f42bee26a7fda93a789674225057201" + name = "github.com/hashicorp/go-cleanhttp" + packages = ["."] + pruneopts = "" + revision = "e8ab9daed8d1ddd2d3c4efba338fe2eeae2e4f18" + version = "v0.5.0" + +[[projects]] + digest = "1:776139dc18d63ef223ffaca5d8e9a3057174890f84393d3c881e934100b66dbc" + name = "github.com/hashicorp/go-retryablehttp" + packages = ["."] + pruneopts = "" + revision = "73489d0a1476f0c9e6fb03f9c39241523a496dfd" + version = "v0.5.2" + [[projects]] digest = "1:d14365c51dd1d34d5c79833ec91413bfbb166be978724f15701e17080dc06dec" name = "github.com/hashicorp/hcl" @@ -235,6 +251,7 @@ input-imports = [ "github.com/MakeNowJust/heredoc", "github.com/Masterminds/semver", + "github.com/hashicorp/go-retryablehttp", "github.com/mitchellh/go-homedir", "github.com/pkg/errors", "github.com/spf13/cobra", diff --git a/Gopkg.toml b/Gopkg.toml index 8ed85782..ffdcd39c 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -30,3 +30,7 @@ [[constraint]] name = "gopkg.in/yaml.v2" version = "v2.2.1" + +[[constraint]] + name = "github.com/hashicorp/go-retryablehttp" + version = "v0.5.2" diff --git a/pkg/exec/exec.go b/pkg/exec/exec.go index b95ef3b9..c3cb00de 100644 --- a/pkg/exec/exec.go +++ b/pkg/exec/exec.go @@ -17,15 +17,12 @@ package exec import ( "bufio" "fmt" + "github.com/helm/chart-testing/pkg/util" + "github.com/pkg/errors" "io" - "net" "os" "os/exec" "strings" - "sync" - - "github.com/helm/chart-testing/pkg/util" - "github.com/pkg/errors" ) type ProcessExecutor struct { @@ -109,34 +106,27 @@ func (p ProcessExecutor) CreateProcess(executable string, execArgs ...interface{ type fn func(port int) error func (p ProcessExecutor) RunWithProxy(withProxy fn) error { - listener, err := net.Listen("tcp", ":0") - defer listener.Close() + randomPort, err := util.GetRandomPort() if err != nil { - return errors.Wrap(err, "Could not find a free port to run 'kubectl proxy'") + return errors.Wrap(err, "Could not find a free port for running 'kubectl proxy'") } - randomPort := listener.Addr().(*net.TCPAddr).Port - fmt.Printf("Running ' kubectl proxy on port %d\n", randomPort) - cmdProxy, err := p.CreateProcess("kubectl", "proxy", "--port", randomPort) + fmt.Printf("Running 'kubectl proxy' on port %d\n", randomPort) + cmdProxy, err := p.CreateProcess("kubectl", "proxy", fmt.Sprintf("--port=%d", randomPort)) if err != nil { return errors.Wrap(err, "Error creating the 'kubectl proxy' process") } - - var wg sync.WaitGroup - wg.Add(1) + err = cmdProxy.Start() + if err != nil { + return errors.Wrap(err, "Error starting the 'kubectl proxy' process") + } go func() { - err = cmdProxy.Start() - if err != nil { - fmt.Println("Error starting the 'kubectl proxy' process:", err) - return - } - wg.Wait() + cmdProxy.Wait() }() err = withProxy(randomPort) - wg.Done() cmdProxy.Process.Signal(os.Kill) if err != nil { diff --git a/pkg/tool/kubectl.go b/pkg/tool/kubectl.go index 45323f97..8863ca6e 100644 --- a/pkg/tool/kubectl.go +++ b/pkg/tool/kubectl.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "github.com/hashicorp/go-retryablehttp" "github.com/helm/chart-testing/pkg/exec" "github.com/pkg/errors" ) @@ -90,7 +91,7 @@ func (k Kubectl) forceNamespaceDeletion(namespace string) error { // Remove finalizer from the namespace fun := func(port int) error { k8sURL := fmt.Sprintf("http://127.0.0.1:%d/api/v1/namespaces/%s/finalize", port, namespace) - req, err := http.NewRequest("PUT", k8sURL, bytes.NewReader(namespaceUpdateBytes)) + req, err := retryablehttp.NewRequest("PUT", k8sURL, bytes.NewReader(namespaceUpdateBytes)) if err != nil { fmt.Println("Error creating the request to update the namespace:", err) return err @@ -98,7 +99,9 @@ func (k Kubectl) forceNamespaceDeletion(namespace string) error { req.Header.Set("Content-Type", "application/json") errMsg := "Error removing finalizer from namespace" - if resp, err := http.DefaultClient.Do(req); err != nil { + client := retryablehttp.NewClient() + client.Logger = nil + if resp, err := client.Do(req); err != nil { return errors.Wrap(err, errMsg) } else if resp.StatusCode != http.StatusOK { return errors.New(errMsg) diff --git a/pkg/util/util.go b/pkg/util/util.go index a73856bd..a098d4f3 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -21,6 +21,7 @@ import ( "gopkg.in/yaml.v2" "io/ioutil" "math/rand" + "net" "os" "path" "path/filepath" @@ -203,3 +204,13 @@ func TruncateLeft(s string, maxLength int) string { } return s } + +func GetRandomPort() (int , error) { + listener, err := net.Listen("tcp", ":0") + defer listener.Close() + if err != nil { + return 0, err + } + + return listener.Addr().(*net.TCPAddr).Port, nil +}