github.com/alouche/packer@v0.3.7/builder/virtualbox/step_forward_ssh.go (about)

     1  package virtualbox
     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  //
    17  // Produces:
    18  type stepForwardSSH struct{}
    19  
    20  func (s *stepForwardSSH) Run(state multistep.StateBag) multistep.StepAction {
    21  	config := state.Get("config").(*config)
    22  	driver := state.Get("driver").(Driver)
    23  	ui := state.Get("ui").(packer.Ui)
    24  	vmName := state.Get("vmName").(string)
    25  
    26  	log.Printf("Looking for available SSH port between %d and %d", config.SSHHostPortMin, config.SSHHostPortMax)
    27  	var sshHostPort uint
    28  	portRange := int(config.SSHHostPortMax - config.SSHHostPortMin)
    29  	for {
    30  		sshHostPort = uint(rand.Intn(portRange)) + config.SSHHostPortMin
    31  		log.Printf("Trying port: %d", sshHostPort)
    32  		l, err := net.Listen("tcp", fmt.Sprintf(":%d", sshHostPort))
    33  		if err == nil {
    34  			defer l.Close()
    35  			break
    36  		}
    37  	}
    38  
    39  	// Create a forwarded port mapping to the VM
    40  	ui.Say(fmt.Sprintf("Creating forwarded port mapping for SSH (host port %d)", sshHostPort))
    41  	command := []string{
    42  		"modifyvm", vmName,
    43  		"--natpf1",
    44  		fmt.Sprintf("packerssh,tcp,127.0.0.1,%d,,%d", sshHostPort, config.SSHPort),
    45  	}
    46  	if err := driver.VBoxManage(command...); err != nil {
    47  		err := fmt.Errorf("Error creating port forwarding rule: %s", err)
    48  		state.Put("error", err)
    49  		ui.Error(err.Error())
    50  		return multistep.ActionHalt
    51  	}
    52  
    53  	// Save the port we're using so that future steps can use it
    54  	state.Put("sshHostPort", sshHostPort)
    55  
    56  	return multistep.ActionContinue
    57  }
    58  
    59  func (s *stepForwardSSH) Cleanup(state multistep.StateBag) {}