Refactor "host" package

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

@ -1,7 +1,11 @@
package host package host
import ( import (
"context"
"encoding/json" "encoding/json"
"os"
"runtime"
"time"
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
) )
@ -52,3 +56,99 @@ func (t TemperatureStat) String() string {
s, _ := json.Marshal(t) s, _ := json.Marshal(t)
return string(s) 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 ( import (
"context" "context"
"sync/atomic" "sync/atomic"
"time"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
@ -13,10 +12,6 @@ import (
// cachedBootTime must be accessed via atomic.Load/StoreUint64 // cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64 var cachedBootTime uint64
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func BootTimeWithContext(ctx context.Context) (uint64, error) { func BootTimeWithContext(ctx context.Context) (uint64, error) {
t := atomic.LoadUint64(&cachedBootTime) t := atomic.LoadUint64(&cachedBootTime)
if t != 0 { if t != 0 {
@ -32,18 +27,10 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) {
return uint64(tv.Sec), nil 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) { func UptimeWithContext(ctx context.Context) (uint64, error) {
boot, err := BootTimeWithContext(ctx) boot, err := BootTimeWithContext(ctx)
if err != nil { if err != nil {
return 0, err return 0, err
} }
return uptime(boot), nil return timeSince(boot), nil
} }

@ -9,7 +9,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"os/exec" "os/exec"
"runtime"
"strings" "strings"
"unsafe" "unsafe"
@ -21,65 +20,20 @@ import (
// from utmpx.h // from utmpx.h
const USER_PROCESS = 7 const USER_PROCESS = 7
func Info() (*InfoStat, error) { func HostIDWithContext(ctx context.Context) (string, 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))
}
uuid, err := unix.Sysctl("kern.uuid") uuid, err := unix.Sysctl("kern.uuid")
if err == nil && uuid != "" { if err != nil {
ret.HostID = strings.ToLower(uuid) return "", err
} }
return strings.ToLower(uuid), err
return ret, nil
} }
func Users() ([]UserStat, error) { func numProcs(ctx context.Context) (uint64, error) {
return UsersWithContext(context.Background()) procs, err := process.PidsWithContext(ctx)
if err != nil {
return 0, err
}
return uint64(len(procs)), nil
} }
func UsersWithContext(ctx context.Context) ([]UserStat, error) { 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) { func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
platform := "" platform := ""
family := "" family := ""
@ -163,18 +113,10 @@ func PlatformInformationWithContext(ctx context.Context) (string, string, string
return platform, family, pver, nil return platform, family, pver, nil
} }
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) { func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError return "", "", common.ErrNotImplementedError
} }
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) { func KernelVersionWithContext(ctx context.Context) (string, error) {
version, err := unix.Sysctl("kern.osrelease") version, err := unix.Sysctl("kern.osrelease")
return strings.ToLower(version), err return strings.ToLower(version), err

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

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

@ -8,58 +8,42 @@ import (
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
) )
func Info() (*InfoStat, error) { func HostIDWithContext(ctx context.Context) (string, error) {
return InfoWithContext(context.Background()) return "", common.ErrNotImplementedError
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
return nil, common.ErrNotImplementedError
} }
func BootTime() (uint64, error) { func numProcs(ctx context.Context) (uint64, error) {
return BootTimeWithContext(context.Background()) return 0, common.ErrNotImplementedError
} }
func BootTimeWithContext(ctx context.Context) (uint64, error) { func BootTimeWithContext(ctx context.Context) (uint64, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func UptimeWithContext(ctx context.Context) (uint64, error) { func UptimeWithContext(ctx context.Context) (uint64, error) {
return 0, common.ErrNotImplementedError return 0, common.ErrNotImplementedError
} }
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) { func UsersWithContext(ctx context.Context) ([]UserStat, error) {
return []UserStat{}, common.ErrNotImplementedError return []UserStat{}, common.ErrNotImplementedError
} }
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) { func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError return "", "", common.ErrNotImplementedError
} }
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) { func KernelVersionWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError return "", common.ErrNotImplementedError
} }
func PlatformInformation() (string, string, string, error) {
return PlatformInformationWithContext(context.Background())
}
func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) { func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
return "", "", "", common.ErrNotImplementedError 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" "io/ioutil"
"math" "math"
"os" "os"
"runtime"
"strings" "strings"
"unsafe" "unsafe"
@ -24,61 +23,20 @@ const (
UTHostSize = 16 UTHostSize = 16
) )
func Info() (*InfoStat, error) { func HostIDWithContext(ctx context.Context) (string, error) {
return InfoWithContext(context.Background()) uuid, err := unix.Sysctl("kern.hostuuid")
} if err != nil {
return "", err
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))
} }
return strings.ToLower(uuid), err
hostid, err := unix.Sysctl("kern.hostuuid")
if err == nil && hostid != "" {
ret.HostID = strings.ToLower(hostid)
} }
return ret, nil func numProcs(ctx context.Context) (uint64, error) {
procs, err := process.PidsWithContext(ctx)
if err != nil {
return 0, err
} }
return uint64(len(procs)), nil
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
} }
func UsersWithContext(ctx context.Context) ([]UserStat, error) { 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) { func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
platform, err := unix.Sysctl("kern.ostype") platform, err := unix.Sysctl("kern.ostype")
if err != nil { if err != nil {
@ -144,10 +98,6 @@ func PlatformInformationWithContext(ctx context.Context) (string, string, string
return strings.ToLower(platform), "", strings.ToLower(version), nil 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) { func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError return "", "", common.ErrNotImplementedError
} }
@ -191,19 +141,11 @@ func getUsersFromUtmp(utmpfile string) ([]UserStat, error) {
return ret, nil return ret, nil
} }
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return []TemperatureStat{}, common.ErrNotImplementedError return []TemperatureStat{}, common.ErrNotImplementedError
} }
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) { func KernelVersionWithContext(ctx context.Context) (string, error) {
_, _, version, err := PlatformInformation() _, _, version, err := PlatformInformationWithContext(ctx)
return version, err return version, err
} }

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

@ -8,7 +8,6 @@ import (
"encoding/binary" "encoding/binary"
"io/ioutil" "io/ioutil"
"os" "os"
"runtime"
"strings" "strings"
"unsafe" "unsafe"
@ -23,54 +22,16 @@ const (
UTHostSize = 16 UTHostSize = 16
) )
func Info() (*InfoStat, error) { func HostIDWithContext(ctx context.Context) (string, error) {
return InfoWithContext(context.Background()) return "", common.ErrNotImplementedError
} }
func InfoWithContext(ctx context.Context) (*InfoStat, error) { func numProcs(ctx context.Context) (uint64, error) {
ret := &InfoStat{ procs, err := process.PidsWithContext(ctx)
OS: runtime.GOOS, if err != nil {
PlatformFamily: "openbsd", return 0, err
}
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
} }
return uint64(len(procs)), nil
func PlatformInformation() (string, string, string, error) {
return PlatformInformationWithContext(context.Background())
} }
func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) { 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 return platform, family, version, nil
} }
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) { func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError return "", "", common.ErrNotImplementedError
} }
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) { func UsersWithContext(ctx context.Context) ([]UserStat, error) {
var ret []UserStat var ret []UserStat
utmpfile := "/var/run/utmp" utmpfile := "/var/run/utmp"
@ -141,19 +94,11 @@ func UsersWithContext(ctx context.Context) ([]UserStat, error) {
return ret, nil return ret, nil
} }
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return []TemperatureStat{}, common.ErrNotImplementedError return []TemperatureStat{}, common.ErrNotImplementedError
} }
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) { func KernelVersionWithContext(ctx context.Context) (string, error) {
_, _, version, err := PlatformInformation() _, _, version, err := PlatformInformationWithContext(ctx)
return version, err return version, err
} }

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

@ -9,86 +9,19 @@ import (
"os" "os"
"os/exec" "os/exec"
"regexp" "regexp"
"runtime"
"strconv" "strconv"
"strings" "strings"
"time"
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
) )
func Info() (*InfoStat, error) { func HostIDWithContext(ctx context.Context) (string, error) {
return InfoWithContext(context.Background()) platform, err := parseReleaseFile()
}
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")
if err != nil { if err != nil {
return nil, err return "", 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]
}
} }
switch result.Platform { if platform == "SmartOS" {
case "SmartOS":
// If everything works, use the current zone ID as the HostID if present. // If everything works, use the current zone ID as the HostID if present.
zonename, err := exec.LookPath("zonename") zonename, err := exec.LookPath("zonename")
if err == nil { if err == nil {
@ -102,21 +35,19 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) {
if line == "global" { if line == "global" {
hostname, err := os.Hostname() hostname, err := os.Hostname()
if err == nil { if err == nil {
result.HostID = hostname return hostname, nil
} }
} else { } else {
result.HostID = strings.TrimSpace(line) return strings.TrimSpace(line), nil
break
} }
} }
} }
} }
} }
// 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 // this point there are no hardware facilities available. This behavior
// matches that of other supported OSes. // matches that of other supported OSes.
if result.HostID == "" {
hostID, err := exec.LookPath("hostid") hostID, err := exec.LookPath("hostid")
if err == nil { if err == nil {
out, err := invoke.CommandWithContext(ctx, hostID) out, err := invoke.CommandWithContext(ctx, hostID)
@ -124,37 +55,25 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) {
sc := bufio.NewScanner(bytes.NewReader(out)) sc := bufio.NewScanner(bytes.NewReader(out))
for sc.Scan() { for sc.Scan() {
line := sc.Text() line := sc.Text()
result.HostID = strings.TrimSpace(line) return strings.TrimSpace(line), nil
break
}
} }
} }
} }
// Find the boot time and calculate uptime relative to it return "", nil
bootTime, err := BootTime()
if err != nil {
return nil, err
} }
result.BootTime = bootTime
result.Uptime = uptimeSince(bootTime)
// Count number of processes based on the number of entries in /proc // Count number of processes based on the number of entries in /proc
func numProcs(ctx context.Context) (uint64, error) {
dirs, err := ioutil.ReadDir("/proc") dirs, err := ioutil.ReadDir("/proc")
if err != nil { if err != nil {
return nil, err return 0, err
} }
result.Procs = uint64(len(dirs)) return uint64(len(dirs)), nil
return result, nil
} }
var kstatMatch = regexp.MustCompile(`([^\s]+)[\s]+([^\s]*)`) var kstatMatch = regexp.MustCompile(`([^\s]+)[\s]+([^\s]*)`)
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func BootTimeWithContext(ctx context.Context) (uint64, error) { func BootTimeWithContext(ctx context.Context) (uint64, error) {
kstat, err := exec.LookPath("kstat") kstat, err := exec.LookPath("kstat")
if err != nil { if err != nil {
@ -174,80 +93,92 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) {
return strconv.ParseUint(kstats[0][2], 10, 64) return strconv.ParseUint(kstats[0][2], 10, 64)
} }
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func UptimeWithContext(ctx context.Context) (uint64, error) { func UptimeWithContext(ctx context.Context) (uint64, error) {
bootTime, err := BootTime() bootTime, err := BootTime()
if err != nil { if err != nil {
return 0, err return 0, err
} }
return uptimeSince(bootTime), nil return timeSince(bootTime), nil
}
func uptimeSince(since uint64) uint64 {
return uint64(time.Now().Unix()) - since
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
} }
func UsersWithContext(ctx context.Context) ([]UserStat, error) { func UsersWithContext(ctx context.Context) ([]UserStat, error) {
return []UserStat{}, common.ErrNotImplementedError return []UserStat{}, common.ErrNotImplementedError
} }
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return []TemperatureStat{}, common.ErrNotImplementedError return []TemperatureStat{}, common.ErrNotImplementedError
} }
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) { func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError return "", "", common.ErrNotImplementedError
} }
func KernelVersion() (string, error) { // Find distribution name from /etc/release
return KernelVersionWithContext(context.Background()) 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) { return platform, nil
// Parse versions from output of `uname(1)` }
// parseUnameOutput returns platformFamily, kernelVersion and platformVersion
func parseUnameOutput(ctx context.Context) (string, string, string, error) {
uname, err := exec.LookPath("uname") uname, err := exec.LookPath("uname")
if err != nil { if err != nil {
return "", err return "", "", "", err
} }
out, err := invoke.CommandWithContext(ctx, uname, "-srv") out, err := invoke.CommandWithContext(ctx, uname, "-srv")
if err != nil { if err != nil {
return "", err return "", "", "", err
} }
fields := strings.Fields(string(out)) fields := strings.Fields(string(out))
if len(fields) >= 2 { if len(fields) < 3 {
return fields[1], nil 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) { func KernelVersionWithContext(ctx context.Context) (string, error) {
return PlatformInformationWithContext(context.Background()) _, kernelVersion, _, err := parseUnameOutput(ctx)
return kernelVersion, err
} }
func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) { func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
/* This is not finished yet at all. Please contribute! */ platform, err := parseReleaseFile()
if err != nil {
return "", "", "", err
}
version, err = KernelVersion() platformFamily, _, platformVersion, err := parseUnameOutput(ctx)
if err != nil { if err != nil {
return "", "", "", err return "", "", "", err
} }
return "solaris", "solaris", version, nil return platform, platformFamily, platformVersion, nil
} }

@ -6,8 +6,6 @@ import (
"context" "context"
"fmt" "fmt"
"math" "math"
"os"
"runtime"
"strings" "strings"
"sync/atomic" "sync/atomic"
"syscall" "syscall"
@ -16,7 +14,7 @@ import (
"github.com/StackExchange/wmi" "github.com/StackExchange/wmi"
"github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/internal/common"
process "github.com/shirou/gopsutil/process" "github.com/shirou/gopsutil/process"
"golang.org/x/sys/windows" "golang.org/x/sys/windows"
) )
@ -64,66 +62,7 @@ type msAcpi_ThermalZoneTemperature struct {
InstanceName string InstanceName string
} }
func Info() (*InfoStat, error) { func HostIDWithContext(ctx context.Context) (string, 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) {
// 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 // 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 // for rationale of using windows.RegOpenKeyEx/RegQueryValueEx instead of registry.OpenKey/GetStringValue
var h windows.Handle var h windows.Handle
@ -153,8 +92,12 @@ func getMachineGuid() (string, error) {
return strings.ToLower(hostID), nil return strings.ToLower(hostID), nil
} }
func Uptime() (uint64, error) { func numProcs(ctx context.Context) (uint64, error) {
return UptimeWithContext(context.Background()) procs, err := process.PidsWithContext(ctx)
if err != nil {
return 0, err
}
return uint64(len(procs)), nil
} }
func UptimeWithContext(ctx context.Context) (uint64, error) { 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 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 // cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64 var cachedBootTime uint64
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func BootTimeWithContext(ctx context.Context) (uint64, error) { func BootTimeWithContext(ctx context.Context) (uint64, error) {
t := atomic.LoadUint64(&cachedBootTime) t := atomic.LoadUint64(&cachedBootTime)
if t != 0 { if t != 0 {
@ -190,15 +125,11 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
t = bootTimeFromUptime(up) t = timeSince(up)
atomic.StoreUint64(&cachedBootTime, t) atomic.StoreUint64(&cachedBootTime, t)
return t, nil 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) { 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 // 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 // RtlGetVersion bypasses this lying layer and returns the true Windows version
@ -212,7 +143,7 @@ func PlatformInformationWithContext(ctx context.Context) (platform string, famil
} }
// Platform // 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) 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 { if err != nil {
return return
@ -258,20 +189,12 @@ func PlatformInformationWithContext(ctx context.Context) (platform string, famil
return platform, family, version, nil return platform, family, version, nil
} }
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) { func UsersWithContext(ctx context.Context) ([]UserStat, error) {
var ret []UserStat var ret []UserStat
return ret, common.ErrNotImplementedError return ret, common.ErrNotImplementedError
} }
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) { func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
var ret []TemperatureStat var ret []TemperatureStat
var dst []msAcpi_ThermalZoneTemperature var dst []msAcpi_ThermalZoneTemperature
@ -299,24 +222,16 @@ func kelvinToCelsius(temp uint32, n int) float64 {
return math.Trunc((t+0.5/n10)*n10) / n10 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) { func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError return "", "", common.ErrNotImplementedError
} }
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) { func KernelVersionWithContext(ctx context.Context) (string, error) {
_, _, version, err := PlatformInformation() _, _, version, err := PlatformInformationWithContext(ctx)
return version, err return version, err
} }
func kernelArch() (string, error) { func KernelArch() (string, error) {
var systemInfo systemInfo var systemInfo systemInfo
procGetNativeSystemInfo.Call(uintptr(unsafe.Pointer(&systemInfo))) procGetNativeSystemInfo.Call(uintptr(unsafe.Pointer(&systemInfo)))

Loading…
Cancel
Save