Commit eef3223f authored by Peter Leschev's avatar Peter Leschev

Adding the ability to skip nat port forwarding for ssh connectivity

parent 7a8372db
...@@ -16,6 +16,7 @@ type SSHConfig struct { ...@@ -16,6 +16,7 @@ type SSHConfig struct {
SSHPort uint `mapstructure:"ssh_port"` SSHPort uint `mapstructure:"ssh_port"`
SSHUser string `mapstructure:"ssh_username"` SSHUser string `mapstructure:"ssh_username"`
RawSSHWaitTimeout string `mapstructure:"ssh_wait_timeout"` RawSSHWaitTimeout string `mapstructure:"ssh_wait_timeout"`
SSHSkipNatMapping bool `mapstructure:"ssh_skip_nat_mapping"`
SSHWaitTimeout time.Duration SSHWaitTimeout time.Duration
} }
......
...@@ -17,9 +17,10 @@ import ( ...@@ -17,9 +17,10 @@ import (
// Produces: // Produces:
// exportPath string - The path to the resulting export. // exportPath string - The path to the resulting export.
type StepExport struct { type StepExport struct {
Format string Format string
OutputDir string OutputDir string
ExportOpts []string ExportOpts []string
SkipNatMapping bool
} }
func (s *StepExport) Run(state multistep.StateBag) multistep.StepAction { func (s *StepExport) Run(state multistep.StateBag) multistep.StepAction {
...@@ -33,15 +34,19 @@ 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 // Clear out the Packer-created forwarding rule
ui.Say("Preparing to export machine...") ui.Say("Preparing to export machine...")
ui.Message(fmt.Sprintf( var command []string
"Deleting forwarded port mapping for SSH (host port %d)",
state.Get("sshHostPort"))) if s.SkipNatMapping == false {
command := []string{"modifyvm", vmName, "--natpf1", "delete", "packerssh"} ui.Message(fmt.Sprintf(
if err := driver.VBoxManage(command...); err != nil { "Deleting forwarded port mapping for SSH (host port %d)",
err := fmt.Errorf("Error deleting port forwarding rule: %s", err) state.Get("sshHostPort")))
state.Put("error", err) command := []string{"modifyvm", vmName, "--natpf1", "delete", "packerssh"}
ui.Error(err.Error()) if err := driver.VBoxManage(command...); err != nil {
return multistep.ActionHalt 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 // Export the VM to an OVF
......
...@@ -19,9 +19,10 @@ import ( ...@@ -19,9 +19,10 @@ import (
// //
// Produces: // Produces:
type StepForwardSSH struct { type StepForwardSSH struct {
GuestPort uint GuestPort uint
HostPortMin uint HostPortMin uint
HostPortMax uint HostPortMax uint
SkipNatMapping bool
} }
func (s *StepForwardSSH) Run(state multistep.StateBag) multistep.StepAction { func (s *StepForwardSSH) Run(state multistep.StateBag) multistep.StepAction {
...@@ -29,39 +30,44 @@ 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) ui := state.Get("ui").(packer.Ui)
vmName := state.Get("vmName").(string) vmName := state.Get("vmName").(string)
log.Printf("Looking for available SSH port between %d and %d",
s.HostPortMin, s.HostPortMax)
var sshHostPort uint 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) portRange := int(s.HostPortMax - s.HostPortMin)
if portRange > 0 { if portRange > 0 {
// Have to check if > 0 to avoid a panic // Have to check if > 0 to avoid a panic
offset = uint(rand.Intn(portRange)) offset = uint(rand.Intn(portRange))
} }
for { for {
sshHostPort = offset + s.HostPortMin sshHostPort = offset + s.HostPortMin
log.Printf("Trying port: %d", sshHostPort) log.Printf("Trying port: %d", sshHostPort)
l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", sshHostPort)) l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", sshHostPort))
if err == nil { if err == nil {
defer l.Close() defer l.Close()
break break
}
} }
}
// Create a forwarded port mapping to the VM // Create a forwarded port mapping to the VM
ui.Say(fmt.Sprintf("Creating forwarded port mapping for SSH (host port %d)", sshHostPort)) ui.Say(fmt.Sprintf("Creating forwarded port mapping for SSH (host port %d)", sshHostPort))
command := []string{ command := []string{
"modifyvm", vmName, "modifyvm", vmName,
"--natpf1", "--natpf1",
fmt.Sprintf("packerssh,tcp,127.0.0.1,%d,,%d", sshHostPort, s.GuestPort), fmt.Sprintf("packerssh,tcp,127.0.0.1,%d,,%d", sshHostPort, s.GuestPort),
} }
if err := driver.VBoxManage(command...); err != nil { if err := driver.VBoxManage(command...); err != nil {
err := fmt.Errorf("Error creating port forwarding rule: %s", err) err := fmt.Errorf("Error creating port forwarding rule: %s", err)
state.Put("error", err) state.Put("error", err)
ui.Error(err.Error()) ui.Error(err.Error())
return multistep.ActionHalt return multistep.ActionHalt
}
} }
// Save the port we're using so that future steps can use it // Save the port we're using so that future steps can use it
......
...@@ -290,9 +290,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -290,9 +290,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
new(stepAttachGuestAdditions), new(stepAttachGuestAdditions),
new(vboxcommon.StepAttachFloppy), new(vboxcommon.StepAttachFloppy),
&vboxcommon.StepForwardSSH{ &vboxcommon.StepForwardSSH{
GuestPort: b.config.SSHPort, GuestPort: b.config.SSHPort,
HostPortMin: b.config.SSHHostPortMin, HostPortMin: b.config.SSHHostPortMin,
HostPortMax: b.config.SSHHostPortMax, HostPortMax: b.config.SSHHostPortMax,
SkipNatMapping: b.config.SSHSkipNatMapping,
}, },
&vboxcommon.StepVBoxManage{ &vboxcommon.StepVBoxManage{
Commands: b.config.VBoxManage, Commands: b.config.VBoxManage,
...@@ -319,9 +320,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -319,9 +320,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
}, },
new(vboxcommon.StepRemoveDevices), new(vboxcommon.StepRemoveDevices),
&vboxcommon.StepExport{ &vboxcommon.StepExport{
Format: b.config.Format, Format: b.config.Format,
OutputDir: b.config.OutputDir, OutputDir: b.config.OutputDir,
ExportOpts: b.config.ExportOpts.ExportOpts, ExportOpts: b.config.ExportOpts.ExportOpts,
SkipNatMapping: b.config.SSHSkipNatMapping,
}, },
} }
......
...@@ -65,9 +65,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -65,9 +65,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
*/ */
new(vboxcommon.StepAttachFloppy), new(vboxcommon.StepAttachFloppy),
&vboxcommon.StepForwardSSH{ &vboxcommon.StepForwardSSH{
GuestPort: b.config.SSHPort, GuestPort: b.config.SSHPort,
HostPortMin: b.config.SSHHostPortMin, HostPortMin: b.config.SSHHostPortMin,
HostPortMax: b.config.SSHHostPortMax, HostPortMax: b.config.SSHHostPortMax,
SkipNatMapping: b.config.SSHSkipNatMapping,
}, },
&vboxcommon.StepVBoxManage{ &vboxcommon.StepVBoxManage{
Commands: b.config.VBoxManage, Commands: b.config.VBoxManage,
...@@ -95,9 +96,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe ...@@ -95,9 +96,10 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
}, },
new(vboxcommon.StepRemoveDevices), new(vboxcommon.StepRemoveDevices),
&vboxcommon.StepExport{ &vboxcommon.StepExport{
Format: b.config.Format, Format: b.config.Format,
OutputDir: b.config.OutputDir, OutputDir: b.config.OutputDir,
ExportOpts: b.config.ExportOpts.ExportOpts, ExportOpts: b.config.ExportOpts.ExportOpts,
SkipNatMapping: b.config.SSHSkipNatMapping,
}, },
} }
......
...@@ -191,6 +191,10 @@ Optional: ...@@ -191,6 +191,10 @@ Optional:
available. By default this is "20m", or 20 minutes. Note that this should 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. 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 * `vboxmanage` (array of array of strings) - Custom `VBoxManage` commands to
execute in order to further customize the virtual machine being created. 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 The value of this is an array of commands to execute. The commands are executed
......
...@@ -126,6 +126,10 @@ Optional: ...@@ -126,6 +126,10 @@ Optional:
available. By default this is "20m", or 20 minutes. Note that this should 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. 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 * `vboxmanage` (array of array of strings) - Custom `VBoxManage` commands to
execute in order to further customize the virtual machine being created. 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 The value of this is an array of commands to execute. The commands are executed
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment