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 }