// +build linux package util import ( "bufio" "bytes" "os" "os/exec" "path/filepath" "strings" "syscall" "github.com/SvenDowideit/cpuid" "github.com/docker/docker/pkg/mount" ) func mountProc() error { if _, err := os.Stat("/proc/self/mountinfo"); os.IsNotExist(err) { if _, err := os.Stat("/proc"); os.IsNotExist(err) { if err = os.Mkdir("/proc", 0755); err != nil { return err } } if err := syscall.Mount("none", "/proc", "proc", 0, ""); err != nil { return err } } return nil } func Mount(device, target, fsType, options string) error { if err := mountProc(); err != nil { return nil } bindMount := false for _, v := range strings.Split(options, ",") { if v == "bind" { bindMount = true break } } if bindMount { deviceInfo, err := os.Stat(device) if err != nil { return err } mode := deviceInfo.Mode() switch { case mode.IsDir(): if err := os.MkdirAll(target, 0755); err != nil { return err } case mode.IsRegular(): err := os.MkdirAll(filepath.Dir(target), 0755) if err != nil { return err } file, err := os.OpenFile(target, os.O_CREATE, mode&os.ModePerm) if err != nil { return err } if err := file.Close(); err != nil { return err } default: return os.ErrInvalid } } else { err := os.MkdirAll(target, 0755) if err != nil { return err } if fsType == "auto" || fsType == "" { inferredType, err := GetFsType(device) if err != nil { return err } fsType = inferredType } } return mount.Mount(device, target, fsType, options) } func Unmount(target string) error { return mount.Unmount(target) } func Blkid(label string) (deviceName, deviceType string, err error) { // Not all blkid's have `blkid -L label (see busybox/alpine) cmd := exec.Command("blkid") cmd.Stderr = os.Stderr out, err := cmd.Output() if err != nil { return } r := bytes.NewReader(out) s := bufio.NewScanner(r) for s.Scan() { line := s.Text() if !strings.Contains(line, `LABEL="`+label+`"`) { continue } d := strings.Split(line, ":") deviceName = d[0] s1 := strings.Split(line, `TYPE="`) s2 := strings.Split(s1[1], `"`) deviceType = s2[0] return } return } func BlkidType(deviceType string) (deviceNames []string, err error) { // Not all blkid's have `blkid -L label (see busybox/alpine) cmd := exec.Command("blkid") cmd.Stderr = os.Stderr out, err := cmd.Output() if err != nil { return nil, err } r := bytes.NewReader(out) s := bufio.NewScanner(r) for s.Scan() { line := s.Text() if !strings.Contains(line, `TYPE="`+deviceType+`"`) { continue } d := strings.Split(line, ":") deviceName := d[0] deviceNames = append(deviceNames, deviceName) } return deviceNames, nil } // GetHypervisor tries to detect if we're running in a VM, and returns a string for its type func GetHypervisor() string { return cpuid.CPU.HypervisorName }