func getLSB() (*LSB, error) { ret := &LSB{} if common.PathExists("/etc/lsb-release") { contents, err := common.ReadLines("/etc/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") { out, err := exec.Command("/usr/bin/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 }
func CPUTimes(percpu bool) ([]CPUTimesStat, error) { var ret []CPUTimesStat if !common.PathExists(HELPER_PATH) { return nil, fmt.Errorf("could not get cpu time") } out, err := exec.Command(HELPER_PATH).Output() if err != nil { return ret, err } for _, line := range strings.Split(string(out), "\n") { f := strings.Split(string(line), ",") if len(f) != 5 { continue } cpu, err := strconv.ParseFloat(f[0], 64) if err != nil { return ret, err } // cpu:99 means total, so just ignore if percpu if (percpu && cpu == 99) || (!percpu && cpu != 99) { continue } user, err := strconv.ParseFloat(f[1], 64) if err != nil { return ret, err } sys, err := strconv.ParseFloat(f[2], 64) if err != nil { return ret, err } idle, err := strconv.ParseFloat(f[3], 64) if err != nil { return ret, err } nice, err := strconv.ParseFloat(f[4], 64) if err != nil { return ret, err } c := CPUTimesStat{ User: float64(user / ClocksPerSec), Nice: float64(nice / ClocksPerSec), System: float64(sys / ClocksPerSec), Idle: float64(idle / ClocksPerSec), } if !percpu { c.CPU = "cpu-total" } else { c.CPU = fmt.Sprintf("cpu%d", uint16(cpu)) } ret = append(ret, c) } return ret, nil }
func Users() ([]UserStat, error) { utmpfile := "/var/run/utx.active" if !common.PathExists(utmpfile) { utmpfile = "/var/run/utmp" // before 9.0 return getUsersFromUtmp(utmpfile) } var ret []UserStat file, err := os.Open(utmpfile) if err != nil { return ret, err } buf, err := ioutil.ReadAll(file) if err != nil { return ret, err } u := Utmpx{} entrySize := int(unsafe.Sizeof(u)) - 3 entrySize = 197 // TODO: why should 197 count := len(buf) / entrySize for i := 0; i < count; i++ { b := buf[i*entrySize : i*entrySize+entrySize] var u Utmpx br := bytes.NewReader(b) err := binary.Read(br, binary.LittleEndian, &u) if err != nil || u.Type != 4 { continue } sec := (binary.LittleEndian.Uint32(u.Tv.Sec[:])) / 2 // TODO: user := UserStat{ User: common.IntToString(u.User[:]), Terminal: common.IntToString(u.Line[:]), Host: common.IntToString(u.Host[:]), Started: int(sec), } ret = append(ret, user) } return ret, nil }
func init() { out, err := exec.Command("/usr/bin/getconf", "CLK_TCK").Output() // ignore errors if err == nil { i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) if err == nil { ClocksPerSec = float64(i) } } // adhoc compile on the host. Errors will be ignored. // gcc is required to compile. if !common.PathExists(HELPER_PATH) && os.Getenv(HELPER_ENABLE_ENV) == "yes" { cmd := exec.Command("gcc", "-o", HELPER_PATH, "-x", "c", "-") stdin, err := cmd.StdinPipe() if err != nil { return } io.WriteString(stdin, cpu_helper_src) stdin.Close() cmd.Output() } }
func GetVirtualization() (string, string, error) { var system string var role string filename := common.GetEnv("HOST_PROC", "/proc") + "/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.StringsHas(contents, "control_d") { role = "host" } } } } filename = common.GetEnv("HOST_PROC", "/proc") + "/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.GetEnv("HOST_PROC", "/proc") + "/cpuinfo" if common.PathExists(filename) { contents, err := common.ReadLines(filename) if err == nil { if common.StringsHas(contents, "QEMU Virtual CPU") || common.StringsHas(contents, "Common KVM processor") || common.StringsHas(contents, "Common 32-bit KVM processor") { system = "kvm" role = "guest" } } } filename = common.GetEnv("HOST_PROC", "/proc") 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.StringsHas(contents, "s_context:") || common.StringsHas(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.StringsHas(contents, "lxc") || common.StringsHas(contents, "docker") { system = "lxc" role = "guest" } else if common.PathExists("/usr/bin/lxc-version") { // TODO: which system = "lxc" role = "host" } } } return system, role, nil }
func GetPlatformInformation() (platform string, family string, version string, err error) { lsb, err := getLSB() if err != nil { lsb = &LSB{} } if common.PathExists("/etc/oracle-release") { platform = "oracle" contents, err := common.ReadLines("/etc/oracle-release") if err == nil { version = getRedhatishVersion(contents) } } else if common.PathExists("/etc/enterprise-release") { platform = "oracle" contents, err := common.ReadLines("/etc/enterprise-release") if err == nil { version = getRedhatishVersion(contents) } } else if common.PathExists("/etc/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("/etc/debian_version") if err == nil { version = contents[0] } } } else if common.PathExists("/etc/redhat-release") { contents, err := common.ReadLines("/etc/redhat-release") if err == nil { version = getRedhatishVersion(contents) platform = getRedhatishPlatform(contents) } } else if common.PathExists("/etc/system-release") { contents, err := common.ReadLines("/etc/system-release") if err == nil { version = getRedhatishVersion(contents) platform = getRedhatishPlatform(contents) } } else if common.PathExists("/etc/gentoo-release") { platform = "gentoo" contents, err := common.ReadLines("/etc/gentoo-release") if err == nil { version = getRedhatishVersion(contents) } } else if common.PathExists("/etc/SuSE-release") { contents, err := common.ReadLines("/etc/SuSE-release") if err == nil { version = getSuseVersion(contents) platform = getSusePlatform(contents) } // TODO: slackware detecion } else if common.PathExists("/etc/arch-release") { platform = "arch" // TODO: exherbo detection } 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 }