github.com/sneal/packer@v0.5.2/builder/virtualbox/common/step_forward_ssh.go (about) 1 package common 2 3 import ( 4 "fmt" 5 "github.com/mitchellh/multistep" 6 "github.com/mitchellh/packer/packer" 7 "log" 8 "math/rand" 9 "net" 10 ) 11 12 // This step adds a NAT port forwarding definition so that SSH is available 13 // on the guest machine. 14 // 15 // Uses: 16 // driver Driver 17 // ui packer.Ui 18 // vmName string 19 // 20 // Produces: 21 type StepForwardSSH struct { 22 GuestPort uint 23 HostPortMin uint 24 HostPortMax uint 25 } 26 27 func (s *StepForwardSSH) Run(state multistep.StateBag) multistep.StepAction { 28 driver := state.Get("driver").(Driver) 29 ui := state.Get("ui").(packer.Ui) 30 vmName := state.Get("vmName").(string) 31 32 log.Printf("Looking for available SSH port between %d and %d", 33 s.HostPortMin, s.HostPortMax) 34 var sshHostPort uint 35 var offset uint = 0 36 37 portRange := int(s.HostPortMax - s.HostPortMin) 38 if portRange > 0 { 39 // Have to check if > 0 to avoid a panic 40 offset = uint(rand.Intn(portRange)) 41 } 42 43 for { 44 sshHostPort = offset + s.HostPortMin 45 log.Printf("Trying port: %d", sshHostPort) 46 l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", sshHostPort)) 47 if err == nil { 48 defer l.Close() 49 break 50 } 51 } 52 53 // Create a forwarded port mapping to the VM 54 ui.Say(fmt.Sprintf("Creating forwarded port mapping for SSH (host port %d)", sshHostPort)) 55 command := []string{ 56 "modifyvm", vmName, 57 "--natpf1", 58 fmt.Sprintf("packerssh,tcp,127.0.0.1,%d,,%d", sshHostPort, s.GuestPort), 59 } 60 if err := driver.VBoxManage(command...); err != nil { 61 err := fmt.Errorf("Error creating port forwarding rule: %s", err) 62 state.Put("error", err) 63 ui.Error(err.Error()) 64 return multistep.ActionHalt 65 } 66 67 // Save the port we're using so that future steps can use it 68 state.Put("sshHostPort", sshHostPort) 69 70 return multistep.ActionContinue 71 } 72 73 func (s *StepForwardSSH) Cleanup(state multistep.StateBag) {}