github.com/alouche/packer@v0.3.7/builder/vmware/step_configure_vnc.go (about)

     1  package vmware
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/mitchellh/multistep"
     6  	"github.com/mitchellh/packer/packer"
     7  	"io/ioutil"
     8  	"log"
     9  	"math/rand"
    10  	"net"
    11  	"os"
    12  )
    13  
    14  // This step configures the VM to enable the VNC server.
    15  //
    16  // Uses:
    17  //   config *config
    18  //   ui     packer.Ui
    19  //   vmx_path string
    20  //
    21  // Produces:
    22  //   vnc_port uint - The port that VNC is configured to listen on.
    23  type stepConfigureVNC struct{}
    24  
    25  func (stepConfigureVNC) Run(state multistep.StateBag) multistep.StepAction {
    26  	config := state.Get("config").(*config)
    27  	ui := state.Get("ui").(packer.Ui)
    28  	vmxPath := state.Get("vmx_path").(string)
    29  
    30  	f, err := os.Open(vmxPath)
    31  	if err != nil {
    32  		err := fmt.Errorf("Error reading VMX data: %s", err)
    33  		state.Put("error", err)
    34  		ui.Error(err.Error())
    35  		return multistep.ActionHalt
    36  	}
    37  
    38  	vmxBytes, err := ioutil.ReadAll(f)
    39  	if err != nil {
    40  		err := fmt.Errorf("Error reading VMX data: %s", err)
    41  		state.Put("error", err)
    42  		ui.Error(err.Error())
    43  		return multistep.ActionHalt
    44  	}
    45  
    46  	// Find an open VNC port. Note that this can still fail later on
    47  	// because we have to release the port at some point. But this does its
    48  	// best.
    49  	log.Printf("Looking for available port between %d and %d", config.VNCPortMin, config.VNCPortMax)
    50  	var vncPort uint
    51  	portRange := int(config.VNCPortMax - config.VNCPortMin)
    52  	for {
    53  		vncPort = uint(rand.Intn(portRange)) + config.VNCPortMin
    54  		log.Printf("Trying port: %d", vncPort)
    55  		l, err := net.Listen("tcp", fmt.Sprintf(":%d", vncPort))
    56  		if err == nil {
    57  			defer l.Close()
    58  			break
    59  		}
    60  	}
    61  
    62  	log.Printf("Found available VNC port: %d", vncPort)
    63  
    64  	vmxData := ParseVMX(string(vmxBytes))
    65  	vmxData["RemoteDisplay.vnc.enabled"] = "TRUE"
    66  	vmxData["RemoteDisplay.vnc.port"] = fmt.Sprintf("%d", vncPort)
    67  
    68  	if err := WriteVMX(vmxPath, vmxData); err != nil {
    69  		err := fmt.Errorf("Error writing VMX data: %s", err)
    70  		state.Put("error", err)
    71  		ui.Error(err.Error())
    72  		return multistep.ActionHalt
    73  	}
    74  
    75  	state.Put("vnc_port", vncPort)
    76  
    77  	return multistep.ActionContinue
    78  }
    79  
    80  func (stepConfigureVNC) Cleanup(multistep.StateBag) {
    81  }