system/mount.go
package system
import (
"fmt"
"math"
"strings"
"syscall"
"github.com/aelsabbahy/goss/util"
"github.com/docker/docker/pkg/mount"
)
type Mount interface {
MountPoint() string
Exists() (bool, error)
Opts() ([]string, error)
Source() (string, error)
Filesystem() (string, error)
Usage() (int, error)
}
type DefMount struct {
mountPoint string
loaded bool
exists bool
mountInfo *mount.Info
usage int
err error
}
func NewDefMount(mountPoint string, system *System, config util.Config) Mount {
return &DefMount{
mountPoint: mountPoint,
}
}
func (m *DefMount) setup() error {
if m.loaded {
return m.err
}
m.loaded = true
mountInfo, err := getMount(m.mountPoint)
if err != nil {
m.exists = false
m.err = err
return m.err
}
m.mountInfo = mountInfo
m.exists = true
usage, err := getUsage(m.mountPoint)
if err != nil {
m.err = err
return m.err
}
m.usage = usage
return nil
}
func (m *DefMount) ID() string {
return m.mountPoint
}
func (m *DefMount) MountPoint() string {
return m.mountPoint
}
func (m *DefMount) Exists() (bool, error) {
if err := m.setup(); err != nil {
return false, nil
}
return m.exists, nil
}
func (m *DefMount) Opts() ([]string, error) {
if err := m.setup(); err != nil {
return nil, err
}
return strings.Split(m.mountInfo.Opts, ","), nil
}
func (m *DefMount) Source() (string, error) {
if err := m.setup(); err != nil {
return "", err
}
return m.mountInfo.Source, nil
}
func (m *DefMount) Filesystem() (string, error) {
if err := m.setup(); err != nil {
return "", err
}
return m.mountInfo.Fstype, nil
}
func (m *DefMount) Usage() (int, error) {
if err := m.setup(); err != nil {
return -1, err
}
return m.usage, nil
}
func getMount(mountpoint string) (*mount.Info, error) {
entries, err := mount.GetMounts()
if err != nil {
return nil, err
}
// Search the table for the mountpoint
for _, e := range entries {
if e.Mountpoint == mountpoint {
return e, nil
}
}
return nil, fmt.Errorf("Mountpoint not found")
}
func getUsage(mountpoint string) (int, error) {
statfsOut := &syscall.Statfs_t{}
err := syscall.Statfs(mountpoint, statfsOut)
if err != nil {
return -1, err
}
percentageFree := float64(statfsOut.Bfree) / float64(statfsOut.Blocks)
usage := math.Round((1 - percentageFree) * 100)
return int(usage), nil
}