pkg/ns: introduce error types indicate NS verification
authorStefan Junker <mail@stefanjunker.de>
Fri, 27 May 2016 09:52:44 +0000 (11:52 +0200)
committerStefan Junker <mail@stefanjunker.de>
Fri, 27 May 2016 11:50:16 +0000 (13:50 +0200)
ns/ns.go
ns/ns_test.go

index a03ee1e..e29f712 100644 (file)
--- 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
index 5b0b587..44ed272 100644 (file)
@@ -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{}))
                })
        })
 })