-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
750 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package types | ||
|
||
// MountInfo reveals information about a particular mounted filesystem. This | ||
// struct is populated from the content in the /proc/<pid>/mountinfo file. | ||
type MountInfo struct { | ||
|
||
// DevicePath is the path of the mounted path. | ||
DevicePath FileSystemDevicePath `json:"devicePath"` | ||
|
||
// MountPoint indicates the mount point relative to the process's root. | ||
MountPoint string `json:"mountPoint"` | ||
|
||
// FSType indicates the type of filesystem, such as EXT3. | ||
FSType string `json:"fsType"` | ||
|
||
// Opts represents mount-specific options. | ||
Opts MountOptions `json:"opts"` | ||
} | ||
|
||
// MarshalText marshals the MountInfo object to its textual representation. | ||
func (i *MountInfo) String() string { | ||
if s, err := i.MarshalText(); err == nil { | ||
return string(s) | ||
} | ||
return "" | ||
} | ||
|
||
// ParseMountInfo parses mount information. | ||
func ParseMountInfo(text string) *MountInfo { | ||
i := &MountInfo{} | ||
i.UnmarshalText([]byte(text)) | ||
return i | ||
} | ||
|
||
// UnmarshalText marshals the MountInfo from its textual representation. | ||
func (i *MountInfo) UnmarshalText(data []byte) error { | ||
|
||
m := mountInfoRX.FindSubmatch(data) | ||
if len(m) == 0 { | ||
return nil | ||
} | ||
|
||
i.DevicePath = FileSystemDevicePath(m[1]) | ||
i.MountPoint = string(m[2]) | ||
i.FSType = string(m[3]) | ||
i.Opts.UnmarshalText(m[4]) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package types | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"regexp" | ||
) | ||
|
||
/* | ||
$ mount | ||
/dev/disk1 on / (hfs, local, journaled) | ||
devfs on /dev (devfs, local, nobrowse) | ||
map -hosts on /net (autofs, nosuid, automounted, nobrowse) | ||
map auto_home on /home (autofs, automounted, nobrowse) | ||
/tmp/one on /private/tmp/bind-one (osxfusefs, nodev, nosuid, synchronous, mounted by akutz) | ||
bindfs@osxfuse1 on /private/tmp/bind-two (osxfusefs, nodev, nosuid, read-only, synchronous, mounted by akutz) | ||
/dev/disk2s1 on /Volumes/VirtualBox (hfs, local, nodev, nosuid, read-only, noowners, quarantine, mounted by akutz) | ||
*/ | ||
|
||
// MarshalText marshals the MountInfo object to its textual representation. | ||
func (i *MountInfo) MarshalText() ([]byte, error) { | ||
buf := &bytes.Buffer{} | ||
fmt.Fprintf(buf, "%s on %s (%s", i.DevicePath, i.MountPoint, i.FSType) | ||
if len(i.Opts) == 0 { | ||
fmt.Fprint(buf, ")") | ||
} else { | ||
fmt.Fprintf(buf, ", %s)", i.Opts) | ||
} | ||
return buf.Bytes(), nil | ||
} | ||
|
||
/* | ||
mountInfoRX is the regex used for matching the output of the Linux mount cmd | ||
$1 = devicePath | ||
$2 = mountPoint | ||
$3 = fileSystemType | ||
$4 = mountOpts | ||
*/ | ||
var mountInfoRX = regexp.MustCompile(`^(.+) on (.+) \((.+?)(?:, (.+))\)$`) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// +build darwin | ||
|
||
package types | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestMountInfoParse(t *testing.T) { | ||
expected := &MountInfo{ | ||
DevicePath: FileSystemDevicePath("/dev/disk1"), | ||
MountPoint: "/", | ||
Opts: MountOptions{MountOptLocal, MountOptJournaled}, | ||
FSType: "hfs", | ||
} | ||
actual := ParseMountInfo("/dev/disk1 on / (hfs, local, journaled)") | ||
assert.Equal(t, expected, actual) | ||
assert.Equal(t, "/dev/disk1 on / (hfs, local, journaled)", actual.String()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package types | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"regexp" | ||
) | ||
|
||
/* | ||
$ mount | ||
/dev/mapper/mea--vg-root on / type ext4 (rw,errors=remount-ro) | ||
proc on /proc type proc (rw,noexec,nosuid,nodev) | ||
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev) | ||
none on /sys/fs/cgroup type tmpfs (rw) | ||
none on /sys/fs/fuse/connections type fusectl (rw) | ||
none on /sys/kernel/debug type debugfs (rw) | ||
none on /sys/kernel/security type securityfs (rw) | ||
udev on /dev type devtmpfs (rw,mode=0755) | ||
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620) | ||
tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755) | ||
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880) | ||
none on /run/shm type tmpfs (rw,nosuid,nodev) | ||
none on /run/user type tmpfs (rw,noexec,nosuid,nodev,size=104857600,mode=0755) | ||
none on /sys/fs/pstore type pstore (rw) | ||
/dev/sda1 on /boot type ext2 (rw) | ||
systemd on /sys/fs/cgroup/systemd type cgroup (rw,noexec,nosuid,nodev,none,name=systemd) | ||
go on /media/sf_go type vboxsf (gid=999,rw) | ||
/tmp/one on /tmp/one-bind type none (rw,bind) | ||
*/ | ||
|
||
// MarshalText marshals the MountInfo object to its textual representation. | ||
func (i *MountInfo) MarshalText() ([]byte, error) { | ||
buf := &bytes.Buffer{} | ||
fmt.Fprintf(buf, "%s on %s type %s", i.DevicePath, i.MountPoint, i.FSType) | ||
if len(i.Opts) > 0 { | ||
fmt.Fprintf(buf, " (%s)", i.Opts) | ||
} | ||
return buf.Bytes(), nil | ||
} | ||
|
||
/* | ||
mountInfoRX is the regex used for matching the output of the Linux mount cmd | ||
$1 = devicePath | ||
$2 = mountPoint | ||
$3 = fileSystemType | ||
$4 = mountOpts | ||
*/ | ||
var mountInfoRX = regexp.MustCompile(`^(.+) on (.+) type (.+?)(?: \((.+)\))?$`) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// +build linux | ||
|
||
package types | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestMountInfoParse(t *testing.T) { | ||
expected := &MountInfo{ | ||
DevicePath: FileSystemDevicePath("proc"), | ||
MountPoint: "/proc", | ||
Opts: MountOptions{MountOptNoExec, MountOptNoSUID, MountOptNoDev}, | ||
FSType: "proc", | ||
} | ||
actual := ParseMountInfo("proc on /proc type proc (rw,noexec,nosuid,nodev)") | ||
assert.Equal(t, expected, actual) | ||
assert.Equal( | ||
t, "proc on /proc type proc (noexec,nosuid,nodev)", actual.String()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
package types | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"runtime" | ||
"strings" | ||
|
||
"github.com/akutz/goof" | ||
) | ||
|
||
// MountOption is a mount option. | ||
type MountOption int | ||
|
||
// MountOptions are a mount options string. | ||
type MountOptions []MountOption | ||
|
||
// String returns the string representation of the MountOption. | ||
func (o MountOption) String() string { | ||
if buf, err := o.MarshalText(); err == nil { | ||
return string(buf) | ||
} | ||
return "" | ||
} | ||
|
||
func (o MountOption) bytes() []byte { | ||
if v, ok := mountOptToStr[o]; ok { | ||
return []byte(v) | ||
} | ||
return nil | ||
} | ||
|
||
// ParseMountOption parses a mount option. | ||
func ParseMountOption(text string) MountOption { | ||
o := MountOptUnknown | ||
o.UnmarshalText([]byte(text)) | ||
return o | ||
} | ||
|
||
// MarshalText marshals the MountOption to its string representation. | ||
func (o MountOption) MarshalText() ([]byte, error) { | ||
if buf := o.bytes(); buf != nil { | ||
return buf, nil | ||
} | ||
return nil, goof.WithField("opt", int(o), "invalid mount option") | ||
} | ||
|
||
// UnmarshalText marshals the MountOption from its string representation. | ||
func (o *MountOption) UnmarshalText(data []byte) error { | ||
text := string(data) | ||
if v, ok := mountStrToOpt[strings.ToLower(text)]; ok { | ||
*o = v | ||
return nil | ||
} | ||
return goof.WithField("opt", text, "invalid mount option") | ||
} | ||
|
||
const ( | ||
commaByteVal byte = 44 | ||
spaceByteVal byte = 32 | ||
) | ||
|
||
var ( | ||
commaSepBuf = []byte{commaByteVal} | ||
commaSpaceSepBuf = []byte{commaByteVal, spaceByteVal} | ||
) | ||
|
||
// ParseMountOptions parses a mount options string. | ||
func ParseMountOptions(text string) MountOptions { | ||
var opts MountOptions | ||
if err := opts.UnmarshalText([]byte(text)); err == nil { | ||
return opts | ||
} | ||
return nil | ||
} | ||
|
||
// String returns the string representation of the MountOptions object. | ||
func (opts MountOptions) String() string { | ||
if s, err := opts.MarshalText(); err == nil { | ||
return string(s) | ||
} | ||
return "" | ||
} | ||
|
||
// MarshalText marshals the MountOptions to its string representation. | ||
func (opts MountOptions) MarshalText() ([]byte, error) { | ||
buf := &bytes.Buffer{} | ||
for x, o := range opts { | ||
if v, ok := mountOptToStr[o]; ok { | ||
buf.WriteString(v) | ||
if x < (len(opts) - 1) { | ||
switch runtime.GOOS { | ||
case "linux": | ||
buf.WriteString(",") | ||
case "darwin": | ||
buf.WriteString(", ") | ||
} | ||
} | ||
} | ||
} | ||
return buf.Bytes(), nil | ||
} | ||
|
||
// UnmarshalText marshals the MountOptions from its string representation. | ||
func (opts *MountOptions) UnmarshalText(text []byte) error { | ||
var sepBuf []byte | ||
switch runtime.GOOS { | ||
case "linux": | ||
sepBuf = commaSepBuf | ||
case "darwin": | ||
sepBuf = commaSpaceSepBuf | ||
} | ||
optBufs := bytes.Split(text, sepBuf) | ||
for _, optText := range optBufs { | ||
if o := ParseMountOption(string(optText)); o != MountOptUnknown { | ||
*opts = append(*opts, o) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
// MarshalJSON marshals the MountOptions to its JSON representation. | ||
func (opts MountOptions) MarshalJSON() ([]byte, error) { | ||
strOpts := make([]string, len(opts)) | ||
for i, o := range opts { | ||
strOpts[i] = o.String() | ||
} | ||
return json.Marshal(strOpts) | ||
} | ||
|
||
// UnmarshalJSON marshals the MountOptions from its JSON representation. | ||
func (opts *MountOptions) UnmarshalJSON(text []byte) error { | ||
strOpts := []string{} | ||
if err := json.Unmarshal(text, &strOpts); err != nil { | ||
return err | ||
} | ||
for _, optText := range strOpts { | ||
if o := ParseMountOption(optText); o != MountOptUnknown { | ||
*opts = append(*opts, o) | ||
} | ||
} | ||
return nil | ||
} |
Oops, something went wrong.