github.com/raghuse92/packer@v1.3.2/builder/qemu/step_forward_ssh.go (about)

     1  package qemu
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"log"
     7  	"math/rand"
     8  	"net"
     9  
    10  	"github.com/hashicorp/packer/helper/multistep"
    11  	"github.com/hashicorp/packer/packer"
    12  )
    13  
    14  // This step adds a NAT port forwarding definition so that SSH is available
    15  // on the guest machine.
    16  //
    17  // Uses:
    18  //
    19  // Produces:
    20  type stepForwardSSH struct{}
    21  
    22  func (s *stepForwardSSH) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
    23  	config := state.Get("config").(*Config)
    24  	ui := state.Get("ui").(packer.Ui)
    25  
    26  	log.Printf("Looking for available communicator (SSH, WinRM, etc) port between %d and %d", config.SSHHostPortMin, config.SSHHostPortMax)
    27  	var sshHostPort uint
    28  
    29  	portRange := config.SSHHostPortMax - config.SSHHostPortMin + 1
    30  	offset := uint(rand.Intn(int(portRange)))
    31  
    32  	for {
    33  		sshHostPort = offset + config.SSHHostPortMin
    34  		log.Printf("Trying port: %d", sshHostPort)
    35  		l, err := net.Listen("tcp", fmt.Sprintf(":%d", sshHostPort))
    36  		if err == nil {
    37  			defer l.Close()
    38  			break
    39  		}
    40  		offset++
    41  		if offset == portRange {
    42  			offset = 0
    43  		}
    44  	}
    45  	ui.Say(fmt.Sprintf("Found port for communicator (SSH, WinRM, etc): %d.", sshHostPort))
    46  
    47  	// Save the port we're using so that future steps can use it
    48  	state.Put("sshHostPort", sshHostPort)
    49  
    50  	return multistep.ActionContinue
    51  }
    52  
    53  func (s *stepForwardSSH) Cleanup(state multistep.StateBag) {}