github.com/amanya/packer@v0.12.1-0.20161117214323-902ac5ab2eb6/common/step_http_server.go (about) 1 package common 2 3 import ( 4 "fmt" 5 "github.com/mitchellh/multistep" 6 "github.com/mitchellh/packer/packer" 7 "log" 8 "math/rand" 9 "net" 10 "net/http" 11 ) 12 13 // This step creates and runs the HTTP server that is serving files from the 14 // directory specified by the 'http_directory` configuration parameter in the 15 // template. 16 // 17 // Uses: 18 // ui packer.Ui 19 // 20 // Produces: 21 // http_port int - The port the HTTP server started on. 22 type StepHTTPServer struct { 23 HTTPDir string 24 HTTPPortMin uint 25 HTTPPortMax uint 26 27 l net.Listener 28 } 29 30 func (s *StepHTTPServer) Run(state multistep.StateBag) multistep.StepAction { 31 ui := state.Get("ui").(packer.Ui) 32 33 var httpPort uint = 0 34 if s.HTTPDir == "" { 35 state.Put("http_port", httpPort) 36 return multistep.ActionContinue 37 } 38 39 // Find an available TCP port for our HTTP server 40 var httpAddr string 41 portRange := int(s.HTTPPortMax - s.HTTPPortMin) 42 for { 43 var err error 44 var offset uint = 0 45 46 if portRange > 0 { 47 // Intn will panic if portRange == 0, so we do a check. 48 offset = uint(rand.Intn(portRange)) 49 } 50 51 httpPort = offset + s.HTTPPortMin 52 httpAddr = fmt.Sprintf("0.0.0.0:%d", httpPort) 53 log.Printf("Trying port: %d", httpPort) 54 s.l, err = net.Listen("tcp", httpAddr) 55 if err == nil { 56 break 57 } 58 } 59 60 ui.Say(fmt.Sprintf("Starting HTTP server on port %d", httpPort)) 61 62 // Start the HTTP server and run it in the background 63 fileServer := http.FileServer(http.Dir(s.HTTPDir)) 64 server := &http.Server{Addr: httpAddr, Handler: fileServer} 65 go server.Serve(s.l) 66 67 // Save the address into the state so it can be accessed in the future 68 state.Put("http_port", httpPort) 69 70 return multistep.ActionContinue 71 } 72 73 func (s *StepHTTPServer) Cleanup(multistep.StateBag) { 74 if s.l != nil { 75 // Close the listener so that the HTTP server stops 76 s.l.Close() 77 } 78 }