Skip to content

Commit 268638f

Browse files
authored
Merge pull request kubernetes-sigs#173 from droot/bugfix/retry-bind-addr-in-use
envtest: added retry for 'addr in use' bind error
2 parents 03818a5 + 64e281d commit 268638f

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

pkg/envtest/server.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ package envtest
1818

1919
import (
2020
"fmt"
21+
"net"
2122
"os"
2223
"path/filepath"
24+
"strings"
2325
"time"
2426

2527
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
@@ -138,8 +140,7 @@ func (te *Environment) Start() (*rest.Config, error) {
138140
te.ControlPlane.APIServer.StartTimeout = te.ControlPlaneStartTimeout
139141
te.ControlPlane.APIServer.StopTimeout = te.ControlPlaneStopTimeout
140142

141-
// Start the control plane - retry if it fails
142-
if err := te.ControlPlane.Start(); err != nil {
143+
if err := te.startControlPlane(); err != nil {
143144
return nil, err
144145
}
145146

@@ -156,6 +157,32 @@ func (te *Environment) Start() (*rest.Config, error) {
156157
return te.Config, err
157158
}
158159

160+
func (te *Environment) startControlPlane() error {
161+
numTries, maxRetries := 0, 5
162+
for ; numTries < maxRetries; numTries++ {
163+
// Start the control plane - retry if it fails
164+
err := te.ControlPlane.Start()
165+
if err == nil {
166+
break
167+
}
168+
// code snippet copied from following answer on stackoverflow
169+
// https://stackoverflow.com/questions/51151973/catching-bind-address-already-in-use-in-golang
170+
if opErr, ok := err.(*net.OpError); ok {
171+
if opErr.Op == "listen" && strings.Contains(opErr.Error(), "address already in use") {
172+
if stopErr := te.ControlPlane.Stop(); stopErr != nil {
173+
return fmt.Errorf("failed to stop controlplane in response to bind error 'address already in use'")
174+
}
175+
}
176+
} else {
177+
return err
178+
}
179+
}
180+
if numTries == maxRetries {
181+
return fmt.Errorf("failed to start the controlplane. retried %d times", numTries)
182+
}
183+
return nil
184+
}
185+
159186
func (te *Environment) defaultTimeouts() error {
160187
var err error
161188
if te.ControlPlaneStartTimeout == 0 {

0 commit comments

Comments
 (0)