From 7f149e595dddd039325ba999df06c4860cdddcb1 Mon Sep 17 00:00:00 2001 From: Mark Peek Date: Sun, 1 Nov 2015 14:29:24 -0800 Subject: [PATCH] Refactor http server config into common --- builder/parallels/iso/builder.go | 24 ++---- builder/parallels/iso/builder_test.go | 39 ---------- builder/parallels/iso/step_http_server.go | 76 ------------------ builder/qemu/builder.go | 24 ++---- builder/qemu/builder_test.go | 39 ---------- builder/qemu/step_http_server.go | 76 ------------------ builder/virtualbox/common/run_config.go | 18 ----- builder/virtualbox/iso/builder.go | 4 +- builder/virtualbox/iso/builder_test.go | 39 ---------- builder/virtualbox/iso/step_http_server.go | 76 ------------------ builder/virtualbox/ovf/builder.go | 2 +- builder/virtualbox/ovf/config.go | 2 + builder/vmware/common/run_config.go | 18 ----- builder/vmware/common/step_http_server.go | 78 ------------------- builder/vmware/iso/builder.go | 4 +- builder/vmware/iso/builder_test.go | 39 ---------- builder/vmware/vmx/builder.go | 2 +- builder/vmware/vmx/config.go | 2 + common/http_config.go | 34 ++++++++ common/http_config_test.go | 45 +++++++++++ .../common => common}/step_http_server.go | 0 21 files changed, 105 insertions(+), 536 deletions(-) delete mode 100644 builder/parallels/iso/step_http_server.go delete mode 100644 builder/qemu/step_http_server.go delete mode 100644 builder/virtualbox/iso/step_http_server.go delete mode 100644 builder/vmware/common/step_http_server.go create mode 100644 common/http_config.go create mode 100644 common/http_config_test.go rename {builder/virtualbox/common => common}/step_http_server.go (100%) diff --git a/builder/parallels/iso/builder.go b/builder/parallels/iso/builder.go index 4dda28cbe..a5b4b4dec 100644 --- a/builder/parallels/iso/builder.go +++ b/builder/parallels/iso/builder.go @@ -23,6 +23,7 @@ type Builder struct { type Config struct { common.PackerConfig `mapstructure:",squash"` + common.HTTPConfig `mapstructure:",squash"` common.ISOConfig `mapstructure:",squash"` parallelscommon.FloppyConfig `mapstructure:",squash"` parallelscommon.OutputConfig `mapstructure:",squash"` @@ -39,9 +40,6 @@ type Config struct { GuestOSType string `mapstructure:"guest_os_type"` HardDriveInterface string `mapstructure:"hard_drive_interface"` HostInterfaces []string `mapstructure:"host_interfaces"` - HTTPDir string `mapstructure:"http_directory"` - HTTPPortMin uint `mapstructure:"http_port_min"` - HTTPPortMax uint `mapstructure:"http_port_max"` SkipCompaction bool `mapstructure:"skip_compaction"` VMName string `mapstructure:"vm_name"` @@ -77,6 +75,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { warnings = append(warnings, isoWarnings...) errs = packer.MultiErrorAppend(errs, isoErrs...) + errs = packer.MultiErrorAppend(errs, b.config.HTTPConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend( errs, b.config.OutputConfig.Prepare(&b.config.ctx, &b.config.PackerConfig)...) @@ -110,14 +109,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { "Run it to see all available values: `prlctl create x -d list` ") } - if b.config.HTTPPortMin == 0 { - b.config.HTTPPortMin = 8000 - } - - if b.config.HTTPPortMax == 0 { - b.config.HTTPPortMax = 9000 - } - if len(b.config.HostInterfaces) == 0 { b.config.HostInterfaces = []string{"en0", "en1", "en2", "en3", "en4", "en5", "en6", "en7", "en8", "en9", "ppp0", "ppp1", "ppp2"} @@ -132,11 +123,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs, errors.New("hard_drive_interface can only be ide, sata, or scsi")) } - if b.config.HTTPPortMin > b.config.HTTPPortMax { - errs = packer.MultiErrorAppend( - errs, errors.New("http_port_min must be less than http_port_max")) - } - // Warnings if b.config.ShutdownCommand == "" { warnings = append(warnings, @@ -185,7 +171,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &common.StepCreateFloppy{ Files: b.config.FloppyFiles, }, - new(stepHTTPServer), + &common.StepHTTPServer{ + HTTPDir: b.config.HTTPDir, + HTTPPortMin: b.config.HTTPPortMin, + HTTPPortMax: b.config.HTTPPortMax, + }, new(stepCreateVM), new(stepCreateDisk), new(stepSetBootOrder), diff --git a/builder/parallels/iso/builder_test.go b/builder/parallels/iso/builder_test.go index ff0af5582..b5099e1b7 100644 --- a/builder/parallels/iso/builder_test.go +++ b/builder/parallels/iso/builder_test.go @@ -138,45 +138,6 @@ func TestBuilderPrepare_HardDriveInterface(t *testing.T) { } } -func TestBuilderPrepare_HTTPPort(t *testing.T) { - var b Builder - config := testConfig() - - // Bad - config["http_port_min"] = 1000 - config["http_port_max"] = 500 - warns, err := b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err == nil { - t.Fatal("should have error") - } - - // Bad - config["http_port_min"] = -500 - b = Builder{} - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err == nil { - t.Fatal("should have error") - } - - // Good - config["http_port_min"] = 500 - config["http_port_max"] = 1000 - b = Builder{} - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("should not have error: %s", err) - } -} - func TestBuilderPrepare_InvalidKey(t *testing.T) { var b Builder config := testConfig() diff --git a/builder/parallels/iso/step_http_server.go b/builder/parallels/iso/step_http_server.go deleted file mode 100644 index 4744af278..000000000 --- a/builder/parallels/iso/step_http_server.go +++ /dev/null @@ -1,76 +0,0 @@ -package iso - -import ( - "fmt" - "github.com/mitchellh/multistep" - "github.com/mitchellh/packer/packer" - "log" - "math/rand" - "net" - "net/http" -) - -// This step creates and runs the HTTP server that is serving files from the -// directory specified by the 'http_directory` 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 multistep.StateBag) multistep.StepAction { - config := state.Get("config").(*Config) - ui := state.Get("ui").(packer.Ui) - - var httpPort uint = 0 - if config.HTTPDir == "" { - state.Put("http_port", httpPort) - 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 - - 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 - } - } - - 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} - go server.Serve(s.l) - - // Save the address into the state so it can be accessed in the future - state.Put("http_port", httpPort) - - return multistep.ActionContinue -} - -func (s *stepHTTPServer) Cleanup(multistep.StateBag) { - if s.l != nil { - // Close the listener so that the HTTP server stops - s.l.Close() - } -} diff --git a/builder/qemu/builder.go b/builder/qemu/builder.go index 2e7e107d7..942d28e93 100644 --- a/builder/qemu/builder.go +++ b/builder/qemu/builder.go @@ -79,6 +79,7 @@ type Builder struct { type Config struct { common.PackerConfig `mapstructure:",squash"` + common.HTTPConfig `mapstructure:",squash"` common.ISOConfig `mapstructure:",squash"` Comm communicator.Config `mapstructure:",squash"` @@ -94,9 +95,6 @@ type Config struct { Format string `mapstructure:"format"` Headless bool `mapstructure:"headless"` DiskImage bool `mapstructure:"disk_image"` - HTTPDir string `mapstructure:"http_directory"` - HTTPPortMin uint `mapstructure:"http_port_min"` - HTTPPortMax uint `mapstructure:"http_port_max"` MachineType string `mapstructure:"machine_type"` NetDevice string `mapstructure:"net_device"` OutputDir string `mapstructure:"output_directory"` @@ -160,14 +158,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } } - if b.config.HTTPPortMin == 0 { - b.config.HTTPPortMin = 8000 - } - - if b.config.HTTPPortMax == 0 { - b.config.HTTPPortMax = 9000 - } - if b.config.MachineType == "" { b.config.MachineType = "pc" } @@ -235,6 +225,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { warnings = append(warnings, isoWarnings...) errs = packer.MultiErrorAppend(errs, isoErrs...) + errs = packer.MultiErrorAppend(errs, b.config.HTTPConfig.Prepare(&b.config.ctx)...) if es := b.config.Comm.Prepare(&b.config.ctx); len(es) > 0 { errs = packer.MultiErrorAppend(errs, es...) } @@ -274,11 +265,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs, errors.New("unrecognized disk cache type")) } - if b.config.HTTPPortMin > b.config.HTTPPortMax { - errs = packer.MultiErrorAppend( - errs, errors.New("http_port_min must be less than http_port_max")) - } - if !b.config.PackerForce { if _, err := os.Stat(b.config.OutputDir); err == nil { errs = packer.MultiErrorAppend( @@ -357,7 +343,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe new(stepCreateDisk), new(stepCopyDisk), new(stepResizeDisk), - new(stepHTTPServer), + &common.StepHTTPServer{ + HTTPDir: b.config.HTTPDir, + HTTPPortMin: b.config.HTTPPortMin, + HTTPPortMax: b.config.HTTPPortMax, + }, new(stepForwardSSH), new(stepConfigureVNC), steprun, diff --git a/builder/qemu/builder_test.go b/builder/qemu/builder_test.go index f885c570b..a7ce88e6d 100644 --- a/builder/qemu/builder_test.go +++ b/builder/qemu/builder_test.go @@ -206,45 +206,6 @@ func TestBuilderPrepare_DiskSize(t *testing.T) { } } -func TestBuilderPrepare_HTTPPort(t *testing.T) { - var b Builder - config := testConfig() - - // Bad - config["http_port_min"] = 1000 - config["http_port_max"] = 500 - warns, err := b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err == nil { - t.Fatal("should have error") - } - - // Bad - config["http_port_min"] = -500 - b = Builder{} - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err == nil { - t.Fatal("should have error") - } - - // Good - config["http_port_min"] = 500 - config["http_port_max"] = 1000 - b = Builder{} - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("should not have error: %s", err) - } -} - func TestBuilderPrepare_Format(t *testing.T) { var b Builder config := testConfig() diff --git a/builder/qemu/step_http_server.go b/builder/qemu/step_http_server.go deleted file mode 100644 index a5d784ec2..000000000 --- a/builder/qemu/step_http_server.go +++ /dev/null @@ -1,76 +0,0 @@ -package qemu - -import ( - "fmt" - "github.com/mitchellh/multistep" - "github.com/mitchellh/packer/packer" - "log" - "math/rand" - "net" - "net/http" -) - -// This step creates and runs the HTTP server that is serving files from the -// directory specified by the 'http_directory` 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 multistep.StateBag) multistep.StepAction { - config := state.Get("config").(*Config) - ui := state.Get("ui").(packer.Ui) - - var httpPort uint = 0 - if config.HTTPDir == "" { - state.Put("http_port", httpPort) - 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 - - 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 - } - } - - 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} - go server.Serve(s.l) - - // Save the address into the state so it can be accessed in the future - state.Put("http_port", httpPort) - - return multistep.ActionContinue -} - -func (s *stepHTTPServer) Cleanup(multistep.StateBag) { - if s.l != nil { - // Close the listener so that the HTTP server stops - s.l.Close() - } -} diff --git a/builder/virtualbox/common/run_config.go b/builder/virtualbox/common/run_config.go index 164e1993f..16ce1c4ad 100644 --- a/builder/virtualbox/common/run_config.go +++ b/builder/virtualbox/common/run_config.go @@ -1,7 +1,6 @@ package common import ( - "errors" "fmt" "time" @@ -12,10 +11,6 @@ type RunConfig struct { Headless bool `mapstructure:"headless"` RawBootWait string `mapstructure:"boot_wait"` - HTTPDir string `mapstructure:"http_directory"` - HTTPPortMin uint `mapstructure:"http_port_min"` - HTTPPortMax uint `mapstructure:"http_port_max"` - BootWait time.Duration `` } @@ -24,14 +19,6 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { c.RawBootWait = "10s" } - if c.HTTPPortMin == 0 { - c.HTTPPortMin = 8000 - } - - if c.HTTPPortMax == 0 { - c.HTTPPortMax = 9000 - } - var errs []error var err error c.BootWait, err = time.ParseDuration(c.RawBootWait) @@ -39,10 +26,5 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { errs = append(errs, fmt.Errorf("Failed parsing boot_wait: %s", err)) } - if c.HTTPPortMin > c.HTTPPortMax { - errs = append(errs, - errors.New("http_port_min must be less than http_port_max")) - } - return errs } diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index 587d2f28e..b8b08959a 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -24,6 +24,7 @@ type Builder struct { type Config struct { common.PackerConfig `mapstructure:",squash"` + common.HTTPConfig `mapstructure:",squash"` common.ISOConfig `mapstructure:",squash"` vboxcommon.ExportConfig `mapstructure:",squash"` vboxcommon.ExportOpts `mapstructure:",squash"` @@ -81,6 +82,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { errs = packer.MultiErrorAppend(errs, b.config.FloppyConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend( errs, b.config.OutputConfig.Prepare(&b.config.ctx, &b.config.PackerConfig)...) + errs = packer.MultiErrorAppend(errs, b.config.HTTPConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(&b.config.ctx)...) @@ -194,7 +196,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &common.StepCreateFloppy{ Files: b.config.FloppyFiles, }, - &vboxcommon.StepHTTPServer{ + &common.StepHTTPServer{ HTTPDir: b.config.HTTPDir, HTTPPortMin: b.config.HTTPPortMin, HTTPPortMax: b.config.HTTPPortMax, diff --git a/builder/virtualbox/iso/builder_test.go b/builder/virtualbox/iso/builder_test.go index eb2d2fb75..e4e3e6a53 100644 --- a/builder/virtualbox/iso/builder_test.go +++ b/builder/virtualbox/iso/builder_test.go @@ -260,45 +260,6 @@ func TestBuilderPrepare_HardDriveInterface(t *testing.T) { } } -func TestBuilderPrepare_HTTPPort(t *testing.T) { - var b Builder - config := testConfig() - - // Bad - config["http_port_min"] = 1000 - config["http_port_max"] = 500 - warns, err := b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err == nil { - t.Fatal("should have error") - } - - // Bad - config["http_port_min"] = -500 - b = Builder{} - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err == nil { - t.Fatal("should have error") - } - - // Good - config["http_port_min"] = 500 - config["http_port_max"] = 1000 - b = Builder{} - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("should not have error: %s", err) - } -} - func TestBuilderPrepare_InvalidKey(t *testing.T) { var b Builder config := testConfig() diff --git a/builder/virtualbox/iso/step_http_server.go b/builder/virtualbox/iso/step_http_server.go deleted file mode 100644 index 4744af278..000000000 --- a/builder/virtualbox/iso/step_http_server.go +++ /dev/null @@ -1,76 +0,0 @@ -package iso - -import ( - "fmt" - "github.com/mitchellh/multistep" - "github.com/mitchellh/packer/packer" - "log" - "math/rand" - "net" - "net/http" -) - -// This step creates and runs the HTTP server that is serving files from the -// directory specified by the 'http_directory` 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 multistep.StateBag) multistep.StepAction { - config := state.Get("config").(*Config) - ui := state.Get("ui").(packer.Ui) - - var httpPort uint = 0 - if config.HTTPDir == "" { - state.Put("http_port", httpPort) - 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 - - 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 - } - } - - 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} - go server.Serve(s.l) - - // Save the address into the state so it can be accessed in the future - state.Put("http_port", httpPort) - - return multistep.ActionContinue -} - -func (s *stepHTTPServer) Cleanup(multistep.StateBag) { - if s.l != nil { - // Close the listener so that the HTTP server stops - s.l.Close() - } -} diff --git a/builder/virtualbox/ovf/builder.go b/builder/virtualbox/ovf/builder.go index d7c93c9eb..894fe1689 100644 --- a/builder/virtualbox/ovf/builder.go +++ b/builder/virtualbox/ovf/builder.go @@ -57,7 +57,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe &common.StepCreateFloppy{ Files: b.config.FloppyFiles, }, - &vboxcommon.StepHTTPServer{ + &common.StepHTTPServer{ HTTPDir: b.config.HTTPDir, HTTPPortMin: b.config.HTTPPortMin, HTTPPortMax: b.config.HTTPPortMax, diff --git a/builder/virtualbox/ovf/config.go b/builder/virtualbox/ovf/config.go index c1afd8c25..0aab0871d 100644 --- a/builder/virtualbox/ovf/config.go +++ b/builder/virtualbox/ovf/config.go @@ -15,6 +15,7 @@ import ( // Config is the configuration structure for the builder. type Config struct { common.PackerConfig `mapstructure:",squash"` + common.HTTPConfig `mapstructure:",squash"` vboxcommon.ExportConfig `mapstructure:",squash"` vboxcommon.ExportOpts `mapstructure:",squash"` vboxcommon.FloppyConfig `mapstructure:",squash"` @@ -77,6 +78,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { errs = packer.MultiErrorAppend(errs, c.ExportConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.ExportOpts.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.FloppyConfig.Prepare(&c.ctx)...) + errs = packer.MultiErrorAppend(errs, c.HTTPConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(&c.ctx, &c.PackerConfig)...) errs = packer.MultiErrorAppend(errs, c.RunConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare(&c.ctx)...) diff --git a/builder/vmware/common/run_config.go b/builder/vmware/common/run_config.go index 2f99984b1..b977b27ab 100644 --- a/builder/vmware/common/run_config.go +++ b/builder/vmware/common/run_config.go @@ -1,7 +1,6 @@ package common import ( - "errors" "fmt" "time" @@ -12,10 +11,6 @@ type RunConfig struct { Headless bool `mapstructure:"headless"` RawBootWait string `mapstructure:"boot_wait"` - HTTPDir string `mapstructure:"http_directory"` - HTTPPortMin uint `mapstructure:"http_port_min"` - HTTPPortMax uint `mapstructure:"http_port_max"` - VNCPortMin uint `mapstructure:"vnc_port_min"` VNCPortMax uint `mapstructure:"vnc_port_max"` @@ -27,14 +22,6 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { c.RawBootWait = "10s" } - if c.HTTPPortMin == 0 { - c.HTTPPortMin = 8000 - } - - if c.HTTPPortMax == 0 { - c.HTTPPortMax = 9000 - } - if c.VNCPortMin == 0 { c.VNCPortMin = 5900 } @@ -53,11 +40,6 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { } } - if c.HTTPPortMin > c.HTTPPortMax { - errs = append(errs, - errors.New("http_port_min must be less than http_port_max")) - } - if c.VNCPortMin > c.VNCPortMax { errs = append( errs, fmt.Errorf("vnc_port_min must be less than vnc_port_max")) diff --git a/builder/vmware/common/step_http_server.go b/builder/vmware/common/step_http_server.go deleted file mode 100644 index 55874992e..000000000 --- a/builder/vmware/common/step_http_server.go +++ /dev/null @@ -1,78 +0,0 @@ -package common - -import ( - "fmt" - "github.com/mitchellh/multistep" - "github.com/mitchellh/packer/packer" - "log" - "math/rand" - "net" - "net/http" -) - -// This step creates and runs the HTTP server that is serving files from the -// directory specified by the 'http_directory` configuration parameter in the -// template. -// -// Uses: -// ui packer.Ui -// -// Produces: -// http_port int - The port the HTTP server started on. -type StepHTTPServer struct { - HTTPDir string - HTTPPortMin uint - HTTPPortMax uint - - l net.Listener -} - -func (s *StepHTTPServer) Run(state multistep.StateBag) multistep.StepAction { - ui := state.Get("ui").(packer.Ui) - - var httpPort uint = 0 - if s.HTTPDir == "" { - state.Put("http_port", httpPort) - 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. - offset = uint(rand.Intn(portRange)) - } - - 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 - } - } - - 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(s.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.Put("http_port", httpPort) - - return multistep.ActionContinue -} - -func (s *StepHTTPServer) Cleanup(multistep.StateBag) { - if s.l != nil { - // Close the listener so that the HTTP server stops - s.l.Close() - } -} diff --git a/builder/vmware/iso/builder.go b/builder/vmware/iso/builder.go index 7958b5760..0a1e8a835 100755 --- a/builder/vmware/iso/builder.go +++ b/builder/vmware/iso/builder.go @@ -26,6 +26,7 @@ type Builder struct { type Config struct { common.PackerConfig `mapstructure:",squash"` + common.HTTPConfig `mapstructure:",squash"` common.ISOConfig `mapstructure:",squash"` vmwcommon.DriverConfig `mapstructure:",squash"` vmwcommon.OutputConfig `mapstructure:",squash"` @@ -83,6 +84,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { isoWarnings, isoErrs := b.config.ISOConfig.Prepare(&b.config.ctx) warnings = append(warnings, isoWarnings...) errs = packer.MultiErrorAppend(errs, isoErrs...) + errs = packer.MultiErrorAppend(errs, b.config.HTTPConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.DriverConfig.Prepare(&b.config.ctx)...) errs = packer.MultiErrorAppend(errs, b.config.OutputConfig.Prepare(&b.config.ctx, &b.config.PackerConfig)...) @@ -244,7 +246,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe CustomData: b.config.VMXData, }, &vmwcommon.StepSuppressMessages{}, - &vmwcommon.StepHTTPServer{ + &common.StepHTTPServer{ HTTPDir: b.config.HTTPDir, HTTPPortMin: b.config.HTTPPortMin, HTTPPortMax: b.config.HTTPPortMax, diff --git a/builder/vmware/iso/builder_test.go b/builder/vmware/iso/builder_test.go index 8327e7ebf..bb2149506 100644 --- a/builder/vmware/iso/builder_test.go +++ b/builder/vmware/iso/builder_test.go @@ -152,45 +152,6 @@ func TestBuilderPrepare_Format(t *testing.T) { } } -func TestBuilderPrepare_HTTPPort(t *testing.T) { - var b Builder - config := testConfig() - - // Bad - config["http_port_min"] = 1000 - config["http_port_max"] = 500 - warns, err := b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err == nil { - t.Fatal("should have error") - } - - // Bad - config["http_port_min"] = -500 - b = Builder{} - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err == nil { - t.Fatal("should have error") - } - - // Good - config["http_port_min"] = 500 - config["http_port_max"] = 1000 - b = Builder{} - warns, err = b.Prepare(config) - if len(warns) > 0 { - t.Fatalf("bad: %#v", warns) - } - if err != nil { - t.Fatalf("should not have error: %s", err) - } -} - func TestBuilderPrepare_InvalidKey(t *testing.T) { var b Builder config := testConfig() diff --git a/builder/vmware/vmx/builder.go b/builder/vmware/vmx/builder.go index aa86d3669..dbe785732 100644 --- a/builder/vmware/vmx/builder.go +++ b/builder/vmware/vmx/builder.go @@ -72,7 +72,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe CustomData: b.config.VMXData, }, &vmwcommon.StepSuppressMessages{}, - &vmwcommon.StepHTTPServer{ + &common.StepHTTPServer{ HTTPDir: b.config.HTTPDir, HTTPPortMin: b.config.HTTPPortMin, HTTPPortMax: b.config.HTTPPortMax, diff --git a/builder/vmware/vmx/config.go b/builder/vmware/vmx/config.go index 5f06127fe..4f93db9f3 100644 --- a/builder/vmware/vmx/config.go +++ b/builder/vmware/vmx/config.go @@ -14,6 +14,7 @@ import ( // Config is the configuration structure for the builder. type Config struct { common.PackerConfig `mapstructure:",squash"` + common.HTTPConfig `mapstructure:",squash"` vmwcommon.DriverConfig `mapstructure:",squash"` vmwcommon.OutputConfig `mapstructure:",squash"` vmwcommon.RunConfig `mapstructure:",squash"` @@ -56,6 +57,7 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) { // Prepare the errors var errs *packer.MultiError errs = packer.MultiErrorAppend(errs, c.DriverConfig.Prepare(&c.ctx)...) + errs = packer.MultiErrorAppend(errs, c.HTTPConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.OutputConfig.Prepare(&c.ctx, &c.PackerConfig)...) errs = packer.MultiErrorAppend(errs, c.RunConfig.Prepare(&c.ctx)...) errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare(&c.ctx)...) diff --git a/common/http_config.go b/common/http_config.go new file mode 100644 index 000000000..41381c2a0 --- /dev/null +++ b/common/http_config.go @@ -0,0 +1,34 @@ +package common + +import ( + "errors" + + "github.com/mitchellh/packer/template/interpolate" +) + +// 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"` +} + +func (c *HTTPConfig) Prepare(ctx *interpolate.Context) []error { + // Validation + var errs []error + + if c.HTTPPortMin == 0 { + c.HTTPPortMin = 8000 + } + + if c.HTTPPortMax == 0 { + c.HTTPPortMax = 9000 + } + + if c.HTTPPortMin > c.HTTPPortMax { + errs = append(errs, + errors.New("http_port_min must be less than http_port_max")) + } + + return errs +} diff --git a/common/http_config_test.go b/common/http_config_test.go new file mode 100644 index 000000000..eb42148b8 --- /dev/null +++ b/common/http_config_test.go @@ -0,0 +1,45 @@ +package common + +import ( + "testing" +) + +func TestHTTPConfigPrepare_Bounds(t *testing.T) { + // Test bad + h := HTTPConfig{ + HTTPPortMin: 1000, + HTTPPortMax: 500, + } + err := h.Prepare(nil) + if err == nil { + t.Fatal("should have error") + } + + // Test good + h = HTTPConfig{ + HTTPPortMin: 0, + HTTPPortMax: 0, + } + err = h.Prepare(nil) + if err != nil { + t.Fatalf("should not have error: %s", err) + } + portMin := uint(8000) + if h.HTTPPortMin != portMin { + t.Fatalf("HTTPPortMin: expected %d got %d", portMin, h.HTTPPortMin) + } + portMax := uint(9000) + if h.HTTPPortMax != portMax { + t.Fatalf("HTTPPortMax: expected %d got %d", portMax, h.HTTPPortMax) + } + + // Test good + h = HTTPConfig{ + HTTPPortMin: 500, + HTTPPortMax: 1000, + } + err = h.Prepare(nil) + if err != nil { + t.Fatalf("should not have error: %s", err) + } +} diff --git a/builder/virtualbox/common/step_http_server.go b/common/step_http_server.go similarity index 100% rename from builder/virtualbox/common/step_http_server.go rename to common/step_http_server.go