From eef3223f6cee2d1642c42402ab238dd486665671 Mon Sep 17 00:00:00 2001 From: Peter Leschev Date: Thu, 27 Mar 2014 17:11:34 +1100 Subject: [PATCH] Adding the ability to skip nat port forwarding for ssh connectivity --- builder/virtualbox/common/ssh_config.go | 1 + builder/virtualbox/common/step_export.go | 29 ++++---- builder/virtualbox/common/step_forward_ssh.go | 70 ++++++++++--------- builder/virtualbox/iso/builder.go | 14 ++-- builder/virtualbox/ovf/builder.go | 14 ++-- .../builders/virtualbox-iso.html.markdown | 4 ++ .../builders/virtualbox-ovf.html.markdown | 4 ++ 7 files changed, 80 insertions(+), 56 deletions(-) diff --git a/builder/virtualbox/common/ssh_config.go b/builder/virtualbox/common/ssh_config.go index 00c6167c6..5da8ad403 100644 --- a/builder/virtualbox/common/ssh_config.go +++ b/builder/virtualbox/common/ssh_config.go @@ -16,6 +16,7 @@ type SSHConfig struct { SSHPort uint `mapstructure:"ssh_port"` SSHUser string `mapstructure:"ssh_username"` RawSSHWaitTimeout string `mapstructure:"ssh_wait_timeout"` + SSHSkipNatMapping bool `mapstructure:"ssh_skip_nat_mapping"` SSHWaitTimeout time.Duration } diff --git a/builder/virtualbox/common/step_export.go b/builder/virtualbox/common/step_export.go index e4e860155..0a3cd816c 100644 --- a/builder/virtualbox/common/step_export.go +++ b/builder/virtualbox/common/step_export.go @@ -17,9 +17,10 @@ import ( // Produces: // exportPath string - The path to the resulting export. type StepExport struct { - Format string - OutputDir string - ExportOpts []string + Format string + OutputDir string + ExportOpts []string + SkipNatMapping bool } func (s *StepExport) Run(state multistep.StateBag) multistep.StepAction { @@ -33,15 +34,19 @@ func (s *StepExport) Run(state multistep.StateBag) multistep.StepAction { // Clear out the Packer-created forwarding rule ui.Say("Preparing to export machine...") - ui.Message(fmt.Sprintf( - "Deleting forwarded port mapping for SSH (host port %d)", - state.Get("sshHostPort"))) - command := []string{"modifyvm", vmName, "--natpf1", "delete", "packerssh"} - if err := driver.VBoxManage(command...); err != nil { - err := fmt.Errorf("Error deleting port forwarding rule: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt + var command []string + + if s.SkipNatMapping == false { + ui.Message(fmt.Sprintf( + "Deleting forwarded port mapping for SSH (host port %d)", + state.Get("sshHostPort"))) + command := []string{"modifyvm", vmName, "--natpf1", "delete", "packerssh"} + if err := driver.VBoxManage(command...); err != nil { + err := fmt.Errorf("Error deleting port forwarding rule: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } } // Export the VM to an OVF diff --git a/builder/virtualbox/common/step_forward_ssh.go b/builder/virtualbox/common/step_forward_ssh.go index 862432952..d6d604e00 100644 --- a/builder/virtualbox/common/step_forward_ssh.go +++ b/builder/virtualbox/common/step_forward_ssh.go @@ -19,9 +19,10 @@ import ( // // Produces: type StepForwardSSH struct { - GuestPort uint - HostPortMin uint - HostPortMax uint + GuestPort uint + HostPortMin uint + HostPortMax uint + SkipNatMapping bool } func (s *StepForwardSSH) Run(state multistep.StateBag) multistep.StepAction { @@ -29,39 +30,44 @@ func (s *StepForwardSSH) Run(state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) vmName := state.Get("vmName").(string) - log.Printf("Looking for available SSH port between %d and %d", - s.HostPortMin, s.HostPortMax) var sshHostPort uint - var offset uint = 0 + if s.SkipNatMapping { + sshHostPort = s.GuestPort + log.Printf("Skipping SSH NAT mapping and using SSH port %d", sshHostPort) + } else { + log.Printf("Looking for available SSH port between %d and %d", + s.HostPortMin, s.HostPortMax) + var offset uint = 0 - portRange := int(s.HostPortMax - s.HostPortMin) - if portRange > 0 { - // Have to check if > 0 to avoid a panic - offset = uint(rand.Intn(portRange)) - } - - for { - sshHostPort = offset + s.HostPortMin - log.Printf("Trying port: %d", sshHostPort) - l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", sshHostPort)) - if err == nil { - defer l.Close() - break + portRange := int(s.HostPortMax - s.HostPortMin) + if portRange > 0 { + // Have to check if > 0 to avoid a panic + offset = uint(rand.Intn(portRange)) } - } - // Create a forwarded port mapping to the VM - ui.Say(fmt.Sprintf("Creating forwarded port mapping for SSH (host port %d)", sshHostPort)) - command := []string{ - "modifyvm", vmName, - "--natpf1", - fmt.Sprintf("packerssh,tcp,127.0.0.1,%d,,%d", sshHostPort, s.GuestPort), - } - if err := driver.VBoxManage(command...); err != nil { - err := fmt.Errorf("Error creating port forwarding rule: %s", err) - state.Put("error", err) - ui.Error(err.Error()) - return multistep.ActionHalt + for { + sshHostPort = offset + s.HostPortMin + log.Printf("Trying port: %d", sshHostPort) + l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", sshHostPort)) + if err == nil { + defer l.Close() + break + } + } + + // Create a forwarded port mapping to the VM + ui.Say(fmt.Sprintf("Creating forwarded port mapping for SSH (host port %d)", sshHostPort)) + command := []string{ + "modifyvm", vmName, + "--natpf1", + fmt.Sprintf("packerssh,tcp,127.0.0.1,%d,,%d", sshHostPort, s.GuestPort), + } + if err := driver.VBoxManage(command...); err != nil { + err := fmt.Errorf("Error creating port forwarding rule: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } } // Save the port we're using so that future steps can use it diff --git a/builder/virtualbox/iso/builder.go b/builder/virtualbox/iso/builder.go index 31660a961..7ec34bfe8 100644 --- a/builder/virtualbox/iso/builder.go +++ b/builder/virtualbox/iso/builder.go @@ -290,9 +290,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe new(stepAttachGuestAdditions), new(vboxcommon.StepAttachFloppy), &vboxcommon.StepForwardSSH{ - GuestPort: b.config.SSHPort, - HostPortMin: b.config.SSHHostPortMin, - HostPortMax: b.config.SSHHostPortMax, + GuestPort: b.config.SSHPort, + HostPortMin: b.config.SSHHostPortMin, + HostPortMax: b.config.SSHHostPortMax, + SkipNatMapping: b.config.SSHSkipNatMapping, }, &vboxcommon.StepVBoxManage{ Commands: b.config.VBoxManage, @@ -319,9 +320,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, new(vboxcommon.StepRemoveDevices), &vboxcommon.StepExport{ - Format: b.config.Format, - OutputDir: b.config.OutputDir, - ExportOpts: b.config.ExportOpts.ExportOpts, + Format: b.config.Format, + OutputDir: b.config.OutputDir, + ExportOpts: b.config.ExportOpts.ExportOpts, + SkipNatMapping: b.config.SSHSkipNatMapping, }, } diff --git a/builder/virtualbox/ovf/builder.go b/builder/virtualbox/ovf/builder.go index f2e6a92f5..65c4fe72a 100644 --- a/builder/virtualbox/ovf/builder.go +++ b/builder/virtualbox/ovf/builder.go @@ -65,9 +65,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe */ new(vboxcommon.StepAttachFloppy), &vboxcommon.StepForwardSSH{ - GuestPort: b.config.SSHPort, - HostPortMin: b.config.SSHHostPortMin, - HostPortMax: b.config.SSHHostPortMax, + GuestPort: b.config.SSHPort, + HostPortMin: b.config.SSHHostPortMin, + HostPortMax: b.config.SSHHostPortMax, + SkipNatMapping: b.config.SSHSkipNatMapping, }, &vboxcommon.StepVBoxManage{ Commands: b.config.VBoxManage, @@ -95,9 +96,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe }, new(vboxcommon.StepRemoveDevices), &vboxcommon.StepExport{ - Format: b.config.Format, - OutputDir: b.config.OutputDir, - ExportOpts: b.config.ExportOpts.ExportOpts, + Format: b.config.Format, + OutputDir: b.config.OutputDir, + ExportOpts: b.config.ExportOpts.ExportOpts, + SkipNatMapping: b.config.SSHSkipNatMapping, }, } diff --git a/website/source/docs/builders/virtualbox-iso.html.markdown b/website/source/docs/builders/virtualbox-iso.html.markdown index e6e3b2454..3c2e87e7f 100644 --- a/website/source/docs/builders/virtualbox-iso.html.markdown +++ b/website/source/docs/builders/virtualbox-iso.html.markdown @@ -191,6 +191,10 @@ Optional: available. By default this is "20m", or 20 minutes. Note that this should be quite long since the timer begins as soon as the virtual machine is booted. +* `ssh_skip_nat_mapping` (bool) - Defaults to false. When enabled, Packer does + not setup forwarded port mapping for SSH requests and uses `ssh_port` on the + host to communicate to the virtual machine + * `vboxmanage` (array of array of strings) - Custom `VBoxManage` commands to execute in order to further customize the virtual machine being created. The value of this is an array of commands to execute. The commands are executed diff --git a/website/source/docs/builders/virtualbox-ovf.html.markdown b/website/source/docs/builders/virtualbox-ovf.html.markdown index 6bf6e49d9..43ce70339 100644 --- a/website/source/docs/builders/virtualbox-ovf.html.markdown +++ b/website/source/docs/builders/virtualbox-ovf.html.markdown @@ -126,6 +126,10 @@ Optional: available. By default this is "20m", or 20 minutes. Note that this should be quite long since the timer begins as soon as the virtual machine is booted. +* `ssh_skip_nat_mapping` (bool) - Defaults to false. When enabled, Packer does + not setup forwarded port mapping for SSH requests and uses `ssh_port` on the + host to communicate to the virtual machine + * `vboxmanage` (array of array of strings) - Custom `VBoxManage` commands to execute in order to further customize the virtual machine being created. The value of this is an array of commands to execute. The commands are executed