From cd300c81f40db2dee62facf4492207172cbef99f Mon Sep 17 00:00:00 2001 From: akutz Date: Wed, 1 Jun 2016 00:45:41 -0500 Subject: [PATCH] FileSystemDevicePath --- api/types/types_model.go | 13 ++++--- api/types/types_paths_fsdev.go | 38 +++++++++++++++++++ api/types/types_paths_fsdev_other.go | 15 ++++++++ api/types/types_paths_fsdev_test.go | 56 ++++++++++++++++++++++++++++ api/types/types_paths_fsdev_unix.go | 18 +++++++++ 5 files changed, 134 insertions(+), 6 deletions(-) create mode 100644 api/types/types_paths_fsdev.go create mode 100644 api/types/types_paths_fsdev_other.go create mode 100644 api/types/types_paths_fsdev_test.go create mode 100644 api/types/types_paths_fsdev_unix.go diff --git a/api/types/types_model.go b/api/types/types_model.go index 5a778659..d8041240 100644 --- a/api/types/types_model.go +++ b/api/types/types_model.go @@ -84,8 +84,8 @@ type MountInfo struct { // FSType indicates the type of filesystem, such as EXT3. FSType string `json:"fsType"` - // Source indicates filesystem specific information or "none". - Source string `json:"source"` + // DevicePath is the path of the mounted path. + DevicePath FileSystemDevicePath `json:"devicePath"` // VFSOpts represents per super block options. VFSOpts string `json:"vfsOpts"` @@ -105,7 +105,8 @@ type Snapshot struct { // The snapshot's ID. ID string `json:"id"` - // The time (epoch) at which the request to create the snapshot was submitted. + // The time (epoch) at which the request to create the snapshot was + // submitted. StartTime int64 `json:"startTime,omitempty"` // The status of the snapshot. @@ -173,9 +174,9 @@ func (v *Volume) MountPoint() string { // VolumeAttachment provides information about an object attached to a // storage volume. type VolumeAttachment struct { - // The name of the device on which the volume to which the object is - // attached is mounted. - DeviceName string `json:"deviceName"` + // DevicePath is the name of the device on which the volume to which the + // object is attached is mounted. + DevicePath FileSystemDevicePath `json:"devicePath"` // MountPoint is the mount point for the volume. This field is set when a // volume is retrieved via an integration driver. diff --git a/api/types/types_paths_fsdev.go b/api/types/types_paths_fsdev.go new file mode 100644 index 00000000..35b7f259 --- /dev/null +++ b/api/types/types_paths_fsdev.go @@ -0,0 +1,38 @@ +package types + +import "regexp" + +// FileSystemDevicePath is a path to a filesystem device. +type FileSystemDevicePath string + +// String returns the string representation of the file system device path. +func (p FileSystemDevicePath) String() string { + return string(p) +} + +var ( + nfsDevPathRX = regexp.MustCompile(`^([^:]+):(.+)$`) +) + +// IsNFS returns information about a file system device path as if the path is +// an NFS export. +func (p FileSystemDevicePath) IsNFS() ( + ok bool, + remoteHost string, + remoteDir string) { + + m := nfsDevPathRX.FindStringSubmatch(string(p)) + if len(m) == 0 { + return false, "", "" + } + + return true, m[1], m[2] +} + +// IsBind returns a flag indicating whether or not the path appears to be a +// bind mount path. This is decided based on whether or not the device path is +// in the /dev directory. +func (p FileSystemDevicePath) IsBind() bool { + nfs, _, _ := p.IsNFS() + return !nfs && p.isBind() +} diff --git a/api/types/types_paths_fsdev_other.go b/api/types/types_paths_fsdev_other.go new file mode 100644 index 00000000..12522336 --- /dev/null +++ b/api/types/types_paths_fsdev_other.go @@ -0,0 +1,15 @@ +// +build !linux,!darwin + +package types + +import ( + "fmt" + "runtime" +) + +// isBind returns a flag indicating whether or not the path appears to be a +// bind mount path. +func (p FileSystemDevicePath) isBind() bool { + panic(fmt.Errorf( + "FileSystemDevicePath.IsBind unsupported on %s", runtime.GOOS)) +} diff --git a/api/types/types_paths_fsdev_test.go b/api/types/types_paths_fsdev_test.go new file mode 100644 index 00000000..7ee1629d --- /dev/null +++ b/api/types/types_paths_fsdev_test.go @@ -0,0 +1,56 @@ +package types + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFileSystemDevicePathIsNFS(t *testing.T) { + + nfs, remoteHost, remoteDir := FileSystemDevicePath( + "/dev/xvda").IsNFS() + assert.False(t, nfs) + + nfs, remoteHost, remoteDir = FileSystemDevicePath( + "server1:/shares/mine").IsNFS() + assert.True(t, nfs) + assert.Equal(t, "server1", remoteHost) + assert.Equal(t, "/shares/mine", remoteDir) + + nfs, remoteHost, remoteDir = FileSystemDevicePath( + "/home/myhome/share").IsNFS() + assert.False(t, nfs) +} + +func TestFileSystemDevicePathIsBind(t *testing.T) { + + assert.False(t, FileSystemDevicePath("/dev/xvda").IsBind()) + assert.False(t, FileSystemDevicePath("server1:/shares/mine").IsBind()) + assert.True(t, FileSystemDevicePath("/home/myhome/share").IsBind()) +} + +func TestFileSystemDevicePathMarshalJSON(t *testing.T) { + + buf, err := json.Marshal(FileSystemDevicePath(`/dev/xvda`)) + if err != nil { + assert.NoError(t, err) + t.FailNow() + } + assert.EqualValues(t, []byte(`"/dev/xvda"`), buf) + + buf, err = json.Marshal(FileSystemDevicePath(`server1:/shares/mine`)) + if err != nil { + assert.NoError(t, err) + t.FailNow() + } + assert.EqualValues(t, []byte(`"server1:/shares/mine"`), buf) + + buf, err = json.Marshal(FileSystemDevicePath(`/home/myhome/share`)) + if err != nil { + assert.NoError(t, err) + t.FailNow() + } + assert.EqualValues(t, []byte(`"/home/myhome/share"`), buf) +} diff --git a/api/types/types_paths_fsdev_unix.go b/api/types/types_paths_fsdev_unix.go new file mode 100644 index 00000000..6d5cb81b --- /dev/null +++ b/api/types/types_paths_fsdev_unix.go @@ -0,0 +1,18 @@ +// +build linux darwin + +package types + +import ( + "regexp" +) + +var ( + bindDevPathRX = regexp.MustCompile(`^/dev/.+$`) +) + +// isBind returns a flag indicating whether or not the path appears to be a +// bind mount path. This is decided based on whether or not the device path is +// in the /dev directory. +func (p FileSystemDevicePath) isBind() bool { + return !bindDevPathRX.MatchString(string(p)) +}