From e8771b36a2934a8be89612f09f4adcc2a36ec93e Mon Sep 17 00:00:00 2001 From: Bruce Ma Date: Sat, 1 Jun 2019 17:53:46 +0800 Subject: [PATCH] host-local: make allocation idempotent to multiple requests with same id Signed-off-by: Bruce Ma --- .../host-local/backend/allocator/allocator.go | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/plugins/ipam/host-local/backend/allocator/allocator.go b/plugins/ipam/host-local/backend/allocator/allocator.go index d1c2b101..2d9f80ec 100644 --- a/plugins/ipam/host-local/backend/allocator/allocator.go +++ b/plugins/ipam/host-local/backend/allocator/allocator.go @@ -40,7 +40,7 @@ func NewIPAllocator(s *RangeSet, store backend.Store, id int) *IPAllocator { } } -// Get alocates an IP +// Get allocates an IP func (a *IPAllocator) Get(id string, ifname string, requestedIP net.IP) (*current.IPConfig, error) { a.store.Lock() defer a.store.Unlock() @@ -73,24 +73,39 @@ func (a *IPAllocator) Get(id string, ifname string, requestedIP net.IP) (*curren gw = r.Gateway } else { - iter, err := a.GetIter() - if err != nil { - return nil, err - } - for { - reservedIP, gw = iter.Next() - if reservedIP == nil { + // try to get existing IPs which have been allocated to this id + existIPs := a.store.GetByID(id, ifname) + for _, existIP := range existIPs { + // check whether the existing IP belong to this range set + if r, err := a.rangeset.RangeFor(existIP); err == nil { + reservedIP = &net.IPNet{IP: existIP, Mask: r.Subnet.Mask} + gw = r.Gateway break } + } - reserved, err := a.store.Reserve(id, ifname, reservedIP.IP, a.rangeID) + // if no existing IP was found, try to reserve a new one + if reservedIP == nil { + iter, err := a.GetIter() if err != nil { return nil, err } + for { + reservedIP, gw = iter.Next() + if reservedIP == nil { + break + } - if reserved { - break + reserved, err := a.store.Reserve(id, ifname, reservedIP.IP, a.rangeID) + if err != nil { + return nil, err + } + + if reserved { + break + } } + } }