github.com/rothwerx/packer@v0.9.0/builder/vmware/common/guest_ip.go (about)

     1  package common
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"log"
     8  	"os"
     9  	"regexp"
    10  	"strings"
    11  	"time"
    12  )
    13  
    14  // Interface to help find the IP address of a running virtual machine.
    15  type GuestIPFinder interface {
    16  	GuestIP() (string, error)
    17  }
    18  
    19  // DHCPLeaseGuestLookup looks up the IP address of a guest using DHCP
    20  // lease information from the VMware network devices.
    21  type DHCPLeaseGuestLookup struct {
    22  	// Driver that is being used (to find leases path)
    23  	Driver Driver
    24  
    25  	// Device that the guest is connected to.
    26  	Device string
    27  
    28  	// MAC address of the guest.
    29  	MACAddress string
    30  }
    31  
    32  func (f *DHCPLeaseGuestLookup) GuestIP() (string, error) {
    33  	dhcpLeasesPath := f.Driver.DhcpLeasesPath(f.Device)
    34  	log.Printf("DHCP leases path: %s", dhcpLeasesPath)
    35  	if dhcpLeasesPath == "" {
    36  		return "", errors.New("no DHCP leases path found.")
    37  	}
    38  
    39  	fh, err := os.Open(dhcpLeasesPath)
    40  	if err != nil {
    41  		return "", err
    42  	}
    43  	defer fh.Close()
    44  
    45  	dhcpBytes, err := ioutil.ReadAll(fh)
    46  	if err != nil {
    47  		return "", err
    48  	}
    49  
    50  	var lastIp string
    51  	var lastLeaseEnd time.Time
    52  
    53  	var curIp string
    54  	var curLeaseEnd time.Time
    55  
    56  	ipLineRe := regexp.MustCompile(`^lease (.+?) {$`)
    57  	endTimeLineRe := regexp.MustCompile(`^\s*ends \d (.+?);$`)
    58  	macLineRe := regexp.MustCompile(`^\s*hardware ethernet (.+?);$`)
    59  
    60  	for _, line := range strings.Split(string(dhcpBytes), "\n") {
    61  		// Need to trim off CR character when running in windows
    62  		line = strings.TrimRight(line, "\r")
    63  
    64  		matches := ipLineRe.FindStringSubmatch(line)
    65  		if matches != nil {
    66  			lastIp = matches[1]
    67  			continue
    68  		}
    69  
    70  		matches = endTimeLineRe.FindStringSubmatch(line)
    71  		if matches != nil {
    72  			lastLeaseEnd, _ = time.Parse("2006/01/02 15:04:05", matches[1])
    73  			continue
    74  		}
    75  
    76  		// If the mac address matches and this lease ends farther in the
    77  		// future than the last match we might have, then choose it.
    78  		matches = macLineRe.FindStringSubmatch(line)
    79  		if matches != nil && strings.EqualFold(matches[1], f.MACAddress) && curLeaseEnd.Before(lastLeaseEnd) {
    80  			curIp = lastIp
    81  			curLeaseEnd = lastLeaseEnd
    82  		}
    83  	}
    84  
    85  	if curIp == "" {
    86  		return "", fmt.Errorf("IP not found for MAC %s in DHCP leases at %s", f.MACAddress, dhcpLeasesPath)
    87  	}
    88  
    89  	return curIp, nil
    90  }