Skip to content

Commit

Permalink
Add libvirt API method to obtain DHCP leases.
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
flavio committed Apr 5, 2017
1 parent b14a80e commit 65cc49e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 10 deletions.
2 changes: 1 addition & 1 deletion cmd/docker-machine-driver-kvm/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
default: build

build:
GOGC=off go build -i -o docker-machine-driver-kvm
GOGC=off go build -tags libvirt.1.2.14 -i -o docker-machine-driver-kvm
47 changes: 38 additions & 9 deletions kvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,25 @@ func (d *Driver) getMAC() (string, error) {
return dom.Devices.Interfaces[1].Mac.Address, nil
}

func (d *Driver) getIPByMACFromAPI(mac string) (string, error) {
network, err := d.conn.LookupNetworkByName(d.PrivateNetwork)
if err != nil {
log.Errorf("Failed to lookup network %s", d.PrivateNetwork)
return "", err
}
leases, err := network.GetDHCPLeases()
if err != nil {
log.Warnf("Failed to retrieve DHCP leases from libvirt: %v", err)
return "", err
}
for _, lease := range leases {
if strings.ToLower(mac) == strings.ToLower(lease.GetMACAddress()) {
return lease.GetIPAddress(), nil
}
}
return "", errors.New("failed to match IP for MAC address")
}

func (d *Driver) getIPByMACFromLeaseFile(mac string) (string, error) {
leaseFile := fmt.Sprintf(dnsmasqLeases, d.PrivateNetwork)
data, err := ioutil.ReadFile(leaseFile)
Expand Down Expand Up @@ -626,6 +645,11 @@ func (d *Driver) getIPByMacFromSettings(mac string) (string, error) {
}
statusFile := fmt.Sprintf(dnsmasqStatus, bridge_name)
data, err := ioutil.ReadFile(statusFile)
if err != nil {
log.Debugf("Failed to read dnsmasq status from %s", statusFile)
return "", err
}

type Lease struct {
Ip_address string `json:"ip-address"`
Mac_address string `json:"mac-address"`
Expand All @@ -652,22 +676,27 @@ func (d *Driver) getIPByMacFromSettings(mac string) (string, error) {
return ipAddr, nil
}

type ipLookupFunc func(mac string) (string, error)

func (d *Driver) GetIP() (string, error) {
log.Debugf("GetIP called for %s", d.MachineName)
mac, err := d.getMAC()
if err != nil {
return "", err
}
/*
* TODO - Figure out what version of libvirt changed behavior and
* be smarter about selecting which algorithm to use
*/
ip, err := d.getIPByMACFromLeaseFile(mac)
if ip == "" {
ip, err = d.getIPByMacFromSettings(mac)

methods := []ipLookupFunc{
d.getIPByMACFromLeaseFile,
d.getIPByMacFromSettings,
d.getIPByMACFromAPI,
}
for _, method := range methods {
ip, err := method(mac)
if err == nil {
return ip, nil
}
}
log.Debugf("Unable to locate IP address for MAC %s", mac)
return ip, err
return "", fmt.Errorf("unable to locate IP address for MAC %s")
}

func (d *Driver) publicSSHKeyPath() string {
Expand Down

0 comments on commit 65cc49e

Please sign in to comment.