From 610a90c727a7b66b8a04b4ca46f43ae7b76123c3 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Wed, 13 Jan 2016 17:45:17 +0000 Subject: [PATCH 1/2] Claim address requested by caller --- api/ipam.go | 6 ++++++ ipam/claim.go | 6 ++++++ plugin/ipam/driver.go | 21 ++++++++++++++------- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/api/ipam.go b/api/ipam.go index 7f1dcacc..3de18937 100644 --- a/api/ipam.go +++ b/api/ipam.go @@ -32,6 +32,12 @@ func (client *Client) LookupIP(ID string) (*net.IPNet, error) { return client.ipamOp(ID, "GET") } +// Claim a specific IP on behalf of the ID +func (client *Client) ClaimIP(ID string, addr net.IP) error { + _, err := client.httpVerb("PUT", fmt.Sprintf("/ip/%s/%s", ID, addr), nil) + return err +} + // release an IP which is no longer needed func (client *Client) ReleaseIP(ID string) error { _, err := client.ipamOp(ID, "DELETE") diff --git a/ipam/claim.go b/ipam/claim.go index 216c2dd2..2b33b145 100644 --- a/ipam/claim.go +++ b/ipam/claim.go @@ -75,6 +75,9 @@ func (c *claim) Try(alloc *Allocator) bool { case "": if err := alloc.space.Claim(c.addr); err == nil { alloc.debugln("Claimed", c.addr, "for", c.ident) + if c.ident == "_" { // Special "I don't have a unique ID" identifier + c.ident = c.addr.String() + } alloc.addOwned(c.ident, c.addr) c.sendResult(nil) } else { @@ -84,6 +87,9 @@ func (c *claim) Try(alloc *Allocator) bool { // same identifier is claiming same address; that's OK alloc.debugln("Re-Claimed", c.addr, "for", c.ident) c.sendResult(nil) + case c.addr.String(): + // Address already allocated via "_" name + c.sendResult(fmt.Errorf("address %s already in use", c.addr)) default: // Addr already owned by container on this machine c.sendResult(fmt.Errorf("address %s is already owned by %s", c.addr.String(), existingIdent)) diff --git a/plugin/ipam/driver.go b/plugin/ipam/driver.go index 77cf99b4..1d18a7bc 100644 --- a/plugin/ipam/driver.go +++ b/plugin/ipam/driver.go @@ -78,14 +78,21 @@ func (i *ipam) RequestAddress(poolID string, address net.IP, options map[string] if _, subnet, err = net.ParseCIDR(parts[1]); err != nil { return } - if _, iprange, err = net.ParseCIDR(parts[2]); err != nil { - return + if address != nil { // try to claim specific address requested + if err = i.weave.ClaimIP("_", address); err != nil { + return + } + ip = &net.IPNet{IP: address, Mask: subnet.Mask} + } else { + if _, iprange, err = net.ParseCIDR(parts[2]); err != nil { + return + } + // We are lying slightly to IPAM here: the range is not a subnet + if ip, err = i.weave.AllocateIPInSubnet("_", iprange); err != nil { + return + } + ip.Mask = subnet.Mask // fix up the subnet we lied about } - // We are lying slightly to IPAM here: the range is not a subnet - if ip, err = i.weave.AllocateIPInSubnet("_", iprange); err != nil { - return - } - ip.Mask = subnet.Mask // fix up the subnet we lied about return } From 482045aed8e4e20e6de2091ea297b3f152873ac7 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Wed, 27 Jan 2016 14:53:26 +0000 Subject: [PATCH 2/2] Send back an http error code with any plugin errors. --- plugin/skel/listener.go | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin/skel/listener.go b/plugin/skel/listener.go index 2b4deb71..afe0584e 100644 --- a/plugin/skel/listener.go +++ b/plugin/skel/listener.go @@ -265,6 +265,7 @@ func sendError(w http.ResponseWriter, msg string, code int) { } func errorResponse(w http.ResponseWriter, fmtString string, item ...interface{}) { + w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{ "Err": fmt.Sprintf(fmtString, item...), })