diff --git a/common/http_config.go b/common/http_config.go index bb9b46b26..8a6809ac4 100644 --- a/common/http_config.go +++ b/common/http_config.go @@ -9,8 +9,8 @@ import ( // HTTPConfig contains configuration for the local HTTP Server type HTTPConfig struct { HTTPDir string `mapstructure:"http_directory"` - HTTPPortMin uint `mapstructure:"http_port_min"` - HTTPPortMax uint `mapstructure:"http_port_max"` + HTTPPortMin int `mapstructure:"http_port_min"` + HTTPPortMax int `mapstructure:"http_port_max"` } func (c *HTTPConfig) Prepare(ctx *interpolate.Context) []error { diff --git a/common/step_http_server.go b/common/step_http_server.go index 8e9e58983..e8cd1c6ca 100644 --- a/common/step_http_server.go +++ b/common/step_http_server.go @@ -3,11 +3,10 @@ package common import ( "context" "fmt" - "log" - "math/rand" - "net" + "net/http" + "github.com/hashicorp/packer/common/net" "github.com/hashicorp/packer/helper/common" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" @@ -24,44 +23,35 @@ import ( // http_port int - The port the HTTP server started on. type StepHTTPServer struct { HTTPDir string - HTTPPortMin uint - HTTPPortMax uint + HTTPPortMin int + HTTPPortMax int - l net.Listener + l *net.Listener } -func (s *StepHTTPServer) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepHTTPServer) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) - var httpPort uint = 0 if s.HTTPDir == "" { - state.Put("http_port", httpPort) + state.Put("http_port", uint(0)) return multistep.ActionContinue } // Find an available TCP port for our HTTP server var httpAddr string - portRange := int(s.HTTPPortMax - s.HTTPPortMin) - for { - var err error - var offset uint = 0 - - if portRange > 0 { - // Intn will panic if portRange == 0, so we do a check. - // Intn is from [0, n), so add 1 to make from [0, n] - offset = uint(rand.Intn(portRange + 1)) - } - - httpPort = offset + s.HTTPPortMin - httpAddr = fmt.Sprintf("0.0.0.0:%d", httpPort) - log.Printf("Trying port: %d", httpPort) - s.l, err = net.Listen("tcp", httpAddr) - if err == nil { - break - } + var err error + s.l, err = net.ListenRangeConfig{ + Min: s.HTTPPortMin, + Max: s.HTTPPortMax, + Addr: "0.0.0.0", + Network: "tcp", + }.Listen(ctx) + + if err != nil { + return multistep.ActionHalt } - ui.Say(fmt.Sprintf("Starting HTTP server on port %d", httpPort)) + ui.Say(fmt.Sprintf("Starting HTTP server on port %d", s.l.Port)) // Start the HTTP server and run it in the background fileServer := http.FileServer(http.Dir(s.HTTPDir)) @@ -69,8 +59,8 @@ func (s *StepHTTPServer) Run(_ context.Context, state multistep.StateBag) multis go server.Serve(s.l) // Save the address into the state so it can be accessed in the future - state.Put("http_port", httpPort) - SetHTTPPort(fmt.Sprintf("%d", httpPort)) + state.Put("http_port", s.l.Port) + SetHTTPPort(fmt.Sprintf("%d", s.l.Port)) return multistep.ActionContinue }