From 14f2d1c132c4c4361e540f1fdc9d0b640169f279 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Wed, 1 May 2019 12:27:32 +0200 Subject: [PATCH] ListenRangeConfig:Listen: use the retry pkg to wait a bit in between opens --- common/net/configure_port.go | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/common/net/configure_port.go b/common/net/configure_port.go index fddd4b5d6..7982cf80d 100644 --- a/common/net/configure_port.go +++ b/common/net/configure_port.go @@ -10,6 +10,7 @@ import ( "time" "github.com/hashicorp/packer/common/filelock" + "github.com/hashicorp/packer/common/retry" "github.com/hashicorp/packer/packer" ) @@ -55,11 +56,12 @@ func (lc ListenRangeConfig) Listen(ctx context.Context) (*Listener, error) { lc.Network = "tcp" } portRange := lc.Max - lc.Min - for { - if err := ctx.Err(); err != nil { - return nil, err - } + var listener *Listener + + err := retry.Config{ + RetryDelay: func() time.Duration { return 20 * time.Millisecond }, + }.Run(ctx, func(context.Context) error { port := lc.Min if portRange > 0 { port += rand.Intn(portRange) @@ -67,16 +69,16 @@ func (lc ListenRangeConfig) Listen(ctx context.Context) (*Listener, error) { lockFilePath, err := packer.CachePath("port", strconv.Itoa(port)) if err != nil { - return nil, err + return err } lock := filelock.New(lockFilePath) locked, err := lock.TryLock() if err != nil { - return nil, err + return err } if !locked { - continue // this port seems to be locked by another packer goroutine + return fmt.Errorf("Port %d is file locked", port) } log.Printf("Trying port: %d", port) @@ -84,20 +86,19 @@ func (lc ListenRangeConfig) Listen(ctx context.Context) (*Listener, error) { l, err := lc.ListenConfig.Listen(ctx, lc.Network, fmt.Sprintf("%s:%d", lc.Addr, port)) if err != nil { if err := lock.Unlock(); err != nil { - log.Printf("Could not unlock file lock for port %d: %v", port, err) + log.Fatalf("Could not unlock file lock for port %d: %v", port, err) } - - continue // this port is most likely already open + return fmt.Errorf("Port %d cannot be opened: %v", port, err) } log.Printf("Found available port: %d on IP: %s", port, lc.Addr) - return &Listener{ + listener = &Listener{ Address: lc.Addr, Port: port, Listener: l, lock: lock, - }, err - - time.Sleep(20 * time.Millisecond) - } + } + return nil + }) + return listener, err }