Obtain ifname from CmdArgs and pass to backend Add ifname to second line of file tracking the IP address used by ContainerID

Update host-local tests to use ifname along with ContainerID
in store file

Signed-off-by: Michael Cambria <mcambria@redhat.com>
This commit is contained in:
Michael Cambria
2018-09-10 16:00:47 -04:00
parent 726759b29b
commit 1e8f9525a6
7 changed files with 36 additions and 36 deletions

View File

@ -41,7 +41,7 @@ func NewIPAllocator(s *RangeSet, store backend.Store, id int) *IPAllocator {
} }
// Get alocates an IP // Get alocates an IP
func (a *IPAllocator) Get(id string, requestedIP net.IP) (*current.IPConfig, error) { func (a *IPAllocator) Get(id string, ifname string, requestedIP net.IP) (*current.IPConfig, error) {
a.store.Lock() a.store.Lock()
defer a.store.Unlock() defer a.store.Unlock()
@ -62,7 +62,7 @@ func (a *IPAllocator) Get(id string, requestedIP net.IP) (*current.IPConfig, err
return nil, fmt.Errorf("requested ip %s is subnet's gateway", requestedIP.String()) return nil, fmt.Errorf("requested ip %s is subnet's gateway", requestedIP.String())
} }
reserved, err := a.store.Reserve(id, requestedIP, a.rangeID) reserved, err := a.store.Reserve(id, ifname, requestedIP, a.rangeID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -83,7 +83,7 @@ func (a *IPAllocator) Get(id string, requestedIP net.IP) (*current.IPConfig, err
break break
} }
reserved, err := a.store.Reserve(id, reservedIP.IP, a.rangeID) reserved, err := a.store.Reserve(id, ifname, reservedIP.IP, a.rangeID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -110,11 +110,11 @@ func (a *IPAllocator) Get(id string, requestedIP net.IP) (*current.IPConfig, err
} }
// Release clears all IPs allocated for the container with given ID // Release clears all IPs allocated for the container with given ID
func (a *IPAllocator) Release(id string) error { func (a *IPAllocator) Release(id string, ifname string) error {
a.store.Lock() a.store.Lock()
defer a.store.Unlock() defer a.store.Unlock()
return a.store.ReleaseByID(id) return a.store.ReleaseByID(id, ifname)
} }
type RangeIter struct { type RangeIter struct {

View File

@ -70,7 +70,7 @@ func (t AllocatorTestCase) run(idx int) (*current.IPConfig, error) {
rangeID: "rangeid", rangeID: "rangeid",
} }
return alloc.Get("ID", nil) return alloc.Get("ID", "eth0", nil)
} }
var _ = Describe("host-local ip allocator", func() { var _ = Describe("host-local ip allocator", func() {
@ -88,8 +88,8 @@ var _ = Describe("host-local ip allocator", func() {
It("should loop correctly from the end", func() { It("should loop correctly from the end", func() {
a := mkalloc() a := mkalloc()
a.store.Reserve("ID", net.IP{192, 168, 1, 6}, a.rangeID) a.store.Reserve("ID", "eth0", net.IP{192, 168, 1, 6}, a.rangeID)
a.store.ReleaseByID("ID") a.store.ReleaseByID("ID", "eth0")
r, _ := a.GetIter() r, _ := a.GetIter()
Expect(r.nextip()).To(Equal(net.IP{192, 168, 1, 2})) Expect(r.nextip()).To(Equal(net.IP{192, 168, 1, 2}))
Expect(r.nextip()).To(Equal(net.IP{192, 168, 1, 3})) Expect(r.nextip()).To(Equal(net.IP{192, 168, 1, 3}))
@ -100,8 +100,8 @@ var _ = Describe("host-local ip allocator", func() {
}) })
It("should loop correctly from the middle", func() { It("should loop correctly from the middle", func() {
a := mkalloc() a := mkalloc()
a.store.Reserve("ID", net.IP{192, 168, 1, 3}, a.rangeID) a.store.Reserve("ID", "eth0", net.IP{192, 168, 1, 3}, a.rangeID)
a.store.ReleaseByID("ID") a.store.ReleaseByID("ID", "eth0")
r, _ := a.GetIter() r, _ := a.GetIter()
Expect(r.nextip()).To(Equal(net.IP{192, 168, 1, 4})) Expect(r.nextip()).To(Equal(net.IP{192, 168, 1, 4}))
Expect(r.nextip()).To(Equal(net.IP{192, 168, 1, 5})) Expect(r.nextip()).To(Equal(net.IP{192, 168, 1, 5}))
@ -221,28 +221,28 @@ var _ = Describe("host-local ip allocator", func() {
It("should not allocate the broadcast address", func() { It("should not allocate the broadcast address", func() {
alloc := mkalloc() alloc := mkalloc()
for i := 2; i < 7; i++ { for i := 2; i < 7; i++ {
res, err := alloc.Get("ID", nil) res, err := alloc.Get("ID", "eth0", nil)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
s := fmt.Sprintf("192.168.1.%d/29", i) s := fmt.Sprintf("192.168.1.%d/29", i)
Expect(s).To(Equal(res.Address.String())) Expect(s).To(Equal(res.Address.String()))
fmt.Fprintln(GinkgoWriter, "got ip", res.Address.String()) fmt.Fprintln(GinkgoWriter, "got ip", res.Address.String())
} }
x, err := alloc.Get("ID", nil) x, err := alloc.Get("ID", "eth0", nil)
fmt.Fprintln(GinkgoWriter, "got ip", x) fmt.Fprintln(GinkgoWriter, "got ip", x)
Expect(err).To(HaveOccurred()) Expect(err).To(HaveOccurred())
}) })
It("should allocate in a round-robin fashion", func() { It("should allocate in a round-robin fashion", func() {
alloc := mkalloc() alloc := mkalloc()
res, err := alloc.Get("ID", nil) res, err := alloc.Get("ID", "eth0", nil)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(res.Address.String()).To(Equal("192.168.1.2/29")) Expect(res.Address.String()).To(Equal("192.168.1.2/29"))
err = alloc.Release("ID") err = alloc.Release("ID", "eth0")
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
res, err = alloc.Get("ID", nil) res, err = alloc.Get("ID", "eth0", nil)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(res.Address.String()).To(Equal("192.168.1.3/29")) Expect(res.Address.String()).To(Equal("192.168.1.3/29"))
@ -252,7 +252,7 @@ var _ = Describe("host-local ip allocator", func() {
It("must allocate the requested IP", func() { It("must allocate the requested IP", func() {
alloc := mkalloc() alloc := mkalloc()
requestedIP := net.IP{192, 168, 1, 5} requestedIP := net.IP{192, 168, 1, 5}
res, err := alloc.Get("ID", requestedIP) res, err := alloc.Get("ID", "eth0", requestedIP)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(res.Address.IP.String()).To(Equal(requestedIP.String())) Expect(res.Address.IP.String()).To(Equal(requestedIP.String()))
}) })
@ -260,11 +260,11 @@ var _ = Describe("host-local ip allocator", func() {
It("must fail when the requested IP is allocated", func() { It("must fail when the requested IP is allocated", func() {
alloc := mkalloc() alloc := mkalloc()
requestedIP := net.IP{192, 168, 1, 5} requestedIP := net.IP{192, 168, 1, 5}
res, err := alloc.Get("ID", requestedIP) res, err := alloc.Get("ID", "eth0", requestedIP)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(res.Address.IP.String()).To(Equal(requestedIP.String())) Expect(res.Address.IP.String()).To(Equal(requestedIP.String()))
_, err = alloc.Get("ID", requestedIP) _, err = alloc.Get("ID", "eth0", requestedIP)
Expect(err).To(MatchError(`requested IP address 192.168.1.5 is not available in range set 192.168.1.1-192.168.1.6`)) Expect(err).To(MatchError(`requested IP address 192.168.1.5 is not available in range set 192.168.1.1-192.168.1.6`))
}) })
@ -272,7 +272,7 @@ var _ = Describe("host-local ip allocator", func() {
alloc := mkalloc() alloc := mkalloc()
(*alloc.rangeset)[0].RangeEnd = net.IP{192, 168, 1, 4} (*alloc.rangeset)[0].RangeEnd = net.IP{192, 168, 1, 4}
requestedIP := net.IP{192, 168, 1, 5} requestedIP := net.IP{192, 168, 1, 5}
_, err := alloc.Get("ID", requestedIP) _, err := alloc.Get("ID", "eth0", requestedIP)
Expect(err).To(HaveOccurred()) Expect(err).To(HaveOccurred())
}) })
@ -280,7 +280,7 @@ var _ = Describe("host-local ip allocator", func() {
alloc := mkalloc() alloc := mkalloc()
(*alloc.rangeset)[0].RangeStart = net.IP{192, 168, 1, 3} (*alloc.rangeset)[0].RangeStart = net.IP{192, 168, 1, 3}
requestedIP := net.IP{192, 168, 1, 2} requestedIP := net.IP{192, 168, 1, 2}
_, err := alloc.Get("ID", requestedIP) _, err := alloc.Get("ID", "eth0", requestedIP)
Expect(err).To(HaveOccurred()) Expect(err).To(HaveOccurred())
}) })
}) })

View File

@ -55,7 +55,7 @@ func New(network, dataDir string) (*Store, error) {
return &Store{lk, dir}, nil return &Store{lk, dir}, nil
} }
func (s *Store) Reserve(id string, ip net.IP, rangeID string) (bool, error) { func (s *Store) Reserve(id string, ifname string, ip net.IP, rangeID string) (bool, error) {
fname := GetEscapedPath(s.dataDir, ip.String()) fname := GetEscapedPath(s.dataDir, ip.String())
f, err := os.OpenFile(fname, os.O_RDWR|os.O_EXCL|os.O_CREATE, 0644) f, err := os.OpenFile(fname, os.O_RDWR|os.O_EXCL|os.O_CREATE, 0644)
@ -65,7 +65,7 @@ func (s *Store) Reserve(id string, ip net.IP, rangeID string) (bool, error) {
if err != nil { if err != nil {
return false, err return false, err
} }
if _, err := f.WriteString(strings.TrimSpace(id)); err != nil { if _, err := f.WriteString(strings.TrimSpace(id) + "\n" + ifname); err != nil {
f.Close() f.Close()
os.Remove(f.Name()) os.Remove(f.Name())
return false, err return false, err
@ -99,7 +99,7 @@ func (s *Store) Release(ip net.IP) error {
// N.B. This function eats errors to be tolerant and // N.B. This function eats errors to be tolerant and
// release as much as possible // release as much as possible
func (s *Store) ReleaseByID(id string) error { func (s *Store) ReleaseByID(id string, ifname string) error {
err := filepath.Walk(s.dataDir, func(path string, info os.FileInfo, err error) error { err := filepath.Walk(s.dataDir, func(path string, info os.FileInfo, err error) error {
if err != nil || info.IsDir() { if err != nil || info.IsDir() {
return nil return nil
@ -108,7 +108,7 @@ func (s *Store) ReleaseByID(id string) error {
if err != nil { if err != nil {
return nil return nil
} }
if strings.TrimSpace(string(data)) == strings.TrimSpace(id) { if strings.TrimSpace(string(data)) == (strings.TrimSpace(id) + "\n" + ifname) {
if err := os.Remove(path); err != nil { if err := os.Remove(path); err != nil {
return nil return nil
} }

View File

@ -20,8 +20,8 @@ type Store interface {
Lock() error Lock() error
Unlock() error Unlock() error
Close() error Close() error
Reserve(id string, ip net.IP, rangeID string) (bool, error) Reserve(id string, ifname string, ip net.IP, rangeID string) (bool, error)
LastReservedIP(rangeID string) (net.IP, error) LastReservedIP(rangeID string) (net.IP, error)
Release(ip net.IP) error Release(ip net.IP) error
ReleaseByID(id string) error ReleaseByID(id string, ifname string) error
} }

View File

@ -45,7 +45,7 @@ func (s *FakeStore) Close() error {
return nil return nil
} }
func (s *FakeStore) Reserve(id string, ip net.IP, rangeID string) (bool, error) { func (s *FakeStore) Reserve(id string, ifname string, ip net.IP, rangeID string) (bool, error) {
key := ip.String() key := ip.String()
if _, ok := s.ipMap[key]; !ok { if _, ok := s.ipMap[key]; !ok {
s.ipMap[key] = id s.ipMap[key] = id
@ -68,7 +68,7 @@ func (s *FakeStore) Release(ip net.IP) error {
return nil return nil
} }
func (s *FakeStore) ReleaseByID(id string) error { func (s *FakeStore) ReleaseByID(id string, ifname string) error {
toDelete := []string{} toDelete := []string{}
for k, v := range s.ipMap { for k, v := range s.ipMap {
if v == id { if v == id {

View File

@ -111,12 +111,12 @@ var _ = Describe("host-local Operations", func() {
ipFilePath1 := filepath.Join(tmpDir, "mynet", "10.1.2.2") ipFilePath1 := filepath.Join(tmpDir, "mynet", "10.1.2.2")
contents, err := ioutil.ReadFile(ipFilePath1) contents, err := ioutil.ReadFile(ipFilePath1)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(string(contents)).To(Equal(args.ContainerID)) Expect(string(contents)).To(Equal(args.ContainerID + "\n" + ifname))
ipFilePath2 := filepath.Join(tmpDir, disk.GetEscapedPath("mynet", "2001:db8:1::2")) ipFilePath2 := filepath.Join(tmpDir, disk.GetEscapedPath("mynet", "2001:db8:1::2"))
contents, err = ioutil.ReadFile(ipFilePath2) contents, err = ioutil.ReadFile(ipFilePath2)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(string(contents)).To(Equal(args.ContainerID)) Expect(string(contents)).To(Equal(args.ContainerID + "\n" + ifname))
lastFilePath1 := filepath.Join(tmpDir, "mynet", "last_reserved_ip.0") lastFilePath1 := filepath.Join(tmpDir, "mynet", "last_reserved_ip.0")
contents, err = ioutil.ReadFile(lastFilePath1) contents, err = ioutil.ReadFile(lastFilePath1)
@ -223,7 +223,7 @@ var _ = Describe("host-local Operations", func() {
ipFilePath := filepath.Join(tmpDir, "mynet", "10.1.2.2") ipFilePath := filepath.Join(tmpDir, "mynet", "10.1.2.2")
contents, err := ioutil.ReadFile(ipFilePath) contents, err := ioutil.ReadFile(ipFilePath)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(string(contents)).To(Equal(args.ContainerID)) Expect(string(contents)).To(Equal(args.ContainerID + "\n" + ifname))
lastFilePath := filepath.Join(tmpDir, "mynet", "last_reserved_ip.0") lastFilePath := filepath.Join(tmpDir, "mynet", "last_reserved_ip.0")
contents, err = ioutil.ReadFile(lastFilePath) contents, err = ioutil.ReadFile(lastFilePath)
@ -281,7 +281,7 @@ var _ = Describe("host-local Operations", func() {
ipFilePath := filepath.Join(tmpDir, "mynet", result.IPs[0].Address.IP.String()) ipFilePath := filepath.Join(tmpDir, "mynet", result.IPs[0].Address.IP.String())
contents, err := ioutil.ReadFile(ipFilePath) contents, err := ioutil.ReadFile(ipFilePath)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(string(contents)).To(Equal("dummy")) Expect(string(contents)).To(Equal("dummy" + "\n" + ifname))
// Release the IP // Release the IP
err = testutils.CmdDelWithArgs(args, func() error { err = testutils.CmdDelWithArgs(args, func() error {

View File

@ -85,11 +85,11 @@ func cmdAdd(args *skel.CmdArgs) error {
} }
} }
ipConf, err := allocator.Get(args.ContainerID, requestedIP) ipConf, err := allocator.Get(args.ContainerID, args.IfName, requestedIP)
if err != nil { if err != nil {
// Deallocate all already allocated IPs // Deallocate all already allocated IPs
for _, alloc := range allocs { for _, alloc := range allocs {
_ = alloc.Release(args.ContainerID) _ = alloc.Release(args.ContainerID, args.IfName)
} }
return fmt.Errorf("failed to allocate for range %d: %v", idx, err) return fmt.Errorf("failed to allocate for range %d: %v", idx, err)
} }
@ -102,7 +102,7 @@ func cmdAdd(args *skel.CmdArgs) error {
// If an IP was requested that wasn't fulfilled, fail // If an IP was requested that wasn't fulfilled, fail
if len(requestedIPs) != 0 { if len(requestedIPs) != 0 {
for _, alloc := range allocs { for _, alloc := range allocs {
_ = alloc.Release(args.ContainerID) _ = alloc.Release(args.ContainerID, args.IfName)
} }
errstr := "failed to allocate all requested IPs:" errstr := "failed to allocate all requested IPs:"
for _, ip := range requestedIPs { for _, ip := range requestedIPs {
@ -133,7 +133,7 @@ func cmdDel(args *skel.CmdArgs) error {
for idx, rangeset := range ipamConf.Ranges { for idx, rangeset := range ipamConf.Ranges {
ipAllocator := allocator.NewIPAllocator(&rangeset, store, idx) ipAllocator := allocator.NewIPAllocator(&rangeset, store, idx)
err := ipAllocator.Release(args.ContainerID) err := ipAllocator.Release(args.ContainerID, args.IfName)
if err != nil { if err != nil {
errors = append(errors, err.Error()) errors = append(errors, err.Error())
} }