From f67b5ff59dc1fa6c95ecfc1a092cf0b37bf72676 Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 18 Mar 2019 13:24:59 +0100 Subject: [PATCH] virtualbox StepConfigureVRDP: use common/net pkg to find open port --- builder/virtualbox/common/run_config.go | 4 +- .../virtualbox/common/step_configure_vrdp.go | 50 +++++++++++-------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/builder/virtualbox/common/run_config.go b/builder/virtualbox/common/run_config.go index cf94c306b..e5cae02a6 100644 --- a/builder/virtualbox/common/run_config.go +++ b/builder/virtualbox/common/run_config.go @@ -10,8 +10,8 @@ type RunConfig struct { Headless bool `mapstructure:"headless"` VRDPBindAddress string `mapstructure:"vrdp_bind_address"` - VRDPPortMin uint `mapstructure:"vrdp_port_min"` - VRDPPortMax uint `mapstructure:"vrdp_port_max"` + VRDPPortMin int `mapstructure:"vrdp_port_min"` + VRDPPortMax int `mapstructure:"vrdp_port_max"` } func (c *RunConfig) Prepare(ctx *interpolate.Context) (errs []error) { diff --git a/builder/virtualbox/common/step_configure_vrdp.go b/builder/virtualbox/common/step_configure_vrdp.go index 6cc960ad3..54bde727b 100644 --- a/builder/virtualbox/common/step_configure_vrdp.go +++ b/builder/virtualbox/common/step_configure_vrdp.go @@ -4,9 +4,8 @@ import ( "context" "fmt" "log" - "math/rand" - "net" + "github.com/hashicorp/packer/common/net" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" ) @@ -23,33 +22,33 @@ import ( // vrdp_port unit - The port that VRDP is configured to listen on. type StepConfigureVRDP struct { VRDPBindAddress string - VRDPPortMin uint - VRDPPortMax uint + VRDPPortMin int + VRDPPortMax int + + l *net.Listener } -func (s *StepConfigureVRDP) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { +func (s *StepConfigureVRDP) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { driver := state.Get("driver").(Driver) ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) log.Printf("Looking for available port between %d and %d on %s", s.VRDPPortMin, s.VRDPPortMax, s.VRDPBindAddress) - var vrdpPort uint - portRange := int(s.VRDPPortMax - s.VRDPPortMin) - - for { - if portRange > 0 { - vrdpPort = uint(rand.Intn(portRange)) + s.VRDPPortMin - } else { - vrdpPort = s.VRDPPortMin - } - - log.Printf("Trying port: %d", vrdpPort) - l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", s.VRDPBindAddress, vrdpPort)) - if err == nil { - defer l.Close() - break - } + var err error + s.l, err = net.ListenRangeConfig{ + Addr: s.VRDPBindAddress, + Min: s.VRDPPortMin, + Max: s.VRDPPortMax, + Network: "tcp", + }.Listen(ctx) + if err != nil { + err := fmt.Errorf("Error finding port: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt } + s.l.Listener.Close() // free port, but don't unlock lock file + vrdpPort := s.l.Port command := []string{ "modifyvm", vmName, @@ -72,4 +71,11 @@ func (s *StepConfigureVRDP) Run(_ context.Context, state multistep.StateBag) mul return multistep.ActionContinue } -func (s *StepConfigureVRDP) Cleanup(state multistep.StateBag) {} +func (s *StepConfigureVRDP) Cleanup(state multistep.StateBag) { + if s.l != nil { + err := s.l.Close() + if err != nil { + log.Printf("failed to unlock port lockfile: %v", err) + } + } +}