Update dependencies

This commit is contained in:
github-actions
2024-06-07 06:06:34 +00:00
parent 6c34d837ef
commit 7a48ce2e38
119 changed files with 3282 additions and 1487 deletions

View File

@@ -1,9 +1,16 @@
---
linters:
enable:
- errcheck
- godot
- gosimple
- govet
- ineffassign
- misspell
- revive
- staticcheck
- testifylint
- unused
linter-settings:
godot:

View File

@@ -61,7 +61,7 @@ PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_
SKIP_GOLANGCI_LINT :=
GOLANGCI_LINT :=
GOLANGCI_LINT_OPTS ?=
GOLANGCI_LINT_VERSION ?= v1.56.2
GOLANGCI_LINT_VERSION ?= v1.59.0
# golangci-lint only supports linux, darwin and windows platforms on i386/amd64/arm64.
# windows isn't included here because of the path separator being different.
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))

View File

@@ -12,8 +12,57 @@ import (
)
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
var ret []TimesStat
if percpu {
return []TimesStat{}, common.ErrNotImplementedError
per_out, err := invoke.CommandWithContext(ctx, "sar", "-u", "-P", "ALL", "10", "1")
if err != nil {
return nil, err
}
lines := strings.Split(string(per_out), "\n")
if len(lines) < 6 {
return []TimesStat{}, common.ErrNotImplementedError
}
hp := strings.Fields(lines[5]) // headers
for l := 6; l < len(lines)-1; l++ {
ct := &TimesStat{}
v := strings.Fields(lines[l]) // values
for i, header := range hp {
// We're done in any of these use cases
if i >= len(v) || v[0] == "-" {
break
}
// Position variable for v
pos := i
// There is a missing field at the beginning of all but the first line
// so adjust the position
if l > 6 {
pos = i - 1
}
// We don't want invalid positions
if pos < 0 {
continue
}
if t, err := strconv.ParseFloat(v[pos], 64); err == nil {
switch header {
case `cpu`:
ct.CPU = strconv.FormatFloat(t, 'f', -1, 64)
case `%usr`:
ct.User = t
case `%sys`:
ct.System = t
case `%wio`:
ct.Iowait = t
case `%idle`:
ct.Idle = t
}
}
}
// Valid CPU data, so append it
ret = append(ret, *ct)
}
} else {
out, err := invoke.CommandWithContext(ctx, "sar", "-u", "10", "1")
if err != nil {
@@ -24,26 +73,28 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
return []TimesStat{}, common.ErrNotImplementedError
}
ret := TimesStat{CPU: "cpu-total"}
ct := &TimesStat{CPU: "cpu-total"}
h := strings.Fields(lines[len(lines)-3]) // headers
v := strings.Fields(lines[len(lines)-2]) // values
for i, header := range h {
if t, err := strconv.ParseFloat(v[i], 64); err == nil {
switch header {
case `%usr`:
ret.User = t
ct.User = t
case `%sys`:
ret.System = t
ct.System = t
case `%wio`:
ret.Iowait = t
ct.Iowait = t
case `%idle`:
ret.Idle = t
ct.Idle = t
}
}
}
return []TimesStat{ret}, nil
ret = append(ret, *ct)
}
return ret, nil
}
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
@@ -78,6 +129,20 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
}
}
break
} else if strings.HasPrefix(line, "System Model:") {
p := strings.Split(string(line), ":")
if p != nil {
ret.VendorID = strings.TrimSpace(p[1])
}
} else if strings.HasPrefix(line, "Processor Type:") {
p := strings.Split(string(line), ":")
if p != nil {
c := strings.Split(string(p[1]), "_")
if c != nil {
ret.Family = strings.TrimSpace(c[0])
ret.Model = strings.TrimSpace(c[1])
}
}
}
}
return []InfoStat{ret}, nil

View File

@@ -5,6 +5,8 @@ package disk
import (
"context"
"errors"
"strings"
"github.com/shirou/gopsutil/v3/internal/common"
)
@@ -13,10 +15,36 @@ func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOC
return nil, common.ErrNotImplementedError
}
func SerialNumberWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}
func LabelWithContext(ctx context.Context, name string) (string, error) {
return "", common.ErrNotImplementedError
}
// Using lscfg and a device name, we can get the device information
// This is a pure go implementation, and should be moved to disk_aix_nocgo.go
// if a more efficient CGO method is introduced in disk_aix_cgo.go
func SerialNumberWithContext(ctx context.Context, name string) (string, error) {
// This isn't linux, these aren't actual disk devices
if strings.HasPrefix(name, "/dev/") {
return "", errors.New("devices on /dev are not physical disks on aix")
}
out, err := invoke.CommandWithContext(ctx, "lscfg", "-vl", name)
if err != nil {
return "", err
}
ret := ""
// Kind of inefficient, but it works
lines := strings.Split(string(out[:]), "\n")
for line := 1; line < len(lines); line++ {
v := strings.TrimSpace(lines[line])
if strings.HasPrefix(v, "Serial Number...............") {
ret = strings.TrimPrefix(v, "Serial Number...............")
if ret == "" {
return "", errors.New("empty serial for disk")
}
return ret, nil
}
}
return ret, errors.New("serial entry not found for disk")
}

View File

@@ -6,6 +6,7 @@ package disk
import (
"context"
"regexp"
"strconv"
"strings"
"github.com/shirou/gopsutil/v3/internal/common"
@@ -79,3 +80,108 @@ func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, erro
func getFsType(stat unix.Statfs_t) string {
return FSType[int(stat.Vfstype)]
}
func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
out, err := invoke.CommandWithContext(ctx, "df", "-v")
if err != nil {
return nil, err
}
ret := &UsageStat{}
blocksize := uint64(512)
lines := strings.Split(string(out), "\n")
if len(lines) < 2 {
return &UsageStat{}, common.ErrNotImplementedError
}
hf := strings.Fields(strings.Replace(lines[0], "Mounted on", "Path", -1)) // headers
for line := 1; line < len(lines); line++ {
fs := strings.Fields(lines[line]) // values
for i, header := range hf {
// We're done in any of these use cases
if i >= len(fs) {
break
}
switch header {
case `Filesystem`:
// This is not a valid fs for us to parse
if fs[i] == "/proc" || fs[i] == "/ahafs" || fs[i] != path {
break
}
ret.Fstype, err = GetMountFSTypeWithContext(ctx, fs[i])
if err != nil {
return nil, err
}
case `Path`:
ret.Path = fs[i]
case `512-blocks`:
total, err := strconv.ParseUint(fs[i], 10, 64)
ret.Total = total * blocksize
if err != nil {
return nil, err
}
case `Used`:
ret.Used, err = strconv.ParseUint(fs[i], 10, 64)
if err != nil {
return nil, err
}
case `Free`:
ret.Free, err = strconv.ParseUint(fs[i], 10, 64)
if err != nil {
return nil, err
}
case `%Used`:
val, err := strconv.Atoi(strings.Replace(fs[i], "%", "", -1))
if err != nil {
return nil, err
}
ret.UsedPercent = float64(val) / float64(100)
case `Ifree`:
ret.InodesFree, err = strconv.ParseUint(fs[i], 10, 64)
if err != nil {
return nil, err
}
case `Iused`:
ret.InodesUsed, err = strconv.ParseUint(fs[i], 10, 64)
if err != nil {
return nil, err
}
case `%Iused`:
val, err := strconv.Atoi(strings.Replace(fs[i], "%", "", -1))
if err != nil {
return nil, err
}
ret.InodesUsedPercent = float64(val) / float64(100)
}
}
// Calculated value, since it isn't returned by the command
ret.InodesTotal = ret.InodesUsed + ret.InodesFree
// Valid Usage data, so append it
return ret, nil
}
return ret, nil
}
func GetMountFSTypeWithContext(ctx context.Context, mp string) (string, error) {
out, err := invoke.CommandWithContext(ctx, "mount")
if err != nil {
return "", err
}
// Kind of inefficient, but it works
lines := strings.Split(string(out[:]), "\n")
for line := 1; line < len(lines); line++ {
fields := strings.Fields(lines[line])
if strings.TrimSpace(fields[0]) == mp {
return fields[2], nil
}
}
return "", nil
}

View File

@@ -1,5 +1,5 @@
//go:build freebsd || linux || darwin || (aix && !cgo)
// +build freebsd linux darwin aix,!cgo
//go:build freebsd || linux || darwin
// +build freebsd linux darwin
package disk

202
vendor/github.com/shirou/gopsutil/v3/host/host_aix.go generated vendored Normal file
View File

@@ -0,0 +1,202 @@
//go:build aix
// +build aix
package host
import (
"context"
"errors"
"strconv"
"strings"
"github.com/shirou/gopsutil/v3/internal/common"
)
// from https://www.ibm.com/docs/en/aix/7.2?topic=files-utmph-file
const (
user_PROCESS = 7
hostTemperatureScale = 1000.0 // Not part of the linked file, but kept just in case it becomes relevant
)
func HostIDWithContext(ctx context.Context) (string, error) {
out, err := invoke.CommandWithContext(ctx, "uname", "-u")
if err != nil {
return "", err
}
// The command always returns an extra newline, so we make use of Split() to get only the first line
return strings.Split(string(out[:]), "\n")[0], nil
}
func numProcs(ctx context.Context) (uint64, error) {
return 0, common.ErrNotImplementedError
}
func BootTimeWithContext(ctx context.Context) (btime uint64, err error) {
ut, err := UptimeWithContext(ctx)
if err != nil {
return 0, err
}
if ut <= 0 {
return 0, errors.New("Uptime was not set, so cannot calculate boot time from it.")
}
ut = ut * 60
return timeSince(ut), nil
}
// This function takes multiple formats of output frmo the uptime
// command and converts the data into minutes.
// Some examples of uptime output that this command handles:
// 11:54AM up 13 mins, 1 user, load average: 2.78, 2.62, 1.79
// 12:41PM up 1 hr, 1 user, load average: 2.47, 2.85, 2.83
// 07:43PM up 5 hrs, 1 user, load average: 3.27, 2.91, 2.72
// 11:18:23 up 83 days, 18:29, 4 users, load average: 0.16, 0.03, 0.01
func UptimeWithContext(ctx context.Context) (uint64, error) {
out, err := invoke.CommandWithContext(ctx, "uptime")
if err != nil {
return 0, err
}
// Convert our uptime to a series of fields we can extract
ut := strings.Fields(string(out[:]))
// Convert the second field value to integer
var days uint64 = 0
var hours uint64 = 0
var minutes uint64 = 0
if ut[3] == "days," {
days, err = strconv.ParseUint(ut[2], 10, 64)
if err != nil {
return 0, err
}
// Split field 4 into hours and minutes
hm := strings.Split(ut[4], ":")
hours, err = strconv.ParseUint(hm[0], 10, 64)
if err != nil {
return 0, err
}
minutes, err = strconv.ParseUint(strings.Replace(hm[1], ",", "", -1), 10, 64)
if err != nil {
return 0, err
}
} else if ut[3] == "hr," || ut[3] == "hrs," {
hours, err = strconv.ParseUint(ut[2], 10, 64)
if err != nil {
return 0, err
}
} else if ut[3] == "mins," {
minutes, err = strconv.ParseUint(ut[2], 10, 64)
if err != nil {
return 0, err
}
} else if _, err := strconv.ParseInt(ut[3], 10, 64); err == nil && strings.Contains(ut[2], ":") {
// Split field 2 into hours and minutes
hm := strings.Split(ut[2], ":")
hours, err = strconv.ParseUint(hm[0], 10, 64)
if err != nil {
return 0, err
}
minutes, err = strconv.ParseUint(strings.Replace(hm[1], ",", "", -1), 10, 64)
if err != nil {
return 0, err
}
}
// Stack them all together as minutes
total_time := (days * 24 * 60) + (hours * 60) + minutes
return total_time, nil
}
// This is a weak implementation due to the limitations on retrieving this data in AIX
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
var ret []UserStat
out, err := invoke.CommandWithContext(ctx, "w")
if err != nil {
return nil, err
}
lines := strings.Split(string(out), "\n")
if len(lines) < 3 {
return []UserStat{}, common.ErrNotImplementedError
}
hf := strings.Fields(lines[1]) // headers
for l := 2; l < len(lines); l++ {
v := strings.Fields(lines[l]) // values
us := &UserStat{}
for i, header := range hf {
// We're done in any of these use cases
if i >= len(v) || v[0] == "-" {
break
}
if t, err := strconv.ParseFloat(v[i], 64); err == nil {
switch header {
case `User`:
us.User = strconv.FormatFloat(t, 'f', 1, 64)
case `tty`:
us.Terminal = strconv.FormatFloat(t, 'f', 1, 64)
}
}
}
// Valid User data, so append it
ret = append(ret, *us)
}
return ret, nil
}
// Much of this function could be static. However, to be future proofed, I've made it call the OS for the information in all instances.
func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) {
// Set the platform (which should always, and only be, "AIX") from `uname -s`
out, err := invoke.CommandWithContext(ctx, "uname", "-s")
if err != nil {
return "", "", "", err
}
platform = strings.TrimRight(string(out[:]), "\n")
// Set the family
family = strings.TrimRight(string(out[:]), "\n")
// Set the version
out, err = invoke.CommandWithContext(ctx, "oslevel")
if err != nil {
return "", "", "", err
}
version = strings.TrimRight(string(out[:]), "\n")
return platform, family, version, nil
}
func KernelVersionWithContext(ctx context.Context) (version string, err error) {
out, err := invoke.CommandWithContext(ctx, "oslevel", "-s")
if err != nil {
return "", err
}
version = strings.TrimRight(string(out[:]), "\n")
return version, nil
}
func KernelArch() (arch string, err error) {
out, err := invoke.Command("bootinfo", "-y")
if err != nil {
return "", err
}
arch = strings.TrimRight(string(out[:]), "\n")
return arch, nil
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return nil, common.ErrNotImplementedError
}

View File

@@ -0,0 +1,48 @@
//go:build aix && ppc64 && cgo
// +build aix,ppc64,cgo
// Guessed at from the following document:
// https://www.ibm.com/docs/sl/ibm-mq/9.2?topic=platforms-standard-data-types-aix-linux-windows
package host
const (
sizeofPtr = 0x8
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
sizeOfUtmp = 0x180
)
type (
_C_short int16
_C_int int32
_C_long int64
_C_long_long int64
)
type utmp struct {
Type int16
Pad_cgo_0 [2]byte
Pid int32
Line [32]int8
Id [4]int8
User [32]int8
Host [256]int8
Exit exit_status
Session int32
Tv timeval
Addr_v6 [4]int32
X__glibc_reserved [20]int8
}
type exit_status struct {
Termination int16
Exit int16
}
type timeval struct {
Sec int64
Usec int64
}

View File

@@ -1,5 +1,5 @@
//go:build !darwin && !linux && !freebsd && !openbsd && !netbsd && !solaris && !windows
// +build !darwin,!linux,!freebsd,!openbsd,!netbsd,!solaris,!windows
//go:build !darwin && !linux && !freebsd && !openbsd && !netbsd && !solaris && !windows && !aix
// +build !darwin,!linux,!freebsd,!openbsd,!netbsd,!solaris,!windows,!aix
package host

View File

@@ -12,7 +12,7 @@ import (
)
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
vmem, swap, err := callSVMon(ctx)
vmem, swap, err := callSVMon(ctx, true)
if err != nil {
return nil, err
}
@@ -25,7 +25,7 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
}
func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
_, swap, err := callSVMon(ctx)
_, swap, err := callSVMon(ctx, false)
if err != nil {
return nil, err
}
@@ -35,7 +35,7 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
return swap, nil
}
func callSVMon(ctx context.Context) (*VirtualMemoryStat, *SwapMemoryStat, error) {
func callSVMon(ctx context.Context, virt bool) (*VirtualMemoryStat, *SwapMemoryStat, error) {
out, err := invoke.CommandWithContext(ctx, "svmon", "-G")
if err != nil {
return nil, nil, err
@@ -45,7 +45,7 @@ func callSVMon(ctx context.Context) (*VirtualMemoryStat, *SwapMemoryStat, error)
vmem := &VirtualMemoryStat{}
swap := &SwapMemoryStat{}
for _, line := range strings.Split(string(out), "\n") {
if strings.HasPrefix(line, "memory") {
if virt && strings.HasPrefix(line, "memory") {
p := strings.Fields(line)
if len(p) > 2 {
if t, err := strconv.ParseUint(p[1], 10, 64); err == nil {

View File

@@ -24,14 +24,21 @@ func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
}
txtFound := 0
lines := strings.Split(string(out), "\n")
fallback := ""
for i := 1; i < len(lines); i++ {
if lines[i] == "ftxt" {
txtFound++
if txtFound == 1 {
fallback = lines[i-1][1:]
}
if txtFound == 2 {
return lines[i-1][1:], nil
}
}
}
if fallback != "" {
return fallback, nil
}
return "", fmt.Errorf("missing txt data returned by lsof")
}

View File

@@ -68,7 +68,12 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) {
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
mib := []int32{CTLKern, KernProcCwd, p.Pid}
buf, _, err := common.CallSyscall(mib)
if err != nil {
return "", err
}
return common.ByteToString(buf), nil
}
func (p *Process) ExeWithContext(ctx context.Context) (string, error) {

View File

@@ -14,6 +14,7 @@ const (
KernProcProc = 8
KernProcPathname = 12
KernProcArgs = 55
KernProcCwd = 78
KernProcArgv = 1
KernProcEnv = 3
)

View File

@@ -11,6 +11,7 @@ const (
KernProcProc = 8
KernProcPathname = 12
KernProcArgs = 55
KernProcCwd = 78
KernProcArgv = 1
KernProcEnv = 3
)

View File

@@ -14,6 +14,7 @@ const (
KernProcProc = 8
KernProcPathname = 12
KernProcArgs = 55
KernProcCwd = 78
KernProcArgv = 1
KernProcEnv = 3
)

View File

@@ -14,6 +14,7 @@ const (
KernProcProc = 8
KernProcPathname = 12
KernProcArgs = 55
KernProcCwd = 78
KernProcArgv = 1
KernProcEnv = 3
)

View File

@@ -14,6 +14,7 @@ const (
KernProcProc = 8
KernProcPathname = 12
KernProcArgs = 55
KernProcCwd = 78
KernProcArgv = 1
KernProcEnv = 3
)