1
0
mirror of https://github.com/shirou/gopsutil.git synced 2025-04-26 13:48:59 +08:00
shirou_gopsutil/host/host_solaris.go

185 lines
4.3 KiB
Go
Raw Normal View History

package host
import (
"bufio"
"bytes"
2017-12-31 15:25:49 +09:00
"context"
"fmt"
"io/ioutil"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
"github.com/shirou/gopsutil/v3/internal/common"
)
2020-09-11 14:51:20 +03:00
func HostIDWithContext(ctx context.Context) (string, error) {
platform, err := parseReleaseFile()
if err != nil {
2020-09-11 14:51:20 +03:00
return "", err
}
2020-09-11 14:51:20 +03:00
if platform == "SmartOS" {
// If everything works, use the current zone ID as the HostID if present.
zonename, err := exec.LookPath("zonename")
if err == nil {
2018-03-31 21:35:53 +09:00
out, err := invoke.CommandWithContext(ctx, zonename)
if err == nil {
sc := bufio.NewScanner(bytes.NewReader(out))
for sc.Scan() {
line := sc.Text()
// If we're in the global zone, rely on the hostname.
if line == "global" {
hostname, err := os.Hostname()
if err == nil {
2020-09-11 14:51:20 +03:00
return hostname, nil
}
} else {
2020-09-11 14:51:20 +03:00
return strings.TrimSpace(line), nil
}
}
}
}
}
2020-09-11 14:51:20 +03:00
// If HostID is still unknown, use hostid(1), which can lie to callers but at
// this point there are no hardware facilities available. This behavior
// matches that of other supported OSes.
2020-09-11 14:51:20 +03:00
hostID, err := exec.LookPath("hostid")
if err == nil {
out, err := invoke.CommandWithContext(ctx, hostID)
if err == nil {
2020-09-11 14:51:20 +03:00
sc := bufio.NewScanner(bytes.NewReader(out))
for sc.Scan() {
line := sc.Text()
return strings.TrimSpace(line), nil
}
}
}
2020-09-11 14:51:20 +03:00
return "", nil
}
2020-09-11 14:51:20 +03:00
// Count number of processes based on the number of entries in /proc
func numProcs(ctx context.Context) (uint64, error) {
dirs, err := ioutil.ReadDir("/proc")
if err != nil {
2020-09-11 14:51:20 +03:00
return 0, err
}
2020-09-11 14:51:20 +03:00
return uint64(len(dirs)), nil
}
var kstatMatch = regexp.MustCompile(`([^\s]+)[\s]+([^\s]*)`)
2017-12-31 15:25:49 +09:00
func BootTimeWithContext(ctx context.Context) (uint64, error) {
kstat, err := exec.LookPath("kstat")
if err != nil {
return 0, err
}
2018-03-31 21:35:53 +09:00
out, err := invoke.CommandWithContext(ctx, kstat, "-p", "unix:0:system_misc:boot_time")
if err != nil {
return 0, err
}
kstats := kstatMatch.FindAllStringSubmatch(string(out), -1)
if len(kstats) != 1 {
2017-03-15 22:43:20 +09:00
return 0, fmt.Errorf("expected 1 kstat, found %d", len(kstats))
}
return strconv.ParseUint(kstats[0][2], 10, 64)
}
2017-12-31 15:25:49 +09:00
func UptimeWithContext(ctx context.Context) (uint64, error) {
bootTime, err := BootTime()
if err != nil {
return 0, err
}
2020-09-11 14:51:20 +03:00
return timeSince(bootTime), nil
2017-12-31 15:25:49 +09:00
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
return []UserStat{}, common.ErrNotImplementedError
}
2017-03-19 02:05:46 +01:00
2017-12-31 15:25:49 +09:00
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
2017-04-10 22:24:36 +09:00
return []TemperatureStat{}, common.ErrNotImplementedError
2017-03-19 02:05:46 +01:00
}
2017-08-03 11:08:35 +09:00
2017-12-31 15:25:49 +09:00
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
2017-08-03 11:08:35 +09:00
return "", "", common.ErrNotImplementedError
}
2020-09-11 14:51:20 +03:00
// Find distribution name from /etc/release
func parseReleaseFile() (string, error) {
b, err := ioutil.ReadFile("/etc/release")
if err != nil {
return "", err
}
s := string(b)
s = strings.TrimSpace(s)
var platform string
switch {
case strings.HasPrefix(s, "SmartOS"):
platform = "SmartOS"
case strings.HasPrefix(s, "OpenIndiana"):
platform = "OpenIndiana"
case strings.HasPrefix(s, "OmniOS"):
platform = "OmniOS"
case strings.HasPrefix(s, "Open Storage"):
platform = "NexentaStor"
case strings.HasPrefix(s, "Solaris"):
platform = "Solaris"
case strings.HasPrefix(s, "Oracle Solaris"):
platform = "Solaris"
default:
platform = strings.Fields(s)[0]
}
return platform, nil
2017-12-31 15:25:49 +09:00
}
2020-09-11 14:51:20 +03:00
// parseUnameOutput returns platformFamily, kernelVersion and platformVersion
func parseUnameOutput(ctx context.Context) (string, string, string, error) {
uname, err := exec.LookPath("uname")
2017-08-03 11:08:35 +09:00
if err != nil {
2020-09-11 14:51:20 +03:00
return "", "", "", err
2017-08-03 11:08:35 +09:00
}
2018-03-31 21:35:53 +09:00
out, err := invoke.CommandWithContext(ctx, uname, "-srv")
2017-08-03 11:08:35 +09:00
if err != nil {
2020-09-11 14:51:20 +03:00
return "", "", "", err
2017-08-03 11:08:35 +09:00
}
fields := strings.Fields(string(out))
2020-09-11 14:51:20 +03:00
if len(fields) < 3 {
return "", "", "", fmt.Errorf("malformed `uname` output")
2017-08-03 11:08:35 +09:00
}
2020-09-11 14:51:20 +03:00
return fields[0], fields[1], fields[2], nil
2017-08-03 11:08:35 +09:00
}
2020-09-11 14:51:20 +03:00
func KernelVersionWithContext(ctx context.Context) (string, error) {
_, kernelVersion, _, err := parseUnameOutput(ctx)
return kernelVersion, err
}
2020-09-11 14:51:20 +03:00
func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
platform, err := parseReleaseFile()
if err != nil {
return "", "", "", err
}
2020-09-11 14:51:20 +03:00
platformFamily, _, platformVersion, err := parseUnameOutput(ctx)
if err != nil {
return "", "", "", err
}
2020-09-11 14:51:20 +03:00
return platform, platformFamily, platformVersion, nil
}