Adding the ability to skip nat port forwarding for ssh connectivity

This commit is contained in:
Peter Leschev 2014-03-27 17:11:34 +11:00
parent 7a8372db74
commit eef3223f6c
7 changed files with 80 additions and 56 deletions

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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,
},
}

View File

@ -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,
},
}

View File

@ -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

View File

@ -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