Refactor "host" package

pull/943/head
Sergey Vinogradov 5 years ago
parent 8a625ec054
commit 5209442b3c

@ -1,7 +1,11 @@
package host
import (
"context"
"encoding/json"
"os"
"runtime"
"time"
"github.com/shirou/gopsutil/internal/common"
)
@ -52,3 +56,99 @@ func (t TemperatureStat) String() string {
s, _ := json.Marshal(t)
return string(s)
}
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
var err error
ret := &InfoStat{
OS: runtime.GOOS,
}
ret.Hostname, err = os.Hostname()
if err != nil && err != common.ErrNotImplementedError {
return nil, err
}
ret.Platform, ret.PlatformFamily, ret.PlatformVersion, err = PlatformInformationWithContext(ctx)
if err != nil && err != common.ErrNotImplementedError {
return nil, err
}
ret.KernelVersion, err = KernelVersionWithContext(ctx)
if err != nil && err != common.ErrNotImplementedError {
return nil, err
}
ret.KernelArch, err = KernelArch()
if err != nil && err != common.ErrNotImplementedError {
return nil, err
}
ret.VirtualizationSystem, ret.VirtualizationRole, err = VirtualizationWithContext(ctx)
if err != nil && err != common.ErrNotImplementedError {
return nil, err
}
ret.BootTime, err = BootTimeWithContext(ctx)
if err != nil && err != common.ErrNotImplementedError {
return nil, err
}
ret.Uptime, err = UptimeWithContext(ctx)
if err != nil && err != common.ErrNotImplementedError {
return nil, err
}
ret.Procs, err = numProcs(ctx)
if err != nil && err != common.ErrNotImplementedError {
return nil, err
}
ret.HostID, err = HostIDWithContext(ctx)
if err != nil && err != common.ErrNotImplementedError {
return nil, err
}
return ret, nil
}
// BootTime returns the system boot time expressed in seconds since the epoch.
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func PlatformInformation() (string, string, string, error) {
return PlatformInformationWithContext(context.Background())
}
// HostID returns the unique host ID provided by the OS.
func HostID() (string, error) {
return HostIDWithContext(context.Background())
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func timeSince(ts uint64) uint64 {
return uint64(time.Now().Unix()) - ts
}

@ -5,7 +5,6 @@ package host
import (
"context"
"sync/atomic"
"time"
"golang.org/x/sys/unix"
)
@ -13,10 +12,6 @@ import (
// cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func BootTimeWithContext(ctx context.Context) (uint64, error) {
t := atomic.LoadUint64(&cachedBootTime)
if t != 0 {
@ -32,18 +27,10 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) {
return uint64(tv.Sec), nil
}
func uptime(boot uint64) uint64 {
return uint64(time.Now().Unix()) - boot
}
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func UptimeWithContext(ctx context.Context) (uint64, error) {
boot, err := BootTimeWithContext(ctx)
if err != nil {
return 0, err
}
return uptime(boot), nil
return timeSince(boot), nil
}

@ -9,7 +9,6 @@ import (
"io/ioutil"
"os"
"os/exec"
"runtime"
"strings"
"unsafe"
@ -21,65 +20,20 @@ import (
// from utmpx.h
const USER_PROCESS = 7
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
ret := &InfoStat{
OS: runtime.GOOS,
PlatformFamily: "darwin",
}
hostname, err := os.Hostname()
if err == nil {
ret.Hostname = hostname
}
kernelVersion, err := KernelVersionWithContext(ctx)
if err == nil {
ret.KernelVersion = kernelVersion
}
kernelArch, err := kernelArch()
if err == nil {
ret.KernelArch = kernelArch
}
platform, family, pver, err := PlatformInformation()
if err == nil {
ret.Platform = platform
ret.PlatformFamily = family
ret.PlatformVersion = pver
}
system, role, err := Virtualization()
if err == nil {
ret.VirtualizationSystem = system
ret.VirtualizationRole = role
}
boot, err := BootTime()
if err == nil {
ret.BootTime = boot
ret.Uptime = uptime(boot)
}
procs, err := process.Pids()
if err == nil {
ret.Procs = uint64(len(procs))
}
func HostIDWithContext(ctx context.Context) (string, error) {
uuid, err := unix.Sysctl("kern.uuid")
if err == nil && uuid != "" {
ret.HostID = strings.ToLower(uuid)
if err != nil {
return "", err
}
return ret, nil
return strings.ToLower(uuid), err
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
func numProcs(ctx context.Context) (uint64, error) {
procs, err := process.PidsWithContext(ctx)
if err != nil {
return 0, err
}
return uint64(len(procs)), nil
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
@ -126,10 +80,6 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) {
}
func PlatformInformation() (string, string, string, error) {
return PlatformInformationWithContext(context.Background())
}
func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
platform := ""
family := ""
@ -163,18 +113,10 @@ func PlatformInformationWithContext(ctx context.Context) (string, string, string
return platform, family, pver, nil
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) {
version, err := unix.Sysctl("kern.osrelease")
return strings.ToLower(version), err

@ -8,10 +8,6 @@ package host
import "C"
import "context"
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
temperatureKeys := []string{
C.AMBIENT_AIR_0,

@ -9,10 +9,6 @@ import (
"github.com/shirou/gopsutil/internal/common"
)
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return []TemperatureStat{}, common.ErrNotImplementedError
}

@ -8,58 +8,42 @@ import (
"github.com/shirou/gopsutil/internal/common"
)
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
return nil, common.ErrNotImplementedError
func HostIDWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
func numProcs(ctx context.Context) (uint64, error) {
return 0, common.ErrNotImplementedError
}
func BootTimeWithContext(ctx context.Context) (uint64, error) {
return 0, common.ErrNotImplementedError
}
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func UptimeWithContext(ctx context.Context) (uint64, error) {
return 0, common.ErrNotImplementedError
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
return []UserStat{}, common.ErrNotImplementedError
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func PlatformInformation() (string, string, string, error) {
return PlatformInformationWithContext(context.Background())
}
func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
return "", "", "", common.ErrNotImplementedError
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return []TemperatureStat{}, common.ErrNotImplementedError
}
func KernelArch() (string, error) {
return "", common.ErrNotImplementedError
}

@ -9,7 +9,6 @@ import (
"io/ioutil"
"math"
"os"
"runtime"
"strings"
"unsafe"
@ -24,61 +23,20 @@ const (
UTHostSize = 16
)
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
ret := &InfoStat{
OS: runtime.GOOS,
PlatformFamily: "freebsd",
}
hostname, err := os.Hostname()
if err == nil {
ret.Hostname = hostname
}
platform, family, version, err := PlatformInformation()
if err == nil {
ret.Platform = platform
ret.PlatformFamily = family
ret.PlatformVersion = version
ret.KernelVersion = version
}
kernelArch, err := kernelArch()
if err == nil {
ret.KernelArch = kernelArch
}
system, role, err := Virtualization()
if err == nil {
ret.VirtualizationSystem = system
ret.VirtualizationRole = role
}
boot, err := BootTime()
if err == nil {
ret.BootTime = boot
ret.Uptime = uptime(boot)
}
procs, err := process.Pids()
if err == nil {
ret.Procs = uint64(len(procs))
func HostIDWithContext(ctx context.Context) (string, error) {
uuid, err := unix.Sysctl("kern.hostuuid")
if err != nil {
return "", err
}
hostid, err := unix.Sysctl("kern.hostuuid")
if err == nil && hostid != "" {
ret.HostID = strings.ToLower(hostid)
return strings.ToLower(uuid), err
}
return ret, nil
func numProcs(ctx context.Context) (uint64, error) {
procs, err := process.PidsWithContext(ctx)
if err != nil {
return 0, err
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
return uint64(len(procs)), nil
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
@ -126,10 +84,6 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) {
}
func PlatformInformation() (string, string, string, error) {
return PlatformInformationWithContext(context.Background())
}
func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
platform, err := unix.Sysctl("kern.ostype")
if err != nil {
@ -144,10 +98,6 @@ func PlatformInformationWithContext(ctx context.Context) (string, string, string
return strings.ToLower(platform), "", strings.ToLower(version), nil
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
@ -191,19 +141,11 @@ func getUsersFromUtmp(utmpfile string) ([]UserStat, error) {
return ret, nil
}
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return []TemperatureStat{}, common.ErrNotImplementedError
}
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) {
_, _, version, err := PlatformInformation()
_, _, version, err := PlatformInformationWithContext(ctx)
return version, err
}

@ -12,10 +12,8 @@ import (
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strconv"
"strings"
"time"
"github.com/shirou/gopsutil/internal/common"
"golang.org/x/sys/unix"
@ -31,52 +29,7 @@ type LSB struct {
// from utmp.h
const USER_PROCESS = 7
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
ret := &InfoStat{
OS: runtime.GOOS,
}
hostname, err := os.Hostname()
if err == nil {
ret.Hostname = hostname
}
platform, family, version, err := PlatformInformation()
if err == nil {
ret.Platform = platform
ret.PlatformFamily = family
ret.PlatformVersion = version
}
kernelVersion, err := KernelVersion()
if err == nil {
ret.KernelVersion = kernelVersion
}
kernelArch, err := kernelArch()
if err == nil {
ret.KernelArch = kernelArch
}
system, role, err := Virtualization()
if err == nil {
ret.VirtualizationSystem = system
ret.VirtualizationRole = role
}
boot, err := BootTime()
if err == nil {
ret.BootTime = boot
ret.Uptime = uptime(boot)
}
if numProcs, err := common.NumProcs(); err == nil {
ret.Procs = numProcs
}
func HostIDWithContext(ctx context.Context) (string, error) {
sysProductUUID := common.HostSys("class/dmi/id/product_uuid")
machineID := common.HostEtc("machine-id")
procSysKernelRandomBootID := common.HostProc("sys/kernel/random/boot_id")
@ -86,8 +39,7 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) {
case common.PathExists(sysProductUUID):
lines, err := common.ReadLines(sysProductUUID)
if err == nil && len(lines) > 0 && lines[0] != "" {
ret.HostID = strings.ToLower(lines[0])
break
return strings.ToLower(lines[0]), nil
}
fallthrough
// Fallback on GNU Linux systems with systemd, readable by everyone
@ -95,48 +47,34 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) {
lines, err := common.ReadLines(machineID)
if err == nil && len(lines) > 0 && len(lines[0]) == 32 {
st := lines[0]
ret.HostID = fmt.Sprintf("%s-%s-%s-%s-%s", st[0:8], st[8:12], st[12:16], st[16:20], st[20:32])
break
return fmt.Sprintf("%s-%s-%s-%s-%s", st[0:8], st[8:12], st[12:16], st[16:20], st[20:32]), nil
}
fallthrough
// Not stable between reboot, but better than nothing
default:
lines, err := common.ReadLines(procSysKernelRandomBootID)
if err == nil && len(lines) > 0 && lines[0] != "" {
ret.HostID = strings.ToLower(lines[0])
return strings.ToLower(lines[0]), nil
}
}
return ret, nil
return "", nil
}
// BootTime returns the system boot time expressed in seconds since the epoch.
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
func numProcs(ctx context.Context) (uint64, error) {
return common.NumProcs()
}
func BootTimeWithContext(ctx context.Context) (uint64, error) {
return common.BootTimeWithContext(ctx)
}
func uptime(boot uint64) uint64 {
return uint64(time.Now().Unix()) - boot
}
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func UptimeWithContext(ctx context.Context) (uint64, error) {
boot, err := BootTime()
if err != nil {
return 0, err
}
return uptime(boot), nil
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
return timeSince(boot), nil
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
@ -236,12 +174,7 @@ func getLSB() (*LSB, error) {
return ret, nil
}
func PlatformInformation() (platform string, family string, version string, err error) {
return PlatformInformationWithContext(context.Background())
}
func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) {
lsb, err := getLSB()
if err != nil {
lsb = &LSB{}
@ -370,10 +303,6 @@ func PlatformInformationWithContext(ctx context.Context) (platform string, famil
}
func KernelVersion() (version string, err error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (version string, err error) {
var utsname unix.Utsname
err = unix.Uname(&utsname)
@ -432,18 +361,10 @@ func getSusePlatform(contents []string) string {
return "suse"
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return common.VirtualizationWithContext(ctx)
}
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
var temperatures []TemperatureStat
files, err := filepath.Glob(common.HostSys("/class/hwmon/hwmon*/temp*_*"))

@ -8,7 +8,6 @@ import (
"encoding/binary"
"io/ioutil"
"os"
"runtime"
"strings"
"unsafe"
@ -23,54 +22,16 @@ const (
UTHostSize = 16
)
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
func HostIDWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
ret := &InfoStat{
OS: runtime.GOOS,
PlatformFamily: "openbsd",
}
hostname, err := os.Hostname()
if err == nil {
ret.Hostname = hostname
}
kernelArch, err := kernelArch()
if err == nil {
ret.KernelArch = kernelArch
}
platform, family, version, err := PlatformInformation()
if err == nil {
ret.Platform = platform
ret.PlatformFamily = family
ret.PlatformVersion = version
}
system, role, err := Virtualization()
if err == nil {
ret.VirtualizationSystem = system
ret.VirtualizationRole = role
}
procs, err := process.Pids()
if err == nil {
ret.Procs = uint64(len(procs))
}
boot, err := BootTime()
if err == nil {
ret.BootTime = boot
ret.Uptime = uptime(boot)
}
return ret, nil
func numProcs(ctx context.Context) (uint64, error) {
procs, err := process.PidsWithContext(ctx)
if err != nil {
return 0, err
}
func PlatformInformation() (string, string, string, error) {
return PlatformInformationWithContext(context.Background())
return uint64(len(procs)), nil
}
func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
@ -90,18 +51,10 @@ func PlatformInformationWithContext(ctx context.Context) (string, string, string
return platform, family, version, nil
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
var ret []UserStat
utmpfile := "/var/run/utmp"
@ -141,19 +94,11 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) {
return ret, nil
}
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return []TemperatureStat{}, common.ErrNotImplementedError
}
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) {
_, _, version, err := PlatformInformation()
_, _, version, err := PlatformInformationWithContext(ctx)
return version, err
}

@ -8,7 +8,7 @@ import (
"golang.org/x/sys/unix"
)
func kernelArch() (string, error) {
func KernelArch() (string, error) {
var utsname unix.Utsname
err := unix.Uname(&utsname)
return string(utsname.Machine[:bytes.IndexByte(utsname.Machine[:], 0)]), err

@ -9,86 +9,19 @@ import (
"os"
"os/exec"
"regexp"
"runtime"
"strconv"
"strings"
"time"
"github.com/shirou/gopsutil/internal/common"
)
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
result := &InfoStat{
OS: runtime.GOOS,
}
hostname, err := os.Hostname()
if err != nil {
return nil, err
}
result.Hostname = hostname
// Parse versions from output of `uname(1)`
uname, err := exec.LookPath("uname")
if err != nil {
return nil, err
}
out, err := invoke.CommandWithContext(ctx, uname, "-srv")
if err != nil {
return nil, err
}
fields := strings.Fields(string(out))
if len(fields) >= 1 {
result.PlatformFamily = fields[0]
}
if len(fields) >= 2 {
result.KernelVersion = fields[1]
}
if len(fields) == 3 {
result.PlatformVersion = fields[2]
}
kernelArch, err := kernelArch()
if err == nil {
result.KernelArch = kernelArch
}
// Find distribution name from /etc/release
fh, err := os.Open("/etc/release")
func HostIDWithContext(ctx context.Context) (string, error) {
platform, err := parseReleaseFile()
if err != nil {
return nil, err
}
defer fh.Close()
sc := bufio.NewScanner(fh)
if sc.Scan() {
line := strings.TrimSpace(sc.Text())
switch {
case strings.HasPrefix(line, "SmartOS"):
result.Platform = "SmartOS"
case strings.HasPrefix(line, "OpenIndiana"):
result.Platform = "OpenIndiana"
case strings.HasPrefix(line, "OmniOS"):
result.Platform = "OmniOS"
case strings.HasPrefix(line, "Open Storage"):
result.Platform = "NexentaStor"
case strings.HasPrefix(line, "Solaris"):
result.Platform = "Solaris"
case strings.HasPrefix(line, "Oracle Solaris"):
result.Platform = "Solaris"
default:
result.Platform = strings.Fields(line)[0]
}
return "", err
}
switch result.Platform {
case "SmartOS":
if platform == "SmartOS" {
// If everything works, use the current zone ID as the HostID if present.
zonename, err := exec.LookPath("zonename")
if err == nil {
@ -102,21 +35,19 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) {
if line == "global" {
hostname, err := os.Hostname()
if err == nil {
result.HostID = hostname
return hostname, nil
}
} else {
result.HostID = strings.TrimSpace(line)
break
return strings.TrimSpace(line), nil
}
}
}
}
}
// If HostID is still empty, use hostid(1), which can lie to callers but at
// 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.
if result.HostID == "" {
hostID, err := exec.LookPath("hostid")
if err == nil {
out, err := invoke.CommandWithContext(ctx, hostID)
@ -124,37 +55,25 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) {
sc := bufio.NewScanner(bytes.NewReader(out))
for sc.Scan() {
line := sc.Text()
result.HostID = strings.TrimSpace(line)
break
}
return strings.TrimSpace(line), nil
}
}
}
// Find the boot time and calculate uptime relative to it
bootTime, err := BootTime()
if err != nil {
return nil, err
return "", nil
}
result.BootTime = bootTime
result.Uptime = uptimeSince(bootTime)
// 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 {
return nil, err
return 0, err
}
result.Procs = uint64(len(dirs))
return result, nil
return uint64(len(dirs)), nil
}
var kstatMatch = regexp.MustCompile(`([^\s]+)[\s]+([^\s]*)`)
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func BootTimeWithContext(ctx context.Context) (uint64, error) {
kstat, err := exec.LookPath("kstat")
if err != nil {
@ -174,80 +93,92 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) {
return strconv.ParseUint(kstats[0][2], 10, 64)
}
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func UptimeWithContext(ctx context.Context) (uint64, error) {
bootTime, err := BootTime()
if err != nil {
return 0, err
}
return uptimeSince(bootTime), nil
}
func uptimeSince(since uint64) uint64 {
return uint64(time.Now().Unix()) - since
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
return timeSince(bootTime), nil
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
return []UserStat{}, common.ErrNotImplementedError
}
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return []TemperatureStat{}, common.ErrNotImplementedError
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
// 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]
}
func KernelVersionWithContext(ctx context.Context) (string, error) {
// Parse versions from output of `uname(1)`
return platform, nil
}
// parseUnameOutput returns platformFamily, kernelVersion and platformVersion
func parseUnameOutput(ctx context.Context) (string, string, string, error) {
uname, err := exec.LookPath("uname")
if err != nil {
return "", err
return "", "", "", err
}
out, err := invoke.CommandWithContext(ctx, uname, "-srv")
if err != nil {
return "", err
return "", "", "", err
}
fields := strings.Fields(string(out))
if len(fields) >= 2 {
return fields[1], nil
if len(fields) < 3 {
return "", "", "", fmt.Errorf("malformed `uname` output")
}
return "", fmt.Errorf("could not get kernel version")
return fields[0], fields[1], fields[2], nil
}
func PlatformInformation() (platform string, family string, version string, err error) {
return PlatformInformationWithContext(context.Background())
func KernelVersionWithContext(ctx context.Context) (string, error) {
_, kernelVersion, _, err := parseUnameOutput(ctx)
return kernelVersion, err
}
func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) {
/* This is not finished yet at all. Please contribute! */
func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
platform, err := parseReleaseFile()
if err != nil {
return "", "", "", err
}
version, err = KernelVersion()
platformFamily, _, platformVersion, err := parseUnameOutput(ctx)
if err != nil {
return "", "", "", err
}
return "solaris", "solaris", version, nil
return platform, platformFamily, platformVersion, nil
}

@ -6,8 +6,6 @@ import (
"context"
"fmt"
"math"
"os"
"runtime"
"strings"
"sync/atomic"
"syscall"
@ -16,7 +14,7 @@ import (
"github.com/StackExchange/wmi"
"github.com/shirou/gopsutil/internal/common"
process "github.com/shirou/gopsutil/process"
"github.com/shirou/gopsutil/process"
"golang.org/x/sys/windows"
)
@ -64,66 +62,7 @@ type msAcpi_ThermalZoneTemperature struct {
InstanceName string
}
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
ret := &InfoStat{
OS: runtime.GOOS,
}
{
hostname, err := os.Hostname()
if err == nil {
ret.Hostname = hostname
}
}
{
platform, family, version, err := PlatformInformationWithContext(ctx)
if err == nil {
ret.Platform = platform
ret.PlatformFamily = family
ret.PlatformVersion = version
} else {
return ret, err
}
}
{
kernelArch, err := kernelArch()
if err == nil {
ret.KernelArch = kernelArch
}
}
{
boot, err := BootTimeWithContext(ctx)
if err == nil {
ret.BootTime = boot
ret.Uptime, _ = Uptime()
}
}
{
hostID, err := getMachineGuid()
if err == nil {
ret.HostID = hostID
}
}
{
procs, err := process.PidsWithContext(ctx)
if err == nil {
ret.Procs = uint64(len(procs))
}
}
return ret, nil
}
func getMachineGuid() (string, error) {
func HostIDWithContext(ctx context.Context) (string, error) {
// there has been reports of issues on 32bit using golang.org/x/sys/windows/registry, see https://github.com/shirou/gopsutil/pull/312#issuecomment-277422612
// for rationale of using windows.RegOpenKeyEx/RegQueryValueEx instead of registry.OpenKey/GetStringValue
var h windows.Handle
@ -153,8 +92,12 @@ func getMachineGuid() (string, error) {
return strings.ToLower(hostID), nil
}
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
func numProcs(ctx context.Context) (uint64, error) {
procs, err := process.PidsWithContext(ctx)
if err != nil {
return 0, err
}
return uint64(len(procs)), nil
}
func UptimeWithContext(ctx context.Context) (uint64, error) {
@ -170,17 +113,9 @@ func UptimeWithContext(ctx context.Context) (uint64, error) {
return uint64((time.Duration(r1) * time.Millisecond).Seconds()), nil
}
func bootTimeFromUptime(up uint64) uint64 {
return uint64(time.Now().Unix()) - up
}
// cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func BootTimeWithContext(ctx context.Context) (uint64, error) {
t := atomic.LoadUint64(&cachedBootTime)
if t != 0 {
@ -190,15 +125,11 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) {
if err != nil {
return 0, err
}
t = bootTimeFromUptime(up)
t = timeSince(up)
atomic.StoreUint64(&cachedBootTime, t)
return t, nil
}
func PlatformInformation() (platform string, family string, version string, err error) {
return PlatformInformationWithContext(context.Background())
}
func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) {
// GetVersionEx lies on Windows 8.1 and returns as Windows 8 if we don't declare compatibility in manifest
// RtlGetVersion bypasses this lying layer and returns the true Windows version
@ -212,7 +143,7 @@ func PlatformInformationWithContext(ctx context.Context) (platform string, famil
}
// Platform
var h windows.Handle // like getMachineGuid(), we query the registry using the raw windows.RegOpenKeyEx/RegQueryValueEx
var h windows.Handle // like HostIDWithContext(), we query the registry using the raw windows.RegOpenKeyEx/RegQueryValueEx
err = windows.RegOpenKeyEx(windows.HKEY_LOCAL_MACHINE, windows.StringToUTF16Ptr(`SOFTWARE\Microsoft\Windows NT\CurrentVersion`), 0, windows.KEY_READ|windows.KEY_WOW64_64KEY, &h)
if err != nil {
return
@ -258,20 +189,12 @@ func PlatformInformationWithContext(ctx context.Context) (platform string, famil
return platform, family, version, nil
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
var ret []UserStat
return ret, common.ErrNotImplementedError
}
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
var ret []TemperatureStat
var dst []msAcpi_ThermalZoneTemperature
@ -299,24 +222,16 @@ func kelvinToCelsius(temp uint32, n int) float64 {
return math.Trunc((t+0.5/n10)*n10) / n10
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) {
_, _, version, err := PlatformInformation()
_, _, version, err := PlatformInformationWithContext(ctx)
return version, err
}
func kernelArch() (string, error) {
func KernelArch() (string, error) {
var systemInfo systemInfo
procGetNativeSystemInfo.Call(uintptr(unsafe.Pointer(&systemInfo)))

Loading…
Cancel
Save