From 3a4124d257f32e8b1bc770c9806bf68a84afc8d2 Mon Sep 17 00:00:00 2001 From: Stefan Junker Date: Fri, 27 May 2016 11:52:44 +0200 Subject: [PATCH] pkg/ns: introduce error types indicate NS verification --- ns/ns.go | 38 +++++++++++++++++++++++--------------- ns/ns_test.go | 24 +++++++++++++++--------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/ns/ns.go b/ns/ns.go index a03ee1e0..e29f712c 100644 --- a/ns/ns.go +++ b/ns/ns.go @@ -81,11 +81,23 @@ const ( PROCFS_MAGIC = 0x9fa0 ) -func IsNS(nspath string) (isNS bool, msg string, err error) { +type NSPathNotExistErr struct{ msg string } + +func (e NSPathNotExistErr) Error() string { return e.msg } + +type NSPathNotNSErr struct{ msg string } + +func (e NSPathNotNSErr) Error() string { return e.msg } + +func IsNSorErr(nspath string) error { stat := syscall.Statfs_t{} - if err = syscall.Statfs(nspath, &stat); err != nil { - err = fmt.Errorf("failed to Statfs %s: %v", nspath, err) - return + if err := syscall.Statfs(nspath, &stat); err != nil { + if os.IsNotExist(err) { + err = NSPathNotExistErr{msg: fmt.Sprintf("failed to Statfs %q: %v", nspath, err)} + } else { + err = fmt.Errorf("failed to Statfs %q: %v", nspath, err) + } + return err } switch stat.Type { @@ -95,33 +107,29 @@ func IsNS(nspath string) (isNS bool, msg string, err error) { validPathContent := "ns/" validName := strings.Contains(nspath, validPathContent) if !validName { - msg = fmt.Sprintf("path doesn't contain %q", validPathContent) - return + return NSPathNotNSErr{msg: fmt.Sprintf("path %q doesn't contain %q", nspath, validPathContent)} } - isNS = true + + return nil case NSFS_MAGIC: // Kernel >= 3.19 - isNS = true + return nil default: - msg = fmt.Sprintf("unknown FS magic: %x", stat.Type) + return NSPathNotNSErr{msg: fmt.Sprintf("unknown FS magic on %q: %x", nspath, stat.Type)} } - return } // Returns an object representing the namespace referred to by @path func GetNS(nspath string) (NetNS, error) { - isNS, msg, err := IsNS(nspath) + err := IsNSorErr(nspath) if err != nil { return nil, err } - if !isNS { - return nil, fmt.Errorf("no network namespace detected on %s: %s", nspath, msg) - } fd, err := os.Open(nspath) if err != nil { - return nil, fmt.Errorf("Failed to open %v: %v", nspath, err) + return nil, err } return &netNS{file: fd}, nil diff --git a/ns/ns_test.go b/ns/ns_test.go index 5b0b587d..44ed2728 100644 --- a/ns/ns_test.go +++ b/ns/ns_test.go @@ -181,8 +181,8 @@ var _ = Describe("Linux namespace operations", func() { _, err = ns.GetNS(nspath) Expect(err).To(HaveOccurred()) - errString := fmt.Sprintf("%v", err) - Expect(errString).To(HavePrefix("no network namespace detected on %s", nspath)) + Expect(err).To(BeAssignableToTypeOf(ns.NSPathNotNSErr{})) + Expect(err).NotTo(BeAssignableToTypeOf(ns.NSPathNotExistErr{})) }) }) @@ -214,13 +214,11 @@ var _ = Describe("Linux namespace operations", func() { }) }) - Describe("IsNS", func() { + Describe("IsNSorErr", func() { It("should detect a namespace", func() { createdNetNS, err := ns.NewNS() - isNSFS, msg, err := ns.IsNS(createdNetNS.Path()) + err = ns.IsNSorErr(createdNetNS.Path()) Expect(err).NotTo(HaveOccurred()) - Expect(msg).To(Equal("")) - Expect(isNSFS).To(Equal(true)) }) It("should refuse other paths", func() { @@ -231,9 +229,17 @@ var _ = Describe("Linux namespace operations", func() { nspath := tempFile.Name() defer os.Remove(nspath) - isNSFS, _, err := ns.IsNS(nspath) - Expect(err).NotTo(HaveOccurred()) - Expect(isNSFS).To(Equal(false)) + err = ns.IsNSorErr(nspath) + Expect(err).To(HaveOccurred()) + Expect(err).To(BeAssignableToTypeOf(ns.NSPathNotNSErr{})) + Expect(err).NotTo(BeAssignableToTypeOf(ns.NSPathNotExistErr{})) + }) + + It("should error on non-existing paths", func() { + err := ns.IsNSorErr("/tmp/IDoNotExist") + Expect(err).To(HaveOccurred()) + Expect(err).To(BeAssignableToTypeOf(ns.NSPathNotExistErr{})) + Expect(err).NotTo(BeAssignableToTypeOf(ns.NSPathNotNSErr{})) }) }) })