From 76028d7f8c6aecc4a0ba3202d8006d8f0ae674c9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 9 Dec 2016 18:16:38 -0600 Subject: [PATCH] host-local: trim whitespace from container IDs and disk file contents It doesn't seem like container IDs should really have whitespace or newlines in them. As a complete edge-case, manipulating the host-local store's IP reservations with 'echo' puts a newline at the end, which caused matching to fail in ReleaseByID(). Don't ask... --- .../ipam/host-local/backend/disk/backend.go | 5 +- plugins/ipam/host-local/host_local_test.go | 48 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/plugins/ipam/host-local/backend/disk/backend.go b/plugins/ipam/host-local/backend/disk/backend.go index 14dd40d6..703ec09d 100644 --- a/plugins/ipam/host-local/backend/disk/backend.go +++ b/plugins/ipam/host-local/backend/disk/backend.go @@ -20,6 +20,7 @@ import ( "net" "os" "path/filepath" + "strings" ) const lastIPFile = "last_reserved_ip" @@ -56,7 +57,7 @@ func (s *Store) Reserve(id string, ip net.IP) (bool, error) { if err != nil { return false, err } - if _, err := f.WriteString(id); err != nil { + if _, err := f.WriteString(strings.TrimSpace(id)); err != nil { f.Close() os.Remove(f.Name()) return false, err @@ -99,7 +100,7 @@ func (s *Store) ReleaseByID(id string) error { if err != nil { return nil } - if string(data) == id { + if strings.TrimSpace(string(data)) == strings.TrimSpace(id) { if err := os.Remove(path); err != nil { return nil } diff --git a/plugins/ipam/host-local/host_local_test.go b/plugins/ipam/host-local/host_local_test.go index 41dba71c..97b3b6ff 100644 --- a/plugins/ipam/host-local/host_local_test.go +++ b/plugins/ipam/host-local/host_local_test.go @@ -89,4 +89,52 @@ var _ = Describe("host-local Operations", func() { _, err = os.Stat(ipFilePath) Expect(err).To(HaveOccurred()) }) + + It("ignores whitespace in disk files", func() { + const ifname string = "eth0" + const nspath string = "/some/where" + + tmpDir, err := ioutil.TempDir("", "host_local_artifacts") + Expect(err).NotTo(HaveOccurred()) + defer os.RemoveAll(tmpDir) + + conf := fmt.Sprintf(`{ + "cniVersion": "0.2.0", + "name": "mynet", + "type": "ipvlan", + "master": "foo0", + "ipam": { + "type": "host-local", + "subnet": "10.1.2.0/24", + "dataDir": "%s" + } +}`, tmpDir) + + args := &skel.CmdArgs{ + ContainerID: " dummy\n ", + Netns: nspath, + IfName: ifname, + StdinData: []byte(conf), + } + + // Allocate the IP + result, err := testutils.CmdAddWithResult(nspath, ifname, func() error { + return cmdAdd(args) + }) + Expect(err).NotTo(HaveOccurred()) + + ipFilePath := filepath.Join(tmpDir, "mynet", result.IP4.IP.IP.String()) + contents, err := ioutil.ReadFile(ipFilePath) + Expect(err).NotTo(HaveOccurred()) + Expect(string(contents)).To(Equal("dummy")) + + // Release the IP + err = testutils.CmdDelWithResult(nspath, ifname, func() error { + return cmdDel(args) + }) + Expect(err).NotTo(HaveOccurred()) + + _, err = os.Stat(ipFilePath) + Expect(err).To(HaveOccurred()) + }) })