Skip to content

Commit 86938fc

Browse files
committed
Add libvirt API method to obtain DHCP leases.
Requires libvirt >= 1.2.6. The tag libvirt.1.2.14 is required by libvirt-go to enable its use, since a wider range of libvirt versions are supported there. Initial patch provided by Casey Marshall <[email protected]>
1 parent f328c4b commit 86938fc

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
default: build
22

33
build:
4-
GOGC=off go build -i -o docker-machine-driver-kvm
4+
GOGC=off go build -tags libvirt.1.2.14 -i -o docker-machine-driver-kvm

kvm.go

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,25 @@ func (d *Driver) getMAC() (string, error) {
592592
return dom.Devices.Interfaces[1].Mac.Address, nil
593593
}
594594

595+
func (d *Driver) getIPByMACFromAPI(mac string) (string, error) {
596+
network, err := d.conn.LookupNetworkByName(d.PrivateNetwork)
597+
if err != nil {
598+
log.Errorf("Failed to lookup network %s", d.PrivateNetwork)
599+
return "", err
600+
}
601+
leases, err := network.GetDHCPLeases()
602+
if err != nil {
603+
log.Warnf("Failed to retrieve DHCP leases from libvirt: %v", err)
604+
return "", err
605+
}
606+
for _, lease := range leases {
607+
if strings.ToLower(mac) == strings.ToLower(lease.GetMACAddress()) {
608+
return lease.GetIPAddress(), nil
609+
}
610+
}
611+
return "", errors.New("failed to match IP for MAC address")
612+
}
613+
595614
func (d *Driver) getIPByMACFromLeaseFile(mac string) (string, error) {
596615
leaseFile := fmt.Sprintf(dnsmasqLeases, d.PrivateNetwork)
597616
data, err := ioutil.ReadFile(leaseFile)
@@ -633,6 +652,11 @@ func (d *Driver) getIPByMacFromSettings(mac string) (string, error) {
633652
}
634653
statusFile := fmt.Sprintf(dnsmasqStatus, bridge_name)
635654
data, err := ioutil.ReadFile(statusFile)
655+
if err != nil {
656+
log.Debugf("Failed to read dnsmasq status from %s", statusFile)
657+
return "", err
658+
}
659+
636660
type Lease struct {
637661
Ip_address string `json:"ip-address"`
638662
Mac_address string `json:"mac-address"`
@@ -659,22 +683,27 @@ func (d *Driver) getIPByMacFromSettings(mac string) (string, error) {
659683
return ipAddr, nil
660684
}
661685

686+
type ipLookupFunc func(mac string) (string, error)
687+
662688
func (d *Driver) GetIP() (string, error) {
663689
log.Debugf("GetIP called for %s", d.MachineName)
664690
mac, err := d.getMAC()
665691
if err != nil {
666692
return "", err
667693
}
668-
/*
669-
* TODO - Figure out what version of libvirt changed behavior and
670-
* be smarter about selecting which algorithm to use
671-
*/
672-
ip, err := d.getIPByMACFromLeaseFile(mac)
673-
if ip == "" {
674-
ip, err = d.getIPByMacFromSettings(mac)
694+
695+
methods := []ipLookupFunc{
696+
d.getIPByMACFromLeaseFile,
697+
d.getIPByMacFromSettings,
698+
d.getIPByMACFromAPI,
699+
}
700+
for _, method := range methods {
701+
ip, err := method(mac)
702+
if err == nil {
703+
return ip, nil
704+
}
675705
}
676-
log.Debugf("Unable to locate IP address for MAC %s", mac)
677-
return ip, err
706+
return "", fmt.Errorf("unable to locate IP address for MAC %s")
678707
}
679708

680709
func (d *Driver) publicSSHKeyPath() string {

0 commit comments

Comments
 (0)