From eb8278b21c8a97539e5acadc744578902cb4f8aa Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 5 Jun 2013 14:24:48 -0700 Subject: [PATCH] builder/vmware: Start HTTP server to serve files --- builder/vmware/builder.go | 2 ++ builder/vmware/step_http_server.go | 57 ++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 builder/vmware/step_http_server.go diff --git a/builder/vmware/builder.go b/builder/vmware/builder.go index a9acaeb5d..5c4286a5c 100644 --- a/builder/vmware/builder.go +++ b/builder/vmware/builder.go @@ -18,6 +18,7 @@ type config struct { ISOUrl string `mapstructure:"iso_url"` VMName string `mapstructure:"vm_name"` OutputDir string `mapstructure:"output_directory"` + HTTPDir string `mapstructure:"http_directory"` } func (b *Builder) Prepare(raw interface{}) (err error) { @@ -46,6 +47,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) packer.Artifact { &stepPrepareOutputDir{}, &stepCreateDisk{}, &stepCreateVMX{}, + &stepHTTPServer{}, } // Setup the state bag diff --git a/builder/vmware/step_http_server.go b/builder/vmware/step_http_server.go new file mode 100644 index 000000000..52b118990 --- /dev/null +++ b/builder/vmware/step_http_server.go @@ -0,0 +1,57 @@ +package vmware + +import ( + "fmt" + "github.com/mitchellh/multistep" + "github.com/mitchellh/packer/packer" + "net" + "net/http" +) + +// This step creates and runs the HTTP server that is serving the files +// specified by the 'http_files` configuration parameter in the template. +// +// Uses: +// config *config +// ui packer.Ui +// +// Produces: +// http_port int - The port the HTTP server started on. +type stepHTTPServer struct{ + l net.Listener +} + +func (s *stepHTTPServer) Run(state map[string]interface{}) multistep.StepAction { + config := state["config"].(*config) + ui := state["ui"].(packer.Ui) + + httpPort := 8080 + httpAddr := fmt.Sprintf(":%d", httpPort) + + ui.Say(fmt.Sprintf("Starting HTTP server on port %d", httpPort)) + + // Start the TCP listener + var err error + s.l, err = net.Listen("tcp", httpAddr) + if err != nil { + ui.Error(fmt.Sprintf("Error starting HTTP server: %s", err)) + return multistep.ActionHalt + } + + // Start the HTTP server and run it in the background + fileServer := http.FileServer(http.Dir(config.HTTPDir)) + server := &http.Server{Addr: httpAddr, Handler: fileServer} + go server.Serve(s.l) + + // Save the address into the state so it can be accessed in the future + state["http_port"] = httpPort + + return multistep.ActionContinue +} + +func (s *stepHTTPServer) Cleanup(map[string]interface{}) { + if s.l != nil { + // Close the listener so that the HTTP server stops + s.l.Close() + } +}