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