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