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 {
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
_, 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{}))
})
})
})
})
- 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() {
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{}))
})
})
})