func getLSB() (*LSB, error) { ret := &LSB{} if common.PathExists(common.HostEtc("lsb-release")) { contents, err := common.ReadLines(common.HostEtc("lsb-release")) if err != nil { return ret, err // return empty } for _, line := range contents { field := strings.Split(line, "=") if len(field) < 2 { continue } switch field[0] { case "DISTRIB_ID": ret.ID = field[1] case "DISTRIB_RELEASE": ret.Release = field[1] case "DISTRIB_CODENAME": ret.Codename = field[1] case "DISTRIB_DESCRIPTION": ret.Description = field[1] } } } else if common.PathExists("/usr/bin/lsb_release") { lsb_release, err := exec.LookPath("/usr/bin/lsb_release") if err != nil { return ret, err } out, err := exec.Command(lsb_release).Output() if err != nil { return ret, err } for _, line := range strings.Split(string(out), "\n") { field := strings.Split(line, ":") if len(field) < 2 { continue } switch field[0] { case "Distributor ID": ret.ID = field[1] case "Release": ret.Release = field[1] case "Codename": ret.Codename = field[1] case "Description": ret.Description = field[1] } } } return ret, nil }
// Partitions returns disk partitions. If all is false, returns // physical devices only (e.g. hard disks, cd-rom drives, USB keys) // and ignore all others (e.g. memory partitions such as /dev/shm) // // should use setmntent(3) but this implement use /etc/mtab file func Partitions(all bool) ([]PartitionStat, error) { filename := common.HostEtc("mtab") lines, err := common.ReadLines(filename) if err != nil { return nil, err } fs, err := getFileSystems() if err != nil { return nil, err } ret := make([]PartitionStat, 0, len(lines)) for _, line := range lines { fields := strings.Fields(line) d := PartitionStat{ Device: fields[0], Mountpoint: fields[1], Fstype: fields[2], Opts: fields[3], } if all == false { if d.Device == "none" || !common.StringsHas(fs, d.Fstype) { continue } } ret = append(ret, d) } return ret, nil }
func getOSRelease() (platform string, version string, err error) { contents, err := common.ReadLines(common.HostEtc("os-release")) if err != nil { return "", "", nil // return empty } for _, line := range contents { field := strings.Split(line, "=") if len(field) < 2 { continue } switch field[0] { case "ID": // use ID for lowercase platform = field[1] case "VERSION": version = field[1] } } return platform, version, nil }
// Get disk partitions. // should use setmntent(3) but this implement use /etc/mtab file func Partitions(all bool) ([]PartitionStat, error) { filename := common.HostEtc("mtab") lines, err := common.ReadLines(filename) if err != nil { return nil, err } ret := make([]PartitionStat, 0, len(lines)) for _, line := range lines { fields := strings.Fields(line) d := PartitionStat{ Device: fields[0], Mountpoint: fields[1], Fstype: fields[2], Opts: fields[3], } ret = append(ret, d) } return ret, nil }
func PlatformInformation() (platform string, family string, version string, err error) { lsb, err := getLSB() if err != nil { lsb = &LSB{} } if common.PathExists(common.HostEtc("oracle-release")) { platform = "oracle" contents, err := common.ReadLines(common.HostEtc("oracle-release")) if err == nil { version = getRedhatishVersion(contents) } } else if common.PathExists(common.HostEtc("enterprise-release")) { platform = "oracle" contents, err := common.ReadLines(common.HostEtc("enterprise-release")) if err == nil { version = getRedhatishVersion(contents) } } else if common.PathExists(common.HostEtc("debian_version")) { if lsb.ID == "Ubuntu" { platform = "ubuntu" version = lsb.Release } else if lsb.ID == "LinuxMint" { platform = "linuxmint" version = lsb.Release } else { if common.PathExists("/usr/bin/raspi-config") { platform = "raspbian" } else { platform = "debian" } contents, err := common.ReadLines(common.HostEtc("debian_version")) if err == nil { version = contents[0] } } } else if common.PathExists(common.HostEtc("redhat-release")) { contents, err := common.ReadLines(common.HostEtc("redhat-release")) if err == nil { version = getRedhatishVersion(contents) platform = getRedhatishPlatform(contents) } } else if common.PathExists(common.HostEtc("system-release")) { contents, err := common.ReadLines(common.HostEtc("system-release")) if err == nil { version = getRedhatishVersion(contents) platform = getRedhatishPlatform(contents) } } else if common.PathExists(common.HostEtc("gentoo-release")) { platform = "gentoo" contents, err := common.ReadLines(common.HostEtc("gentoo-release")) if err == nil { version = getRedhatishVersion(contents) } } else if common.PathExists(common.HostEtc("SuSE-release")) { contents, err := common.ReadLines(common.HostEtc("SuSE-release")) if err == nil { version = getSuseVersion(contents) platform = getSusePlatform(contents) } // TODO: slackware detecion } else if common.PathExists(common.HostEtc("arch-release")) { platform = "arch" version = lsb.Release } else if lsb.ID == "RedHat" { platform = "redhat" version = lsb.Release } else if lsb.ID == "Amazon" { platform = "amazon" version = lsb.Release } else if lsb.ID == "ScientificSL" { platform = "scientific" version = lsb.Release } else if lsb.ID == "XenServer" { platform = "xenserver" version = lsb.Release } else if lsb.ID != "" { platform = strings.ToLower(lsb.ID) version = lsb.Release } switch platform { case "debian", "ubuntu", "linuxmint", "raspbian": family = "debian" case "fedora": family = "fedora" case "oracle", "centos", "redhat", "scientific", "enterpriseenterprise", "amazon", "xenserver", "cloudlinux", "ibm_powerkvm": family = "rhel" case "suse", "opensuse": family = "suse" case "gentoo": family = "gentoo" case "slackware": family = "slackware" case "arch": family = "arch" case "exherbo": family = "exherbo" } return platform, family, version, nil }
func Virtualization() (string, string, error) { var system string var role string filename := common.HostProc("xen") if common.PathExists(filename) { system = "xen" role = "guest" // assume guest if common.PathExists(filename + "/capabilities") { contents, err := common.ReadLines(filename + "/capabilities") if err == nil { if common.StringsContains(contents, "control_d") { role = "host" } } } } filename = common.HostProc("modules") if common.PathExists(filename) { contents, err := common.ReadLines(filename) if err == nil { if common.StringsContains(contents, "kvm") { system = "kvm" role = "host" } else if common.StringsContains(contents, "vboxdrv") { system = "vbox" role = "host" } else if common.StringsContains(contents, "vboxguest") { system = "vbox" role = "guest" } } } filename = common.HostProc("cpuinfo") if common.PathExists(filename) { contents, err := common.ReadLines(filename) if err == nil { if common.StringsContains(contents, "QEMU Virtual CPU") || common.StringsContains(contents, "Common KVM processor") || common.StringsContains(contents, "Common 32-bit KVM processor") { system = "kvm" role = "guest" } } } filename = common.HostProc() if common.PathExists(filename + "/bc/0") { system = "openvz" role = "host" } else if common.PathExists(filename + "/vz") { system = "openvz" role = "guest" } // not use dmidecode because it requires root if common.PathExists(filename + "/self/status") { contents, err := common.ReadLines(filename + "/self/status") if err == nil { if common.StringsContains(contents, "s_context:") || common.StringsContains(contents, "VxID:") { system = "linux-vserver" } // TODO: guest or host } } if common.PathExists(filename + "/self/cgroup") { contents, err := common.ReadLines(filename + "/self/cgroup") if err == nil { if common.StringsContains(contents, "lxc") { system = "lxc" role = "guest" } else if common.StringsContains(contents, "docker") { system = "docker" role = "guest" } else if common.StringsContains(contents, "machine-rkt") { system = "rkt" role = "guest" } else if common.PathExists("/usr/bin/lxc-version") { system = "lxc" role = "host" } } } if common.PathExists(common.HostEtc("os-release")) { p, _, err := getOSRelease() if err == nil && p == "coreos" { system = "rkt" // Is it true? role = "host" } } return system, role, nil }