Factor out common port-finding code
Fixes bug where we would infinite-loop trying to find an HTTP server port when all ports were unavailable (e.g. range [80,80] and no root permission) Also fixes bug where SSH port forwarding would try ports up to but not including HostPortMax. Also add clarification in error messages for which port range to expand
This commit is contained in:
parent
602255e9c1
commit
b433754c83
25
builder/xenserver/find_port.go
Normal file
25
builder/xenserver/find_port.go
Normal file
@ -0,0 +1,25 @@
|
||||
package xenserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
)
|
||||
|
||||
// FindPort finds and starts listening on a port in the range [portMin, portMax]
|
||||
// returns the listener and the port number on success, or nil, 0 on failure
|
||||
func FindPort(portMin uint, portMax uint) (net.Listener, uint) {
|
||||
log.Printf("Looking for an available port between %d and %d", portMin, portMax)
|
||||
|
||||
for port := portMin; port <= portMax; port++ {
|
||||
log.Printf("Trying port: %d", port)
|
||||
l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
if err == nil {
|
||||
return l, port
|
||||
} else {
|
||||
log.Printf("Port %d unavailable: %s", port, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return nil, 0
|
||||
}
|
@ -4,8 +4,6 @@ import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"log"
|
||||
"net"
|
||||
)
|
||||
|
||||
type stepForwardPortOverSSH struct {
|
||||
@ -25,32 +23,15 @@ func (self *stepForwardPortOverSSH) Run(state multistep.StateBag) multistep.Step
|
||||
|
||||
// Find a free local port:
|
||||
|
||||
log.Printf("Looking for an available port between %d and %d",
|
||||
self.HostPortMin,
|
||||
self.HostPortMax)
|
||||
l, sshHostPort := FindPort(self.HostPortMin, self.HostPortMax)
|
||||
|
||||
var sshHostPort uint
|
||||
var foundPort bool
|
||||
|
||||
foundPort = false
|
||||
|
||||
for i := self.HostPortMin; i < self.HostPortMax; i++ {
|
||||
sshHostPort = i
|
||||
log.Printf("Trying port: %d", sshHostPort)
|
||||
l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", sshHostPort))
|
||||
if err == nil {
|
||||
l.Close()
|
||||
foundPort = true
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if !foundPort {
|
||||
ui.Error("Error: unable to find free host port. Try providing a larger range")
|
||||
if l == nil || sshHostPort == 0 {
|
||||
ui.Error("Error: unable to find free host port. Try providing a larger range [host_port_min, host_port_max]")
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
l.Close()
|
||||
|
||||
ui.Say(fmt.Sprintf("Creating a local port forward over SSH on local port %d", sshHostPort))
|
||||
|
||||
remotePort, _ := self.RemotePort(state)
|
||||
|
@ -6,8 +6,6 @@ import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
@ -36,32 +34,18 @@ func (s *stepHTTPServer) Run(state multistep.StateBag) multistep.StepAction {
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
// Find an available TCP port for our HTTP server
|
||||
var httpAddr string
|
||||
portRange := int(config.HTTPPortMax - config.HTTPPortMin)
|
||||
for {
|
||||
var err error
|
||||
var offset uint = 0
|
||||
s.l, httpPort = FindPort(config.HTTPPortMin, config.HTTPPortMax)
|
||||
|
||||
if portRange > 0 {
|
||||
// Intn will panic if portRange == 0, so we do a check.
|
||||
offset = uint(rand.Intn(portRange))
|
||||
}
|
||||
|
||||
httpPort = offset + config.HTTPPortMin
|
||||
httpAddr = fmt.Sprintf(":%d", httpPort)
|
||||
log.Printf("Trying port: %d", httpPort)
|
||||
s.l, err = net.Listen("tcp", httpAddr)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
if s.l == nil || httpPort == 0 {
|
||||
ui.Error("Error: unable to find free HTTP server port. Try providing a larger range [http_port_min, http_port_max]")
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
ui.Say(fmt.Sprintf("Starting HTTP server on port %d", httpPort))
|
||||
|
||||
// Start the HTTP server and run it in the background
|
||||
fileServer := http.FileServer(http.Dir(config.HTTPDir))
|
||||
server := &http.Server{Addr: httpAddr, Handler: fileServer}
|
||||
server := &http.Server{Addr: fmt.Sprintf(":%d", httpPort), Handler: fileServer}
|
||||
go server.Serve(s.l)
|
||||
|
||||
// Save the address into the state so it can be accessed in the future
|
||||
|
Loading…
Reference in New Issue
Block a user