diff --git a/vendor/github.com/shirou/gopsutil/LICENSE b/vendor/github.com/shirou/gopsutil/LICENSE new file mode 100644 index 000000000..da71a5e72 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/LICENSE @@ -0,0 +1,61 @@ +gopsutil is distributed under BSD license reproduced below. + +Copyright (c) 2014, WAKAYAMA Shirou +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the gopsutil authors nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +------- +internal/common/binary.go in the gopsutil is copied and modifid from golang/encoding/binary.go. + + + +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu.go b/vendor/github.com/shirou/gopsutil/cpu/cpu.go index f5bf315fe..049869e2e 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu.go @@ -1,6 +1,7 @@ package cpu import ( + "context" "encoding/json" "fmt" "runtime" @@ -12,6 +13,9 @@ import ( "github.com/shirou/gopsutil/internal/common" ) +// TimesStat contains the amounts of time the CPU has spent performing different +// kinds of work. Time units are in USER_HZ or Jiffies (typically hundredths of +// a second). It is based on linux /proc/stat file. type TimesStat struct { CPU string `json:"cpu"` User float64 `json:"user"` @@ -61,6 +65,10 @@ func init() { } func Counts(logical bool) (int, error) { + return CountsWithContext(context.Background(), logical) +} + +func CountsWithContext(ctx context.Context, logical bool) (int, error) { return runtime.NumCPU(), nil } @@ -134,6 +142,10 @@ func calculateAllBusy(t1, t2 []TimesStat) ([]float64, error) { // If an interval of 0 is given it will compare the current cpu times against the last call. // Returns one value per cpu, or a single value if percpu is set to false. func Percent(interval time.Duration, percpu bool) ([]float64, error) { + return PercentWithContext(context.Background(), interval, percpu) +} + +func PercentWithContext(ctx context.Context, interval time.Duration, percpu bool) ([]float64, error) { if interval <= 0 { return percentUsedFromLastCall(percpu) } diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go index af27e620e..001517e2a 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go @@ -3,6 +3,7 @@ package cpu import ( + "context" "os/exec" "strconv" "strings" @@ -22,6 +23,10 @@ const ( var ClocksPerSec = float64(128) func Times(percpu bool) ([]TimesStat, error) { + return TimesWithContext(context.Background(), percpu) +} + +func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { if percpu { return perCPUTimes() } @@ -31,6 +36,10 @@ func Times(percpu bool) ([]TimesStat, error) { // Returns only one CPUInfoStat on FreeBSD func Info() ([]InfoStat, error) { + return InfoWithContext(context.Background()) +} + +func InfoWithContext(ctx context.Context) ([]InfoStat, error) { var ret []InfoStat sysctl, err := exec.LookPath("/usr/sbin/sysctl") if err != nil { diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_fallback.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_fallback.go index 8e09ccb4e..e9e7ada2c 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_fallback.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_fallback.go @@ -3,13 +3,23 @@ package cpu import ( + "context" + "github.com/shirou/gopsutil/internal/common" ) func Times(percpu bool) ([]TimesStat, error) { + return TimesWithContext(context.Background(), percpu) +} + +func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { return []TimesStat{}, common.ErrNotImplementedError } func Info() ([]InfoStat, error) { + return InfoWithContext(context.Background()) +} + +func InfoWithContext(ctx context.Context) ([]InfoStat, error) { return []InfoStat{}, common.ErrNotImplementedError } diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go index 7d0321f79..b6c7186c7 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go @@ -1,23 +1,17 @@ package cpu import ( + "context" "fmt" "os/exec" + "reflect" "regexp" "strconv" "strings" + "unsafe" "github.com/shirou/gopsutil/internal/common" -) - -// sys/resource.h -const ( - CPUser = 0 - CPNice = 1 - CPSys = 2 - CPIntr = 3 - CPIdle = 4 - CPUStates = 5 + "golang.org/x/sys/unix" ) var ClocksPerSec = float64(128) @@ -27,6 +21,8 @@ var featuresMatch = regexp.MustCompile(`Features=.+<(.+)>`) var featuresMatch2 = regexp.MustCompile(`Features2=[a-f\dx]+<(.+)>`) var cpuEnd = regexp.MustCompile(`^Trying to mount root`) var cpuCores = regexp.MustCompile(`FreeBSD/SMP: (\d*) package\(s\) x (\d*) core\(s\)`) +var cpuTimesSize int +var emptyTimes cpuTimes func init() { getconf, err := exec.LookPath("/usr/bin/getconf") @@ -43,97 +39,84 @@ func init() { } } +func timeStat(name string, t *cpuTimes) *TimesStat { + return &TimesStat{ + User: float64(t.User) / ClocksPerSec, + Nice: float64(t.Nice) / ClocksPerSec, + System: float64(t.Sys) / ClocksPerSec, + Idle: float64(t.Idle) / ClocksPerSec, + Irq: float64(t.Intr) / ClocksPerSec, + CPU: name, + } +} + func Times(percpu bool) ([]TimesStat, error) { - var ret []TimesStat + return TimesWithContext(context.Background(), percpu) +} - var sysctlCall string - var ncpu int +func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { if percpu { - sysctlCall = "kern.cp_times" - ncpu, _ = Counts(true) - } else { - sysctlCall = "kern.cp_time" - ncpu = 1 + buf, err := unix.SysctlRaw("kern.cp_times") + if err != nil { + return nil, err + } + + // We can't do this in init due to the conflict with cpu.init() + if cpuTimesSize == 0 { + cpuTimesSize = int(reflect.TypeOf(cpuTimes{}).Size()) + } + + ncpus := len(buf) / cpuTimesSize + ret := make([]TimesStat, 0, ncpus) + for i := 0; i < ncpus; i++ { + times := (*cpuTimes)(unsafe.Pointer(&buf[i*cpuTimesSize])) + if *times == emptyTimes { + // CPU not present + continue + } + ret = append(ret, *timeStat(fmt.Sprintf("cpu%d", len(ret)), times)) + } + return ret, nil } - cpuTimes, err := common.DoSysctrl(sysctlCall) + buf, err := unix.SysctlRaw("kern.cp_time") if err != nil { - return ret, err + return nil, err } - for i := 0; i < ncpu; i++ { - offset := CPUStates * i - user, err := strconv.ParseFloat(cpuTimes[CPUser+offset], 64) - if err != nil { - return ret, err - } - nice, err := strconv.ParseFloat(cpuTimes[CPNice+offset], 64) - if err != nil { - return ret, err - } - sys, err := strconv.ParseFloat(cpuTimes[CPSys+offset], 64) - if err != nil { - return ret, err - } - idle, err := strconv.ParseFloat(cpuTimes[CPIdle+offset], 64) - if err != nil { - return ret, err - } - intr, err := strconv.ParseFloat(cpuTimes[CPIntr+offset], 64) - if err != nil { - return ret, err - } - - c := TimesStat{ - User: float64(user / ClocksPerSec), - Nice: float64(nice / ClocksPerSec), - System: float64(sys / ClocksPerSec), - Idle: float64(idle / ClocksPerSec), - Irq: float64(intr / ClocksPerSec), - } - if !percpu { - c.CPU = "cpu-total" - } else { - c.CPU = fmt.Sprintf("cpu%d", i) - } - - ret = append(ret, c) - } - - return ret, nil + times := (*cpuTimes)(unsafe.Pointer(&buf[0])) + return []TimesStat{*timeStat("cpu-total", times)}, nil } // Returns only one InfoStat on FreeBSD. The information regarding core // count, however is accurate and it is assumed that all InfoStat attributes // are the same across CPUs. func Info() ([]InfoStat, error) { + return InfoWithContext(context.Background()) +} + +func InfoWithContext(ctx context.Context) ([]InfoStat, error) { const dmesgBoot = "/var/run/dmesg.boot" c, num, err := parseDmesgBoot(dmesgBoot) if err != nil { return nil, err } - var vals []string - if vals, err = common.DoSysctrl("hw.clockrate"); err != nil { - return nil, err - } - if c.Mhz, err = strconv.ParseFloat(vals[0], 64); err != nil { - return nil, fmt.Errorf("unable to parse FreeBSD CPU clock rate: %v", err) - } - if vals, err = common.DoSysctrl("hw.ncpu"); err != nil { + var u32 uint32 + if u32, err = unix.SysctlUint32("hw.clockrate"); err != nil { return nil, err } - var i64 int64 - if i64, err = strconv.ParseInt(vals[0], 10, 32); err != nil { - return nil, fmt.Errorf("unable to parse FreeBSD cores: %v", err) - } - c.Cores = int32(i64) + c.Mhz = float64(u32) - if vals, err = common.DoSysctrl("hw.model"); err != nil { + if u32, err = unix.SysctlUint32("hw.ncpu"); err != nil { + return nil, err + } + c.Cores = int32(u32) + + if c.ModelName, err = unix.Sysctl("hw.model"); err != nil { return nil, err } - c.ModelName = strings.Join(vals, " ") ret := make([]InfoStat, num) for i := 0; i < num; i++ { diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd_386.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd_386.go new file mode 100644 index 000000000..8b7f4c321 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd_386.go @@ -0,0 +1,9 @@ +package cpu + +type cpuTimes struct { + User uint32 + Nice uint32 + Sys uint32 + Intr uint32 + Idle uint32 +} diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd_amd64.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd_amd64.go new file mode 100644 index 000000000..57e14528d --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd_amd64.go @@ -0,0 +1,9 @@ +package cpu + +type cpuTimes struct { + User uint64 + Nice uint64 + Sys uint64 + Intr uint64 + Idle uint64 +} diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd_test.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd_test.go new file mode 100644 index 000000000..c0ec73ca3 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd_test.go @@ -0,0 +1,40 @@ +package cpu + +import ( + "path/filepath" + "runtime" + "testing" + + "github.com/shirou/gopsutil/internal/common" +) + +func TestParseDmesgBoot(t *testing.T) { + if runtime.GOOS != "freebsd" { + t.SkipNow() + } + + var cpuTests = []struct { + file string + cpuNum int + cores int32 + }{ + {"1cpu_2core.txt", 1, 2}, + {"1cpu_4core.txt", 1, 4}, + {"2cpu_4core.txt", 2, 4}, + } + for _, tt := range cpuTests { + v, num, err := parseDmesgBoot(filepath.Join("testdata", "freebsd", tt.file)) + if err != nil { + t.Errorf("parseDmesgBoot failed(%s), %v", tt.file, err) + } + if num != tt.cpuNum { + t.Errorf("parseDmesgBoot wrong length(%s), %v", tt.file, err) + } + if v.Cores != tt.cores { + t.Errorf("parseDmesgBoot wrong core(%s), %v", tt.file, err) + } + if !common.StringsContains(v.Flags, "fpu") { + t.Errorf("parseDmesgBoot fail to parse features(%s), %v", tt.file, err) + } + } +} diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go index 48e45da39..0f3d928c2 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go @@ -3,6 +3,7 @@ package cpu import ( + "context" "errors" "fmt" "os/exec" @@ -30,6 +31,10 @@ func init() { } func Times(percpu bool) ([]TimesStat, error) { + return TimesWithContext(context.Background(), percpu) +} + +func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { filename := common.HostProc("stat") var lines = []string{} if percpu { @@ -104,6 +109,10 @@ func finishCPUInfo(c *InfoStat) error { // For example a single socket board with two cores each with HT will // return 4 CPUInfoStat structs on Linux and the "Cores" field set to 1. func Info() ([]InfoStat, error) { + return InfoWithContext(context.Background()) +} + +func InfoWithContext(ctx context.Context) ([]InfoStat, error) { filename := common.HostProc("cpuinfo") lines, _ := common.ReadLines(filename) diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_linux_test.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_linux_test.go new file mode 100644 index 000000000..53cfcb7c7 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_linux_test.go @@ -0,0 +1,40 @@ +package cpu + +import ( + "os" + "testing" +) + +func TestTimesEmpty(t *testing.T) { + orig := os.Getenv("HOST_PROC") + os.Setenv("HOST_PROC", "testdata/linux/times_empty") + _, err := Times(true) + if err != nil { + t.Error("Times(true) failed") + } + _, err = Times(false) + if err != nil { + t.Error("Times(false) failed") + } + os.Setenv("HOST_PROC", orig) +} + +func TestCPUparseStatLine_424(t *testing.T) { + orig := os.Getenv("HOST_PROC") + os.Setenv("HOST_PROC", "testdata/linux/424/proc") + { + l, err := Times(true) + if err != nil || len(l) == 0 { + t.Error("Times(true) failed") + } + t.Logf("Times(true): %#v", l) + } + { + l, err := Times(false) + if err != nil || len(l) == 0 { + t.Error("Times(false) failed") + } + t.Logf("Times(false): %#v", l) + } + os.Setenv("HOST_PROC", orig) +} diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_openbsd.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_openbsd.go index 03aae6e99..82b920f66 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_openbsd.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_openbsd.go @@ -4,6 +4,7 @@ package cpu import ( "bytes" + "context" "encoding/binary" "fmt" "os/exec" @@ -49,6 +50,10 @@ func init() { } func Times(percpu bool) ([]TimesStat, error) { + return TimesWithContext(context.Background(), percpu) +} + +func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { var ret []TimesStat var ncpu int @@ -96,6 +101,10 @@ func Times(percpu bool) ([]TimesStat, error) { // Returns only one (minimal) CPUInfoStat on OpenBSD func Info() ([]InfoStat, error) { + return InfoWithContext(context.Background()) +} + +func InfoWithContext(ctx context.Context) ([]InfoStat, error) { var ret []InfoStat c := InfoStat{} diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_solaris.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_solaris.go index b56786bdb..0899f41c8 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_solaris.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_solaris.go @@ -1,6 +1,7 @@ package cpu import ( + "context" "errors" "fmt" "os/exec" @@ -30,10 +31,18 @@ func init() { } func Times(percpu bool) ([]TimesStat, error) { + return TimesWithContext(context.Background(), percpu) +} + +func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { return []TimesStat{}, common.ErrNotImplementedError } func Info() ([]InfoStat, error) { + return InfoWithContext(context.Background()) +} + +func InfoWithContext(ctx context.Context) ([]InfoStat, error) { psrInfo, err := exec.LookPath("/usr/sbin/psrinfo") if err != nil { return nil, fmt.Errorf("cannot find psrinfo: %s", err) diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_solaris_test.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_solaris_test.go new file mode 100644 index 000000000..b22d38567 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_solaris_test.go @@ -0,0 +1,110 @@ +package cpu + +import ( + "io/ioutil" + "path/filepath" + "reflect" + "sort" + "testing" +) + +func TestParseISAInfo(t *testing.T) { + cases := []struct { + filename string + expected []string + }{ + { + "1cpu_1core_isainfo.txt", + []string{"rdseed", "adx", "avx2", "fma", "bmi2", "bmi1", "rdrand", "f16c", "vmx", + "avx", "xsave", "pclmulqdq", "aes", "movbe", "sse4.2", "sse4.1", "ssse3", "popcnt", + "tscp", "cx16", "sse3", "sse2", "sse", "fxsr", "mmx", "cmov", "amd_sysc", "cx8", + "tsc", "fpu"}, + }, + { + "2cpu_1core_isainfo.txt", + []string{"rdseed", "adx", "avx2", "fma", "bmi2", "bmi1", "rdrand", "f16c", "vmx", + "avx", "xsave", "pclmulqdq", "aes", "movbe", "sse4.2", "sse4.1", "ssse3", "popcnt", + "tscp", "cx16", "sse3", "sse2", "sse", "fxsr", "mmx", "cmov", "amd_sysc", "cx8", + "tsc", "fpu"}, + }, + { + "2cpu_8core_isainfo.txt", + []string{"vmx", "avx", "xsave", "pclmulqdq", "aes", "sse4.2", "sse4.1", "ssse3", "popcnt", + "tscp", "cx16", "sse3", "sse2", "sse", "fxsr", "mmx", "cmov", "amd_sysc", "cx8", + "tsc", "fpu"}, + }, + } + + for _, tc := range cases { + content, err := ioutil.ReadFile(filepath.Join("testdata", "solaris", tc.filename)) + if err != nil { + t.Errorf("cannot read test case: %s", err) + } + + sort.Strings(tc.expected) + + flags, err := parseISAInfo(string(content)) + if err != nil { + t.Fatalf("parseISAInfo: %s", err) + } + + if !reflect.DeepEqual(tc.expected, flags) { + t.Fatalf("Bad flags\nExpected: %v\n Actual: %v", tc.expected, flags) + } + } +} + +func TestParseProcessorInfo(t *testing.T) { + cases := []struct { + filename string + expected []InfoStat + }{ + { + "1cpu_1core_psrinfo.txt", + []InfoStat{ + {CPU: 0, VendorID: "GenuineIntel", Family: "6", Model: "78", Stepping: 3, PhysicalID: "0", CoreID: "0", Cores: 1, ModelName: "Intel(r) Core(tm) i7-6567U CPU @ 3.30GHz", Mhz: 3312}, + }, + }, + { + "2cpu_1core_psrinfo.txt", + []InfoStat{ + {CPU: 0, VendorID: "GenuineIntel", Family: "6", Model: "78", Stepping: 3, PhysicalID: "0", CoreID: "0", Cores: 1, ModelName: "Intel(r) Core(tm) i7-6567U CPU @ 3.30GHz", Mhz: 3312}, + {CPU: 1, VendorID: "GenuineIntel", Family: "6", Model: "78", Stepping: 3, PhysicalID: "1", CoreID: "0", Cores: 1, ModelName: "Intel(r) Core(tm) i7-6567U CPU @ 3.30GHz", Mhz: 3312}, + }, + }, + { + "2cpu_8core_psrinfo.txt", + []InfoStat{ + {CPU: 0, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "0", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 1, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "1", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 2, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "2", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 3, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "3", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 4, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "4", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 5, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "5", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 6, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "6", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 7, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "0", CoreID: "7", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 8, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "0", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 9, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "1", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 10, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "2", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 11, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "3", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 12, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "4", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 13, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "5", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 14, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "6", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + {CPU: 15, VendorID: "GenuineIntel", Family: "6", Model: "45", Stepping: 7, PhysicalID: "1", CoreID: "7", Cores: 2, ModelName: "Intel(r) Xeon(r) CPU E5-2670 0 @ 2.60GHz", Mhz: 2600}, + }, + }, + } + + for _, tc := range cases { + content, err := ioutil.ReadFile(filepath.Join("testdata", "solaris", tc.filename)) + if err != nil { + t.Errorf("cannot read test case: %s", err) + } + + cpus, err := parseProcessorInfo(string(content)) + + if !reflect.DeepEqual(tc.expected, cpus) { + t.Fatalf("Bad Processor Info\nExpected: %v\n Actual: %v", tc.expected, cpus) + } + } +} diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_test.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_test.go new file mode 100644 index 000000000..6082ffcc5 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_test.go @@ -0,0 +1,145 @@ +package cpu + +import ( + "fmt" + "os" + "runtime" + "testing" + "time" +) + +func TestCpu_times(t *testing.T) { + v, err := Times(false) + if err != nil { + t.Errorf("error %v", err) + } + if len(v) == 0 { + t.Error("could not get CPUs ", err) + } + empty := TimesStat{} + for _, vv := range v { + if vv == empty { + t.Errorf("could not get CPU User: %v", vv) + } + } +} + +func TestCpu_counts(t *testing.T) { + v, err := Counts(true) + if err != nil { + t.Errorf("error %v", err) + } + if v == 0 { + t.Errorf("could not get CPU counts: %v", v) + } +} + +func TestCPUTimeStat_String(t *testing.T) { + v := TimesStat{ + CPU: "cpu0", + User: 100.1, + System: 200.1, + Idle: 300.1, + } + e := `{"cpu":"cpu0","user":100.1,"system":200.1,"idle":300.1,"nice":0.0,"iowait":0.0,"irq":0.0,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0,"stolen":0.0}` + if e != fmt.Sprintf("%v", v) { + t.Errorf("CPUTimesStat string is invalid: %v", v) + } +} + +func TestCpuInfo(t *testing.T) { + v, err := Info() + if err != nil { + t.Errorf("error %v", err) + } + if len(v) == 0 { + t.Errorf("could not get CPU Info") + } + for _, vv := range v { + if vv.ModelName == "" { + t.Errorf("could not get CPU Info: %v", vv) + } + } +} + +func testCPUPercent(t *testing.T, percpu bool) { + numcpu := runtime.NumCPU() + testCount := 3 + + if runtime.GOOS != "windows" { + testCount = 100 + v, err := Percent(time.Millisecond, percpu) + if err != nil { + t.Errorf("error %v", err) + } + // Skip CircleCI which CPU num is different + if os.Getenv("CIRCLECI") != "true" { + if (percpu && len(v) != numcpu) || (!percpu && len(v) != 1) { + t.Fatalf("wrong number of entries from CPUPercent: %v", v) + } + } + } + for i := 0; i < testCount; i++ { + duration := time.Duration(10) * time.Microsecond + v, err := Percent(duration, percpu) + if err != nil { + t.Errorf("error %v", err) + } + for _, percent := range v { + // Check for slightly greater then 100% to account for any rounding issues. + if percent < 0.0 || percent > 100.0001*float64(numcpu) { + t.Fatalf("CPUPercent value is invalid: %f", percent) + } + } + } +} + +func testCPUPercentLastUsed(t *testing.T, percpu bool) { + + numcpu := runtime.NumCPU() + testCount := 10 + + if runtime.GOOS != "windows" { + testCount = 2 + v, err := Percent(time.Millisecond, percpu) + if err != nil { + t.Errorf("error %v", err) + } + // Skip CircleCI which CPU num is different + if os.Getenv("CIRCLECI") != "true" { + if (percpu && len(v) != numcpu) || (!percpu && len(v) != 1) { + t.Fatalf("wrong number of entries from CPUPercent: %v", v) + } + } + } + for i := 0; i < testCount; i++ { + v, err := Percent(0, percpu) + if err != nil { + t.Errorf("error %v", err) + } + time.Sleep(1 * time.Millisecond) + for _, percent := range v { + // Check for slightly greater then 100% to account for any rounding issues. + if percent < 0.0 || percent > 100.0001*float64(numcpu) { + t.Fatalf("CPUPercent value is invalid: %f", percent) + } + } + } + +} + +func TestCPUPercent(t *testing.T) { + testCPUPercent(t, false) +} + +func TestCPUPercentPerCpu(t *testing.T) { + testCPUPercent(t, true) +} + +func TestCPUPercentIntervalZero(t *testing.T) { + testCPUPercentLastUsed(t, false) +} + +func TestCPUPercentIntervalZeroPerCPU(t *testing.T) { + testCPUPercentLastUsed(t, true) +} diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_windows.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_windows.go index b5bf8258f..8aa691cf0 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_windows.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_windows.go @@ -3,6 +3,7 @@ package cpu import ( + "context" "fmt" "unsafe" @@ -45,6 +46,10 @@ type Win32_PerfFormattedData_PerfOS_System struct { // Times returns times stat per cpu and combined for all CPUs func Times(percpu bool) ([]TimesStat, error) { + return TimesWithContext(context.Background(), percpu) +} + +func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { if percpu { return perCPUTimes() } @@ -78,11 +83,14 @@ func Times(percpu bool) ([]TimesStat, error) { } func Info() ([]InfoStat, error) { + return InfoWithContext(context.Background()) +} + +func InfoWithContext(ctx context.Context) ([]InfoStat, error) { var ret []InfoStat var dst []Win32_Processor q := wmi.CreateQuery(&dst, "") - err := wmi.Query(q, &dst) - if err != nil { + if err := common.WMIQueryWithContext(ctx, q, &dst); err != nil { return ret, err } @@ -112,18 +120,34 @@ func Info() ([]InfoStat, error) { // PerfInfo returns the performance counter's instance value for ProcessorInformation. // Name property is the key by which overall, per cpu and per core metric is known. func PerfInfo() ([]Win32_PerfFormattedData_Counters_ProcessorInformation, error) { + return PerfInfoWithContext(context.Background()) +} + +func PerfInfoWithContext(ctx context.Context) ([]Win32_PerfFormattedData_Counters_ProcessorInformation, error) { var ret []Win32_PerfFormattedData_Counters_ProcessorInformation + q := wmi.CreateQuery(&ret, "") - err := wmi.Query(q, &ret) + err := common.WMIQueryWithContext(ctx, q, &ret) + if err != nil { + return []Win32_PerfFormattedData_Counters_ProcessorInformation{}, err + } + return ret, err } // ProcInfo returns processes count and processor queue length in the system. // There is a single queue for processor even on multiprocessors systems. func ProcInfo() ([]Win32_PerfFormattedData_PerfOS_System, error) { + return ProcInfoWithContext(context.Background()) +} + +func ProcInfoWithContext(ctx context.Context) ([]Win32_PerfFormattedData_PerfOS_System, error) { var ret []Win32_PerfFormattedData_PerfOS_System q := wmi.CreateQuery(&ret, "") - err := wmi.Query(q, &ret) + err := common.WMIQueryWithContext(ctx, q, &ret) + if err != nil { + return []Win32_PerfFormattedData_PerfOS_System{}, err + } return ret, err } diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_darwin.go b/vendor/github.com/shirou/gopsutil/disk/disk_darwin.go index 76672c16c..82ffacbd0 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_darwin.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_darwin.go @@ -3,6 +3,7 @@ package disk import ( + "context" "path" "unsafe" @@ -11,6 +12,10 @@ import ( ) func Partitions(all bool) ([]PartitionStat, error) { + return PartitionsWithContext(context.Background(), all) +} + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { var ret []PartitionStat count, err := Getfsstat(nil, MntWait) @@ -88,6 +93,10 @@ func Partitions(all bool) ([]PartitionStat, error) { } func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { + return GetfsstatWithContext(context.Background(), buf, flags) +} + +func GetfsstatWithContext(ctx context.Context, buf []Statfs_t, flags int) (n int, err error) { var _p0 unsafe.Pointer var bufsize uintptr if len(buf) > 0 { diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_darwin_cgo.go b/vendor/github.com/shirou/gopsutil/disk/disk_darwin_cgo.go index f75ac9b28..480e23770 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_darwin_cgo.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_darwin_cgo.go @@ -26,6 +26,7 @@ typedef struct import "C" import ( + "context" "errors" "strings" "unsafe" @@ -34,6 +35,10 @@ import ( ) func IOCounters(names ...string) (map[string]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), names...) +} + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { if C.StartIOCounterFetch() == 0 { return nil, errors.New("Unable to fetch disk list") } diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_darwin_nocgo.go b/vendor/github.com/shirou/gopsutil/disk/disk_darwin_nocgo.go index 60fd7a6ce..fe76d83e5 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_darwin_nocgo.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_darwin_nocgo.go @@ -3,8 +3,16 @@ package disk -import "github.com/shirou/gopsutil/internal/common" +import ( + "context" + + "github.com/shirou/gopsutil/internal/common" +) func IOCounters(names ...string) (map[string]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), names...) +} + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { return nil, common.ErrNotImplementedError } diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_fallback.go b/vendor/github.com/shirou/gopsutil/disk/disk_fallback.go index ae9ffa852..22eb50794 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_fallback.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_fallback.go @@ -2,16 +2,32 @@ package disk -import "github.com/shirou/gopsutil/internal/common" +import ( + "context" + + "github.com/shirou/gopsutil/internal/common" +) func IOCounters(names ...string) (map[string]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), names...) +} + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { return nil, common.ErrNotImplementedError } func Partitions(all bool) ([]PartitionStat, error) { + return PartitionsWithContext(context.Background(), all) +} + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { return []PartitionStat{}, common.ErrNotImplementedError } func Usage(path string) (*UsageStat, error) { + return UsageWithContext(context.Background(), path) +} + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { return nil, common.ErrNotImplementedError } diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_freebsd.go b/vendor/github.com/shirou/gopsutil/disk/disk_freebsd.go index 8cd5aef5b..bfb6580c2 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_freebsd.go @@ -4,6 +4,7 @@ package disk import ( "bytes" + "context" "encoding/binary" "path" "strconv" @@ -15,6 +16,10 @@ import ( ) func Partitions(all bool) ([]PartitionStat, error) { + return PartitionsWithContext(context.Background(), all) +} + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { var ret []PartitionStat // get length @@ -96,6 +101,10 @@ func Partitions(all bool) ([]PartitionStat, error) { } func IOCounters(names ...string) (map[string]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), names...) +} + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { // statinfo->devinfo->devstat // /usr/include/devinfo.h ret := make(map[string]IOCountersStat) @@ -150,6 +159,10 @@ func (b Bintime) Compute() float64 { // Getfsstat is borrowed from pkg/syscall/syscall_freebsd.go // change Statfs_t to Statfs in order to get more information func Getfsstat(buf []Statfs, flags int) (n int, err error) { + return GetfsstatWithContext(context.Background(), buf, flags) +} + +func GetfsstatWithContext(ctx context.Context, buf []Statfs, flags int) (n int, err error) { var _p0 unsafe.Pointer var bufsize uintptr if len(buf) > 0 { diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_linux.go b/vendor/github.com/shirou/gopsutil/disk/disk_linux.go index f31c39115..f5eb5261b 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_linux.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_linux.go @@ -3,8 +3,10 @@ package disk import ( + "context" "fmt" "os/exec" + "path/filepath" "strconv" "strings" @@ -216,6 +218,10 @@ var fsTypeMap = map[int64]string{ // physical devices only (e.g. hard disks, cd-rom drives, USB keys) // and ignore all others (e.g. memory partitions such as /dev/shm) func Partitions(all bool) ([]PartitionStat, error) { + return PartitionsWithContext(context.Background(), all) +} + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { filename := common.HostProc("self/mounts") lines, err := common.ReadLines(filename) if err != nil { @@ -272,6 +278,10 @@ func getFileSystems() ([]string, error) { } func IOCounters(names ...string) (map[string]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), names...) +} + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { filename := common.HostProc("diskstats") lines, err := common.ReadLines(filename) if err != nil { @@ -280,6 +290,11 @@ func IOCounters(names ...string) (map[string]IOCountersStat, error) { ret := make(map[string]IOCountersStat, 0) empty := IOCountersStat{} + // use only basename such as "/dev/sda1" to "sda1" + for i, name := range names { + names[i] = filepath.Base(name) + } + for _, line := range lines { fields := strings.Fields(line) if len(fields) < 14 { @@ -363,6 +378,10 @@ func IOCounters(names ...string) (map[string]IOCountersStat, error) { // GetDiskSerialNumber returns Serial Number of given device or empty string // on error. Name of device is expected, eg. /dev/sda func GetDiskSerialNumber(name string) string { + return GetDiskSerialNumberWithContext(context.Background(), name) +} + +func GetDiskSerialNumberWithContext(ctx context.Context, name string) string { n := fmt.Sprintf("--name=%s", name) udevadm, err := exec.LookPath("/sbin/udevadm") if err != nil { diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_openbsd.go b/vendor/github.com/shirou/gopsutil/disk/disk_openbsd.go index d1705eaf8..0ac752a5a 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_openbsd.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_openbsd.go @@ -4,6 +4,7 @@ package disk import ( "bytes" + "context" "encoding/binary" "path" "unsafe" @@ -13,6 +14,10 @@ import ( ) func Partitions(all bool) ([]PartitionStat, error) { + return PartitionsWithContext(context.Background(), all) +} + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { var ret []PartitionStat // get length @@ -64,9 +69,13 @@ func Partitions(all bool) ([]PartitionStat, error) { } func IOCounters(names ...string) (map[string]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), names...) +} + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { ret := make(map[string]IOCountersStat) - r, err := unix.Sysctl("hw.diskstats") + r, err := unix.SysctlRaw("hw.diskstats") if err != nil { return nil, err } @@ -106,6 +115,10 @@ func IOCounters(names ...string) (map[string]IOCountersStat, error) { // Getfsstat is borrowed from pkg/syscall/syscall_freebsd.go // change Statfs_t to Statfs in order to get more information func Getfsstat(buf []Statfs, flags int) (n int, err error) { + return GetfsstatWithContext(context.Background(), buf, flags) +} + +func GetfsstatWithContext(ctx context.Context, buf []Statfs, flags int) (n int, err error) { var _p0 unsafe.Pointer var bufsize uintptr if len(buf) > 0 { @@ -133,6 +146,10 @@ func parseDiskstats(buf []byte) (Diskstats, error) { } func Usage(path string) (*UsageStat, error) { + return UsageWithContext(context.Background(), path) +} + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { stat := unix.Statfs_t{} err := unix.Statfs(path, &stat) if err != nil { diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_solaris.go b/vendor/github.com/shirou/gopsutil/disk/disk_solaris.go new file mode 100644 index 000000000..c66083577 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/disk/disk_solaris.go @@ -0,0 +1,127 @@ +// +build solaris + +package disk + +import ( + "bufio" + "context" + "fmt" + "math" + "os" + "strings" + + "github.com/shirou/gopsutil/internal/common" + "golang.org/x/sys/unix" +) + +const ( + // _DEFAULT_NUM_MOUNTS is set to `cat /etc/mnttab | wc -l` rounded up to the + // nearest power of two. + _DEFAULT_NUM_MOUNTS = 32 + + // _MNTTAB default place to read mount information + _MNTTAB = "/etc/mnttab" +) + +var ( + // A blacklist of read-only virtual filesystems. Writable filesystems are of + // operational concern and must not be included in this list. + fsTypeBlacklist = map[string]struct{}{ + "ctfs": struct{}{}, + "dev": struct{}{}, + "fd": struct{}{}, + "lofs": struct{}{}, + "lxproc": struct{}{}, + "mntfs": struct{}{}, + "objfs": struct{}{}, + "proc": struct{}{}, + } +) + +func Partitions(all bool) ([]PartitionStat, error) { + return PartitionsWithContext(context.Background(), all) +} + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { + ret := make([]PartitionStat, 0, _DEFAULT_NUM_MOUNTS) + + // Scan mnttab(4) + f, err := os.Open(_MNTTAB) + if err != nil { + } + defer func() { + if err == nil { + err = f.Close() + } else { + f.Close() + } + }() + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + fields := strings.Split(scanner.Text(), "\t") + + if _, found := fsTypeBlacklist[fields[2]]; found { + continue + } + + ret = append(ret, PartitionStat{ + // NOTE(seanc@): Device isn't exactly accurate: from mnttab(4): "The name + // of the resource that has been mounted." Ideally this value would come + // from Statvfs_t.Fsid but I'm leaving it to the caller to traverse + // unix.Statvfs(). + Device: fields[0], + Mountpoint: fields[1], + Fstype: fields[2], + Opts: fields[3], + }) + } + if err := scanner.Err(); err != nil { + return nil, fmt.Errorf("unable to scan %q: %v", _MNTTAB, err) + } + + return ret, err +} + +func IOCounters(names ...string) (map[string]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), names...) +} + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { + return nil, common.ErrNotImplementedError +} + +func Usage(path string) (*UsageStat, error) { + return UsageWithContext(context.Background(), path) +} + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { + statvfs := unix.Statvfs_t{} + if err := unix.Statvfs(path, &statvfs); err != nil { + return nil, fmt.Errorf("unable to call statvfs(2) on %q: %v", path, err) + } + + usageStat := &UsageStat{ + Path: path, + Fstype: common.IntToString(statvfs.Basetype[:]), + Total: statvfs.Blocks * statvfs.Frsize, + Free: statvfs.Bfree * statvfs.Frsize, + Used: (statvfs.Blocks - statvfs.Bfree) * statvfs.Frsize, + + // NOTE: ZFS (and FreeBZSD's UFS2) use dynamic inode/dnode allocation. + // Explicitly return a near-zero value for InodesUsedPercent so that nothing + // attempts to garbage collect based on a lack of available inodes/dnodes. + // Similarly, don't use the zero value to prevent divide-by-zero situations + // and inject a faux near-zero value. Filesystems evolve. Has your + // filesystem evolved? Probably not if you care about the number of + // available inodes. + InodesTotal: 1024.0 * 1024.0, + InodesUsed: 1024.0, + InodesFree: math.MaxUint64, + InodesUsedPercent: (1024.0 / (1024.0 * 1024.0)) * 100.0, + } + + usageStat.UsedPercent = (float64(usageStat.Used) / float64(usageStat.Total)) * 100.0 + + return usageStat, nil +} diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_unix.go b/vendor/github.com/shirou/gopsutil/disk/disk_unix.go index 8520829fa..bafef513d 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_unix.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_unix.go @@ -2,12 +2,20 @@ package disk -import "golang.org/x/sys/unix" +import ( + "context" + + "golang.org/x/sys/unix" +) // Usage returns a file system usage. path is a filessytem path such // as "/", not device file path like "/dev/vda1". If you want to use // a return value of disk.Partitions, use "Mountpoint" not "Device". func Usage(path string) (*UsageStat, error) { + return UsageWithContext(context.Background(), path) +} + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { stat := unix.Statfs_t{} err := unix.Statfs(path, &stat) if err != nil { diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_windows.go b/vendor/github.com/shirou/gopsutil/disk/disk_windows.go index 6cc22a296..326bc1f42 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_windows.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_windows.go @@ -4,9 +4,9 @@ package disk import ( "bytes" + "context" "unsafe" - "github.com/StackExchange/wmi" "github.com/shirou/gopsutil/internal/common" "golang.org/x/sys/windows" ) @@ -36,6 +36,10 @@ type Win32_PerfFormattedData struct { const WaitMSec = 500 func Usage(path string) (*UsageStat, error) { + return UsageWithContext(context.Background(), path) +} + +func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) { ret := &UsageStat{} lpFreeBytesAvailable := int64(0) @@ -64,6 +68,10 @@ func Usage(path string) (*UsageStat, error) { } func Partitions(all bool) ([]PartitionStat, error) { + return PartitionsWithContext(context.Background(), all) +} + +func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) { var ret []PartitionStat lpBuffer := make([]byte, 254) diskret, _, err := procGetLogicalDriveStringsW.Call( @@ -129,10 +137,14 @@ func Partitions(all bool) ([]PartitionStat, error) { } func IOCounters(names ...string) (map[string]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), names...) +} + +func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) { ret := make(map[string]IOCountersStat, 0) var dst []Win32_PerfFormattedData - err := wmi.Query("SELECT * FROM Win32_PerfFormattedData_PerfDisk_LogicalDisk ", &dst) + err := common.WMIQueryWithContext(ctx, "SELECT * FROM Win32_PerfFormattedData_PerfDisk_LogicalDisk", &dst) if err != nil { return ret, err } diff --git a/vendor/github.com/shirou/gopsutil/disk/types_freebsd.go b/vendor/github.com/shirou/gopsutil/disk/types_freebsd.go deleted file mode 100644 index dd6ddc4f7..000000000 --- a/vendor/github.com/shirou/gopsutil/disk/types_freebsd.go +++ /dev/null @@ -1,88 +0,0 @@ -// +build ignore -// Hand writing: _Ctype_struct___0 - -/* -Input to cgo -godefs. - -*/ - -package disk - -/* -#include -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - -// because statinfo has long double snap_time, redefine with changing long long -struct statinfo2 { - long cp_time[CPUSTATES]; - long tk_nin; - long tk_nout; - struct devinfo *dinfo; - long long snap_time; -}; -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong - sizeofLongDouble = C.sizeof_longlong - - DEVSTAT_NO_DATA = 0x00 - DEVSTAT_READ = 0x01 - DEVSTAT_WRITE = 0x02 - DEVSTAT_FREE = 0x03 - - // from sys/mount.h - MNT_RDONLY = 0x00000001 /* read only filesystem */ - MNT_SYNCHRONOUS = 0x00000002 /* filesystem written synchronously */ - MNT_NOEXEC = 0x00000004 /* can't exec from filesystem */ - MNT_NOSUID = 0x00000008 /* don't honor setuid bits on fs */ - MNT_UNION = 0x00000020 /* union with underlying filesystem */ - MNT_ASYNC = 0x00000040 /* filesystem written asynchronously */ - MNT_SUIDDIR = 0x00100000 /* special handling of SUID on dirs */ - MNT_SOFTDEP = 0x00200000 /* soft updates being done */ - MNT_NOSYMFOLLOW = 0x00400000 /* do not follow symlinks */ - MNT_GJOURNAL = 0x02000000 /* GEOM journal support enabled */ - MNT_MULTILABEL = 0x04000000 /* MAC support for individual objects */ - MNT_ACLS = 0x08000000 /* ACL support enabled */ - MNT_NOATIME = 0x10000000 /* disable update of file access time */ - MNT_NOCLUSTERR = 0x40000000 /* disable cluster read */ - MNT_NOCLUSTERW = 0x80000000 /* disable cluster write */ - MNT_NFS4ACLS = 0x00000010 - - MNT_WAIT = 1 /* synchronously wait for I/O to complete */ - MNT_NOWAIT = 2 /* start all I/O, but do not wait for it */ - MNT_LAZY = 3 /* push data not written by filesystem syncer */ - MNT_SUSPEND = 4 /* Suspend file system after sync */ -) - -const ( - sizeOfDevstat = C.sizeof_struct_devstat -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong - _C_long_double C.longlong -) - -type Statfs C.struct_statfs -type Fsid C.struct_fsid - -type Devstat C.struct_devstat -type Bintime C.struct_bintime diff --git a/vendor/github.com/shirou/gopsutil/disk/types_openbsd.go b/vendor/github.com/shirou/gopsutil/disk/types_openbsd.go deleted file mode 100644 index 1e3ddef5c..000000000 --- a/vendor/github.com/shirou/gopsutil/disk/types_openbsd.go +++ /dev/null @@ -1,70 +0,0 @@ -// +build ignore -// Hand writing: _Ctype_struct___0 - -/* -Input to cgo -godefs. -*/ - -package disk - -/* -#include -#include -#include - -enum { - sizeofPtr = sizeof(void*), -}; - -*/ -import "C" - -// Machine characteristics; for internal use. - -const ( - sizeofPtr = C.sizeofPtr - sizeofShort = C.sizeof_short - sizeofInt = C.sizeof_int - sizeofLong = C.sizeof_long - sizeofLongLong = C.sizeof_longlong - sizeofLongDouble = C.sizeof_longlong - - DEVSTAT_NO_DATA = 0x00 - DEVSTAT_READ = 0x01 - DEVSTAT_WRITE = 0x02 - DEVSTAT_FREE = 0x03 - - // from sys/mount.h - MNT_RDONLY = 0x00000001 /* read only filesystem */ - MNT_SYNCHRONOUS = 0x00000002 /* filesystem written synchronously */ - MNT_NOEXEC = 0x00000004 /* can't exec from filesystem */ - MNT_NOSUID = 0x00000008 /* don't honor setuid bits on fs */ - MNT_NODEV = 0x00000010 /* don't interpret special files */ - MNT_ASYNC = 0x00000040 /* filesystem written asynchronously */ - - MNT_WAIT = 1 /* synchronously wait for I/O to complete */ - MNT_NOWAIT = 2 /* start all I/O, but do not wait for it */ - MNT_LAZY = 3 /* push data not written by filesystem syncer */ -) - -const ( - sizeOfDiskstats = C.sizeof_struct_diskstats -) - -// Basic types - -type ( - _C_short C.short - _C_int C.int - _C_long C.long - _C_long_long C.longlong - _C_long_double C.longlong -) - -type Statfs C.struct_statfs -type Diskstats C.struct_diskstats -type Fsid C.fsid_t -type Timeval C.struct_timeval - -type Diskstat C.struct_diskstat -type Bintime C.struct_bintime diff --git a/vendor/github.com/shirou/gopsutil/host/host_darwin.go b/vendor/github.com/shirou/gopsutil/host/host_darwin.go index 0ea6d5149..c82d99070 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_darwin.go +++ b/vendor/github.com/shirou/gopsutil/host/host_darwin.go @@ -4,6 +4,7 @@ package host import ( "bytes" + "context" "encoding/binary" "io/ioutil" "os" @@ -23,6 +24,10 @@ import ( 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", @@ -77,6 +82,10 @@ func Info() (*InfoStat, error) { 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 { return t, nil @@ -102,6 +111,10 @@ func uptime(boot uint64) uint64 { } func Uptime() (uint64, error) { + return UptimeWithContext(context.Background()) +} + +func UptimeWithContext(ctx context.Context) (uint64, error) { boot, err := BootTime() if err != nil { return 0, err @@ -110,6 +123,10 @@ func Uptime() (uint64, error) { } func Users() ([]UserStat, error) { + return UsersWithContext(context.Background()) +} + +func UsersWithContext(ctx context.Context) ([]UserStat, error) { utmpfile := "/var/run/utmpx" var ret []UserStat @@ -154,6 +171,10 @@ func Users() ([]UserStat, error) { } func PlatformInformation() (string, string, string, error) { + return PlatformInformationWithContext(context.Background()) +} + +func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) { platform := "" family := "" pver := "" @@ -181,10 +202,18 @@ func PlatformInformation() (string, string, string, error) { } 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() return version, err } diff --git a/vendor/github.com/shirou/gopsutil/host/host_darwin_cgo.go b/vendor/github.com/shirou/gopsutil/host/host_darwin_cgo.go index be5e18b88..f0a437016 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_darwin_cgo.go +++ b/vendor/github.com/shirou/gopsutil/host/host_darwin_cgo.go @@ -6,8 +6,13 @@ package host // #cgo LDFLAGS: -framework IOKit // #include "include/smc.c" 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, C.AMBIENT_AIR_1, diff --git a/vendor/github.com/shirou/gopsutil/host/host_darwin_nocgo.go b/vendor/github.com/shirou/gopsutil/host/host_darwin_nocgo.go index 0205888c3..7869f8c59 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_darwin_nocgo.go +++ b/vendor/github.com/shirou/gopsutil/host/host_darwin_nocgo.go @@ -3,8 +3,16 @@ package host -import "github.com/shirou/gopsutil/internal/common" +import ( + "context" + + "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 } diff --git a/vendor/github.com/shirou/gopsutil/host/host_fallback.go b/vendor/github.com/shirou/gopsutil/host/host_fallback.go index 173f58c6a..f6537a9ec 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_fallback.go +++ b/vendor/github.com/shirou/gopsutil/host/host_fallback.go @@ -2,28 +2,56 @@ package host -import "github.com/shirou/gopsutil/internal/common" +import ( + "context" + + "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 BootTime() (uint64, error) { + return BootTimeWithContext(context.Background()) +} + +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 } diff --git a/vendor/github.com/shirou/gopsutil/host/host_freebsd.go b/vendor/github.com/shirou/gopsutil/host/host_freebsd.go index 6b2962cf6..2f51c31c9 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/host/host_freebsd.go @@ -4,19 +4,21 @@ package host import ( "bytes" + "context" "encoding/binary" "io/ioutil" "os" "os/exec" "runtime" - "strconv" "strings" "sync/atomic" + "syscall" "time" "unsafe" "github.com/shirou/gopsutil/internal/common" "github.com/shirou/gopsutil/process" + "golang.org/x/sys/unix" ) const ( @@ -26,6 +28,10 @@ const ( ) func Info() (*InfoStat, error) { + return InfoWithContext(context.Background()) +} + +func InfoWithContext(ctx context.Context) (*InfoStat, error) { ret := &InfoStat{ OS: runtime.GOOS, PlatformFamily: "freebsd", @@ -61,9 +67,9 @@ func Info() (*InfoStat, error) { ret.Procs = uint64(len(procs)) } - values, err := common.DoSysctrl("kern.hostuuid") - if err == nil && len(values) == 1 && values[0] != "" { - ret.HostID = strings.ToLower(values[0]) + hostid, err := unix.Sysctl("kern.hostuuid") + if err == nil && hostid != "" { + ret.HostID = strings.ToLower(hostid) } return ret, nil @@ -73,23 +79,21 @@ func Info() (*InfoStat, error) { 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 { return t, nil } - values, err := common.DoSysctrl("kern.boottime") + buf, err := unix.SysctlRaw("kern.boottime") if err != nil { return 0, err } - // ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014 - v := strings.Replace(values[2], ",", "", 1) - boottime, err := strconv.ParseUint(v, 10, 64) - if err != nil { - return 0, err - } - t = uint64(boottime) - atomic.StoreUint64(&cachedBootTime, t) + tv := *(*syscall.Timeval)(unsafe.Pointer((&buf[0]))) + atomic.StoreUint64(&cachedBootTime, uint64(tv.Sec)) return t, nil } @@ -99,6 +103,10 @@ func uptime(boot uint64) uint64 { } func Uptime() (uint64, error) { + return UptimeWithContext(context.Background()) +} + +func UptimeWithContext(ctx context.Context) (uint64, error) { boot, err := BootTime() if err != nil { return 0, err @@ -107,6 +115,10 @@ func Uptime() (uint64, error) { } func Users() ([]UserStat, error) { + return UsersWithContext(context.Background()) +} + +func UsersWithContext(ctx context.Context) ([]UserStat, error) { utmpfile := "/var/run/utx.active" if !common.PathExists(utmpfile) { utmpfile = "/var/run/utmp" // before 9.0 @@ -152,6 +164,10 @@ func Users() ([]UserStat, error) { } func PlatformInformation() (string, string, string, error) { + return PlatformInformationWithContext(context.Background()) +} + +func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) { platform := "" family := "" version := "" @@ -174,6 +190,10 @@ func PlatformInformation() (string, string, string, error) { } func Virtualization() (string, string, error) { + return VirtualizationWithContext(context.Background()) +} + +func VirtualizationWithContext(ctx context.Context) (string, string, error) { return "", "", common.ErrNotImplementedError } @@ -217,10 +237,18 @@ func getUsersFromUtmp(utmpfile string) ([]UserStat, error) { } 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() return version, err } diff --git a/vendor/github.com/shirou/gopsutil/host/host_linux.go b/vendor/github.com/shirou/gopsutil/host/host_linux.go index b84000cba..53242584b 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_linux.go +++ b/vendor/github.com/shirou/gopsutil/host/host_linux.go @@ -4,6 +4,7 @@ package host import ( "bytes" + "context" "encoding/binary" "fmt" "io/ioutil" @@ -31,6 +32,10 @@ type LSB struct { const USER_PROCESS = 7 func Info() (*InfoStat, error) { + return InfoWithContext(context.Background()) +} + +func InfoWithContext(ctx context.Context) (*InfoStat, error) { ret := &InfoStat{ OS: runtime.GOOS, } @@ -91,11 +96,26 @@ var cachedBootTime uint64 // BootTime returns the system boot time expressed in seconds since the epoch. func BootTime() (uint64, error) { + return BootTimeWithContext(context.Background()) +} + +func BootTimeWithContext(ctx context.Context) (uint64, error) { t := atomic.LoadUint64(&cachedBootTime) if t != 0 { return t, nil } - filename := common.HostProc("stat") + + system, role, err := Virtualization() + if err != nil { + return 0, err + } + statFile := "stat" + if system == "lxc" && role == "guest" { + // if lxc, /proc/uptime is used. + statFile = "uptime" + } + + filename := common.HostProc(statFile) lines, err := common.ReadLines(filename) if err != nil { return 0, err @@ -124,6 +144,10 @@ func uptime(boot uint64) uint64 { } func Uptime() (uint64, error) { + return UptimeWithContext(context.Background()) +} + +func UptimeWithContext(ctx context.Context) (uint64, error) { boot, err := BootTime() if err != nil { return 0, err @@ -132,7 +156,11 @@ func Uptime() (uint64, error) { } func Users() ([]UserStat, error) { - utmpfile := "/var/run/utmp" + return UsersWithContext(context.Background()) +} + +func UsersWithContext(ctx context.Context) ([]UserStat, error) { + utmpfile := common.HostVar("run/utmp") file, err := os.Open(utmpfile) if err != nil { @@ -249,6 +277,10 @@ func getLSB() (*LSB, error) { } 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 { @@ -371,6 +403,10 @@ func PlatformInformation() (platform string, family string, version string, err } func KernelVersion() (version string, err error) { + return KernelVersionWithContext(context.Background()) +} + +func KernelVersionWithContext(ctx context.Context) (version string, err error) { filename := common.HostProc("sys/kernel/osrelease") if common.PathExists(filename) { contents, err := common.ReadLines(filename) @@ -430,6 +466,10 @@ func getSusePlatform(contents []string) string { } func Virtualization() (string, string, error) { + return VirtualizationWithContext(context.Background()) +} + +func VirtualizationWithContext(ctx context.Context) (string, string, error) { var system string var role string @@ -533,6 +573,10 @@ func Virtualization() (string, string, error) { } 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*_*")) if err != nil { @@ -541,28 +585,52 @@ func SensorsTemperatures() ([]TemperatureStat, error) { if len(files) == 0 { // CentOS has an intermediate /device directory: // https://github.com/giampaolo/psutil/issues/971 - files, err = filepath.Glob(common.HostSys("/class/hwmon/hwmon*/temp*_*")) + files, err = filepath.Glob(common.HostSys("/class/hwmon/hwmon*/device/temp*_*")) if err != nil { return temperatures, err } } - for _, match := range files { - match = strings.Split(match, "_")[0] - name, err := ioutil.ReadFile(filepath.Join(filepath.Dir(match), "name")) + // example directory + // device/ temp1_crit_alarm temp2_crit_alarm temp3_crit_alarm temp4_crit_alarm temp5_crit_alarm temp6_crit_alarm temp7_crit_alarm + // name temp1_input temp2_input temp3_input temp4_input temp5_input temp6_input temp7_input + // power/ temp1_label temp2_label temp3_label temp4_label temp5_label temp6_label temp7_label + // subsystem/ temp1_max temp2_max temp3_max temp4_max temp5_max temp6_max temp7_max + // temp1_crit temp2_crit temp3_crit temp4_crit temp5_crit temp6_crit temp7_crit uevent + for _, file := range files { + filename := strings.Split(filepath.Base(file), "_") + if filename[1] == "label" { + // Do not try to read the temperature of the label file + continue + } + + // Get the label of the temperature you are reading + var label string + c, _ := ioutil.ReadFile(filepath.Join(filepath.Dir(file), filename[0]+"_label")) + if c != nil { + //format the label from "Core 0" to "core0_" + label = fmt.Sprintf("%s_", strings.Join(strings.Split(strings.TrimSpace(strings.ToLower(string(c))), " "), "")) + } + + // Get the name of the tempearture you are reading + name, err := ioutil.ReadFile(filepath.Join(filepath.Dir(file), "name")) if err != nil { return temperatures, err } - current, err := ioutil.ReadFile(match + "_input") + + // Get the temperature reading + current, err := ioutil.ReadFile(file) if err != nil { return temperatures, err } - temperature, err := strconv.ParseFloat(string(current), 64) + temperature, err := strconv.ParseFloat(strings.TrimSpace(string(current)), 64) if err != nil { continue } + + tempName := strings.TrimSpace(strings.ToLower(string(strings.Join(filename[1:], "")))) temperatures = append(temperatures, TemperatureStat{ - SensorKey: string(name), + SensorKey: fmt.Sprintf("%s_%s%s", strings.TrimSpace(string(name)), label, tempName), Temperature: temperature / 1000.0, }) } diff --git a/vendor/github.com/shirou/gopsutil/host/host_linux_mips.go b/vendor/github.com/shirou/gopsutil/host/host_linux_mips.go new file mode 100644 index 000000000..b0fca0939 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/host/host_linux_mips.go @@ -0,0 +1,43 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types_linux.go + +package host + +const ( + sizeofPtr = 0x4 + sizeofShort = 0x2 + sizeofInt = 0x4 + sizeofLong = 0x4 + sizeofLongLong = 0x8 + sizeOfUtmp = 0x180 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int32 + _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__unused [20]int8 +} +type exit_status struct { + Termination int16 + Exit int16 +} +type timeval struct { + Sec int32 + Usec int32 +} diff --git a/vendor/github.com/shirou/gopsutil/host/host_linux_mipsle.go b/vendor/github.com/shirou/gopsutil/host/host_linux_mipsle.go new file mode 100644 index 000000000..b0fca0939 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/host/host_linux_mipsle.go @@ -0,0 +1,43 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types_linux.go + +package host + +const ( + sizeofPtr = 0x4 + sizeofShort = 0x2 + sizeofInt = 0x4 + sizeofLong = 0x4 + sizeofLongLong = 0x8 + sizeOfUtmp = 0x180 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int32 + _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__unused [20]int8 +} +type exit_status struct { + Termination int16 + Exit int16 +} +type timeval struct { + Sec int32 + Usec int32 +} diff --git a/vendor/github.com/shirou/gopsutil/host/host_linux_test.go b/vendor/github.com/shirou/gopsutil/host/host_linux_test.go new file mode 100644 index 000000000..7808eee3d --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/host/host_linux_test.go @@ -0,0 +1,61 @@ +// +build linux + +package host + +import ( + "testing" +) + +func TestGetRedhatishVersion(t *testing.T) { + var ret string + c := []string{"Rawhide"} + ret = getRedhatishVersion(c) + if ret != "rawhide" { + t.Errorf("Could not get version rawhide: %v", ret) + } + + c = []string{"Fedora release 15 (Lovelock)"} + ret = getRedhatishVersion(c) + if ret != "15" { + t.Errorf("Could not get version fedora: %v", ret) + } + + c = []string{"Enterprise Linux Server release 5.5 (Carthage)"} + ret = getRedhatishVersion(c) + if ret != "5.5" { + t.Errorf("Could not get version redhat enterprise: %v", ret) + } + + c = []string{""} + ret = getRedhatishVersion(c) + if ret != "" { + t.Errorf("Could not get version with no value: %v", ret) + } +} + +func TestGetRedhatishPlatform(t *testing.T) { + var ret string + c := []string{"red hat"} + ret = getRedhatishPlatform(c) + if ret != "redhat" { + t.Errorf("Could not get platform redhat: %v", ret) + } + + c = []string{"Fedora release 15 (Lovelock)"} + ret = getRedhatishPlatform(c) + if ret != "fedora" { + t.Errorf("Could not get platform fedora: %v", ret) + } + + c = []string{"Enterprise Linux Server release 5.5 (Carthage)"} + ret = getRedhatishPlatform(c) + if ret != "enterprise" { + t.Errorf("Could not get platform redhat enterprise: %v", ret) + } + + c = []string{""} + ret = getRedhatishPlatform(c) + if ret != "" { + t.Errorf("Could not get platform with no value: %v", ret) + } +} diff --git a/vendor/github.com/shirou/gopsutil/host/host_openbsd.go b/vendor/github.com/shirou/gopsutil/host/host_openbsd.go index 13000b52d..83c2f7df8 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_openbsd.go +++ b/vendor/github.com/shirou/gopsutil/host/host_openbsd.go @@ -4,6 +4,7 @@ package host import ( "bytes" + "context" "encoding/binary" "io/ioutil" "os" @@ -25,6 +26,10 @@ const ( ) func Info() (*InfoStat, error) { + return InfoWithContext(context.Background()) +} + +func InfoWithContext(ctx context.Context) (*InfoStat, error) { ret := &InfoStat{ OS: runtime.GOOS, PlatformFamily: "openbsd", @@ -62,6 +67,10 @@ func Info() (*InfoStat, error) { } func BootTime() (uint64, error) { + return BootTimeWithContext(context.Background()) +} + +func BootTimeWithContext(ctx context.Context) (uint64, error) { val, err := common.DoSysctrl("kern.boottime") if err != nil { return 0, err @@ -80,6 +89,10 @@ func uptime(boot uint64) uint64 { } func Uptime() (uint64, error) { + return UptimeWithContext(context.Background()) +} + +func UptimeWithContext(ctx context.Context) (uint64, error) { boot, err := BootTime() if err != nil { return 0, err @@ -88,6 +101,10 @@ func Uptime() (uint64, error) { } func PlatformInformation() (string, string, string, error) { + return PlatformInformationWithContext(context.Background()) +} + +func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) { platform := "" family := "" version := "" @@ -110,10 +127,18 @@ func PlatformInformation() (string, string, string, error) { } 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" file, err := os.Open(utmpfile) @@ -153,10 +178,18 @@ func Users() ([]UserStat, error) { } 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() return version, err } diff --git a/vendor/github.com/shirou/gopsutil/host/host_solaris.go b/vendor/github.com/shirou/gopsutil/host/host_solaris.go index 24461fd93..2560c0687 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_solaris.go +++ b/vendor/github.com/shirou/gopsutil/host/host_solaris.go @@ -3,6 +3,7 @@ package host import ( "bufio" "bytes" + "context" "fmt" "io/ioutil" "os" @@ -17,6 +18,10 @@ import ( ) func Info() (*InfoStat, error) { + return InfoWithContext(context.Background()) +} + +func InfoWithContext(ctx context.Context) (*InfoStat, error) { result := &InfoStat{ OS: runtime.GOOS, } @@ -142,6 +147,10 @@ func Info() (*InfoStat, error) { 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("/usr/bin/kstat") if err != nil { return 0, err @@ -161,6 +170,10 @@ func BootTime() (uint64, error) { } func Uptime() (uint64, error) { + return UptimeWithContext(context.Background()) +} + +func UptimeWithContext(ctx context.Context) (uint64, error) { bootTime, err := BootTime() if err != nil { return 0, err @@ -173,18 +186,34 @@ func uptimeSince(since uint64) uint64 { } func Users() ([]UserStat, error) { + return UsersWithContext(context.Background()) +} + +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()) +} + +func KernelVersionWithContext(ctx context.Context) (string, error) { // Parse versions from output of `uname(1)` uname, err := exec.LookPath("/usr/bin/uname") if err != nil { diff --git a/vendor/github.com/shirou/gopsutil/host/host_test.go b/vendor/github.com/shirou/gopsutil/host/host_test.go new file mode 100644 index 000000000..b4f3e4095 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/host/host_test.go @@ -0,0 +1,150 @@ +package host + +import ( + "fmt" + "os" + "testing" +) + +func TestHostInfo(t *testing.T) { + v, err := Info() + if err != nil { + t.Errorf("error %v", err) + } + empty := &InfoStat{} + if v == empty { + t.Errorf("Could not get hostinfo %v", v) + } + if v.Procs == 0 { + t.Errorf("Could not determine the number of host processes") + } +} + +func TestUptime(t *testing.T) { + if os.Getenv("CIRCLECI") == "true" { + t.Skip("Skip CI") + } + + v, err := Uptime() + if err != nil { + t.Errorf("error %v", err) + } + if v == 0 { + t.Errorf("Could not get up time %v", v) + } +} + +func TestBoot_time(t *testing.T) { + if os.Getenv("CIRCLECI") == "true" { + t.Skip("Skip CI") + } + v, err := BootTime() + if err != nil { + t.Errorf("error %v", err) + } + if v == 0 { + t.Errorf("Could not get boot time %v", v) + } + if v < 946652400 { + t.Errorf("Invalid Boottime, older than 2000-01-01") + } + t.Logf("first boot time: %d", v) + + v2, err := BootTime() + if v != v2 { + t.Errorf("cached boot time is different") + } + t.Logf("second boot time: %d", v2) +} + +func TestUsers(t *testing.T) { + v, err := Users() + if err != nil { + t.Errorf("error %v", err) + } + empty := UserStat{} + if len(v) == 0 { + t.Fatal("Users is empty") + } + for _, u := range v { + if u == empty { + t.Errorf("Could not Users %v", v) + } + } +} + +func TestHostInfoStat_String(t *testing.T) { + v := InfoStat{ + Hostname: "test", + Uptime: 3000, + Procs: 100, + OS: "linux", + Platform: "ubuntu", + BootTime: 1447040000, + HostID: "edfd25ff-3c9c-b1a4-e660-bd826495ad35", + } + e := `{"hostname":"test","uptime":3000,"bootTime":1447040000,"procs":100,"os":"linux","platform":"ubuntu","platformFamily":"","platformVersion":"","kernelVersion":"","virtualizationSystem":"","virtualizationRole":"","hostid":"edfd25ff-3c9c-b1a4-e660-bd826495ad35"}` + if e != fmt.Sprintf("%v", v) { + t.Errorf("HostInfoStat string is invalid: %v", v) + } +} + +func TestUserStat_String(t *testing.T) { + v := UserStat{ + User: "user", + Terminal: "term", + Host: "host", + Started: 100, + } + e := `{"user":"user","terminal":"term","host":"host","started":100}` + if e != fmt.Sprintf("%v", v) { + t.Errorf("UserStat string is invalid: %v", v) + } +} + +func TestHostGuid(t *testing.T) { + hi, err := Info() + if err != nil { + t.Error(err) + } + if hi.HostID == "" { + t.Error("Host id is empty") + } else { + t.Logf("Host id value: %v", hi.HostID) + } +} + +func TestTemperatureStat_String(t *testing.T) { + v := TemperatureStat{ + SensorKey: "CPU", + Temperature: 1.1, + } + s := `{"sensorKey":"CPU","sensorTemperature":1.1}` + if s != fmt.Sprintf("%v", v) { + t.Errorf("TemperatureStat string is invalid") + } +} + +func TestVirtualization(t *testing.T) { + system, role, err := Virtualization() + if err != nil { + t.Errorf("Virtualization() failed, %v", err) + } + if system == "" || role == "" { + t.Errorf("Virtualization() retuns empty system or role: %s, %s", system, role) + } + + t.Logf("Virtualization(): %s, %s", system, role) +} + +func TestKernelVersion(t *testing.T) { + version, err := KernelVersion() + if err != nil { + t.Errorf("KernelVersion() failed, %v", err) + } + if version == "" { + t.Errorf("KernelVersion() retuns empty: %s", version) + } + + t.Logf("KernelVersion(): %s", version) +} diff --git a/vendor/github.com/shirou/gopsutil/host/host_windows.go b/vendor/github.com/shirou/gopsutil/host/host_windows.go index 98943021b..7897319ad 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_windows.go +++ b/vendor/github.com/shirou/gopsutil/host/host_windows.go @@ -3,6 +3,7 @@ package host import ( + "context" "fmt" "os" "runtime" @@ -31,6 +32,10 @@ type Win32_OperatingSystem struct { } func Info() (*InfoStat, error) { + return InfoWithContext(context.Background()) +} + +func InfoWithContext(ctx context.Context) (*InfoStat, error) { ret := &InfoStat{ OS: runtime.GOOS, } @@ -43,7 +48,7 @@ func Info() (*InfoStat, error) { } { - platform, family, version, err := PlatformInformation() + platform, family, version, err := PlatformInformationWithContext(ctx) if err == nil { ret.Platform = platform ret.PlatformFamily = family @@ -107,9 +112,13 @@ func getMachineGuid() (string, error) { } func GetOSInfo() (Win32_OperatingSystem, error) { + return GetOSInfoWithContext(context.Background()) +} + +func GetOSInfoWithContext(ctx context.Context) (Win32_OperatingSystem, error) { var dst []Win32_OperatingSystem q := wmi.CreateQuery(&dst, "") - err := wmi.Query(q, &dst) + err := common.WMIQueryWithContext(ctx, q, &dst) if err != nil { return Win32_OperatingSystem{}, err } @@ -120,8 +129,12 @@ func GetOSInfo() (Win32_OperatingSystem, error) { } func Uptime() (uint64, error) { + return UptimeWithContext(context.Background()) +} + +func UptimeWithContext(ctx context.Context) (uint64, error) { if osInfo == nil { - _, err := GetOSInfo() + _, err := GetOSInfoWithContext(ctx) if err != nil { return 0, err } @@ -139,6 +152,10 @@ func bootTime(up uint64) uint64 { 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 { return t, nil @@ -153,8 +170,12 @@ func BootTime() (uint64, error) { } 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) { if osInfo == nil { - _, err = GetOSInfo() + _, err = GetOSInfoWithContext(ctx) if err != nil { return } @@ -180,20 +201,36 @@ func PlatformInformation() (platform string, family string, version string, err } func Users() ([]UserStat, error) { + return UsersWithContext(context.Background()) +} + +func UsersWithContext(ctx context.Context) ([]UserStat, error) { var ret []UserStat return ret, nil } 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()) +} + +func KernelVersionWithContext(ctx context.Context) (string, error) { _, _, version, err := PlatformInformation() return version, err } diff --git a/vendor/github.com/shirou/gopsutil/internal/common/common.go b/vendor/github.com/shirou/gopsutil/internal/common/common.go index 1ef9e2741..fcee6be85 100644 --- a/vendor/github.com/shirou/gopsutil/internal/common/common.go +++ b/vendor/github.com/shirou/gopsutil/internal/common/common.go @@ -316,6 +316,10 @@ func HostEtc(combineWith ...string) string { return GetEnv("HOST_ETC", "/etc", combineWith...) } +func HostVar(combineWith ...string) string { + return GetEnv("HOST_VAR", "/var", combineWith...) +} + // https://gist.github.com/kylelemons/1525278 func Pipeline(cmds ...*exec.Cmd) ([]byte, []byte, error) { // Require at least one command diff --git a/vendor/github.com/shirou/gopsutil/internal/common/common_test.go b/vendor/github.com/shirou/gopsutil/internal/common/common_test.go new file mode 100644 index 000000000..cd3338884 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/internal/common/common_test.go @@ -0,0 +1,133 @@ +package common + +import ( + "fmt" + "os" + "reflect" + "runtime" + "strings" + "testing" +) + +func TestReadlines(t *testing.T) { + ret, err := ReadLines("common_test.go") + if err != nil { + t.Error(err) + } + if !strings.Contains(ret[0], "package common") { + t.Error("could not read correctly") + } +} + +func TestReadLinesOffsetN(t *testing.T) { + ret, err := ReadLinesOffsetN("common_test.go", 2, 1) + if err != nil { + t.Error(err) + } + fmt.Println(ret[0]) + if !strings.Contains(ret[0], `import (`) { + t.Error("could not read correctly") + } +} + +func TestIntToString(t *testing.T) { + src := []int8{65, 66, 67} + dst := IntToString(src) + if dst != "ABC" { + t.Error("could not convert") + } +} +func TestByteToString(t *testing.T) { + src := []byte{65, 66, 67} + dst := ByteToString(src) + if dst != "ABC" { + t.Error("could not convert") + } + + src = []byte{0, 65, 66, 67} + dst = ByteToString(src) + if dst != "ABC" { + t.Error("could not convert") + } +} + +func TestmustParseInt32(t *testing.T) { + ret := mustParseInt32("11111") + if ret != int32(11111) { + t.Error("could not parse") + } +} +func TestmustParseUint64(t *testing.T) { + ret := mustParseUint64("11111") + if ret != uint64(11111) { + t.Error("could not parse") + } +} +func TestmustParseFloat64(t *testing.T) { + ret := mustParseFloat64("11111.11") + if ret != float64(11111.11) { + t.Error("could not parse") + } + ret = mustParseFloat64("11111") + if ret != float64(11111) { + t.Error("could not parse") + } +} +func TestStringsContains(t *testing.T) { + target, err := ReadLines("common_test.go") + if err != nil { + t.Error(err) + } + if !StringsContains(target, "func TestStringsContains(t *testing.T) {") { + t.Error("cloud not test correctly") + } +} + +func TestPathExists(t *testing.T) { + if !PathExists("common_test.go") { + t.Error("exists but return not exists") + } + if PathExists("should_not_exists.go") { + t.Error("not exists but return exists") + } +} + +func TestHostEtc(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("windows doesn't have etc") + } + p := HostEtc("mtab") + if p != "/etc/mtab" { + t.Errorf("invalid HostEtc, %s", p) + } +} + +func TestGetSysctrlEnv(t *testing.T) { + // Append case + env := getSysctrlEnv([]string{"FOO=bar"}) + if !reflect.DeepEqual(env, []string{"FOO=bar", "LC_ALL=C"}) { + t.Errorf("unexpected append result from getSysctrlEnv: %q", env) + } + + // Replace case + env = getSysctrlEnv([]string{"FOO=bar", "LC_ALL=en_US.UTF-8"}) + if !reflect.DeepEqual(env, []string{"FOO=bar", "LC_ALL=C"}) { + t.Errorf("unexpected replace result from getSysctrlEnv: %q", env) + } + + // Test against real env + env = getSysctrlEnv(os.Environ()) + found := false + for _, v := range env { + if v == "LC_ALL=C" { + found = true + continue + } + if strings.HasPrefix(v, "LC_ALL") { + t.Fatalf("unexpected LC_ALL value: %q", v) + } + } + if !found { + t.Errorf("unexpected real result from getSysctrlEnv: %q", env) + } +} diff --git a/vendor/github.com/shirou/gopsutil/internal/common/common_windows.go b/vendor/github.com/shirou/gopsutil/internal/common/common_windows.go index 10fc37199..b02c5cf24 100644 --- a/vendor/github.com/shirou/gopsutil/internal/common/common_windows.go +++ b/vendor/github.com/shirou/gopsutil/internal/common/common_windows.go @@ -3,8 +3,10 @@ package common import ( + "context" "unsafe" + "github.com/StackExchange/wmi" "golang.org/x/sys/windows" ) @@ -48,6 +50,7 @@ var ( Modkernel32 = windows.NewLazyDLL("kernel32.dll") ModNt = windows.NewLazyDLL("ntdll.dll") ModPdh = windows.NewLazyDLL("pdh.dll") + ModPsapi = windows.NewLazyDLL("psapi.dll") ProcGetSystemTimes = Modkernel32.NewProc("GetSystemTimes") ProcNtQuerySystemInformation = ModNt.NewProc("NtQuerySystemInformation") @@ -109,3 +112,24 @@ func CreateCounter(query windows.Handle, pname, cname string) (*CounterInfo, err Counter: counter, }, nil } + +// WMIQueryWithContext - wraps wmi.Query with a timed-out context to avoid hanging +func WMIQueryWithContext(ctx context.Context, query string, dst interface{}, connectServerArgs ...interface{}) error { + if _, ok := ctx.Deadline(); !ok { + ctxTimeout, cancel := context.WithTimeout(ctx, Timeout) + defer cancel() + ctx = ctxTimeout + } + + errChan := make(chan error, 1) + go func() { + errChan <- wmi.Query(query, dst, connectServerArgs...) + }() + + select { + case <-ctx.Done(): + return ctx.Err() + case err := <-errChan: + return err + } +} diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_darwin.go b/vendor/github.com/shirou/gopsutil/mem/mem_darwin.go index fde000e63..3e259a00a 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_darwin.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_darwin.go @@ -3,6 +3,7 @@ package mem import ( + "context" "encoding/binary" "strconv" "strings" @@ -28,6 +29,10 @@ func getHwMemsize() (uint64, error) { // SwapMemory returns swapinfo. func SwapMemory() (*SwapMemoryStat, error) { + return SwapMemoryWithContext(context.Background()) +} + +func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { var ret *SwapMemoryStat swapUsage, err := common.DoSysctrl("vm.swapusage") diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_darwin_cgo.go b/vendor/github.com/shirou/gopsutil/mem/mem_darwin_cgo.go index 4b5a6b9e3..389f8cdf9 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_darwin_cgo.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_darwin_cgo.go @@ -9,6 +9,7 @@ package mem import "C" import ( + "context" "fmt" "unsafe" @@ -17,6 +18,10 @@ import ( // VirtualMemory returns VirtualmemoryStat. func VirtualMemory() (*VirtualMemoryStat, error) { + return VirtualMemoryWithContext(context.Background()) +} + +func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { count := C.mach_msg_type_number_t(C.HOST_VM_INFO_COUNT) var vmstat C.vm_statistics_data_t diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go b/vendor/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go index 79af790d0..dd7c2e600 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go @@ -4,6 +4,7 @@ package mem import ( + "context" "os/exec" "strconv" "strings" @@ -68,6 +69,10 @@ func parseVMStat(out string, vms *VirtualMemoryStat) error { // VirtualMemory returns VirtualmemoryStat. func VirtualMemory() (*VirtualMemoryStat, error) { + return VirtualMemoryWithContext(context.Background()) +} + +func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { ret := &VirtualMemoryStat{} total, err := getHwMemsize() diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_darwin_test.go b/vendor/github.com/shirou/gopsutil/mem/mem_darwin_test.go new file mode 100644 index 000000000..dba421ffc --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/mem/mem_darwin_test.go @@ -0,0 +1,46 @@ +// +build darwin + +package mem + +import ( + "strconv" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestVirtualMemoryDarwin(t *testing.T) { + v, err := VirtualMemory() + assert.Nil(t, err) + + outBytes, err := invoke.Command("/usr/sbin/sysctl", "hw.memsize") + assert.Nil(t, err) + outString := string(outBytes) + outString = strings.TrimSpace(outString) + outParts := strings.Split(outString, " ") + actualTotal, err := strconv.ParseInt(outParts[1], 10, 64) + assert.Nil(t, err) + assert.Equal(t, uint64(actualTotal), v.Total) + + assert.True(t, v.Available > 0) + assert.Equal(t, v.Available, v.Free+v.Inactive, "%v", v) + + assert.True(t, v.Used > 0) + assert.True(t, v.Used < v.Total) + + assert.True(t, v.UsedPercent > 0) + assert.True(t, v.UsedPercent < 100) + + assert.True(t, v.Free > 0) + assert.True(t, v.Free < v.Available) + + assert.True(t, v.Active > 0) + assert.True(t, v.Active < v.Total) + + assert.True(t, v.Inactive > 0) + assert.True(t, v.Inactive < v.Total) + + assert.True(t, v.Wired > 0) + assert.True(t, v.Wired < v.Total) +} diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_fallback.go b/vendor/github.com/shirou/gopsutil/mem/mem_fallback.go index e61fe4b19..2a0fd45b3 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_fallback.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_fallback.go @@ -2,12 +2,24 @@ package mem -import "github.com/shirou/gopsutil/internal/common" +import ( + "context" + + "github.com/shirou/gopsutil/internal/common" +) func VirtualMemory() (*VirtualMemoryStat, error) { + return VirtualMemoryWithContext(context.Background()) +} + +func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { return nil, common.ErrNotImplementedError } func SwapMemory() (*SwapMemoryStat, error) { + return SwapMemoryWithContext(context.Background()) +} + +func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { return nil, common.ErrNotImplementedError } diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_freebsd.go b/vendor/github.com/shirou/gopsutil/mem/mem_freebsd.go index 8cca44b53..e691227db 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_freebsd.go @@ -3,79 +3,62 @@ package mem import ( + "context" "errors" "os/exec" "strconv" "strings" - "github.com/shirou/gopsutil/internal/common" + "golang.org/x/sys/unix" ) func VirtualMemory() (*VirtualMemoryStat, error) { - pageSize, err := common.DoSysctrl("vm.stats.vm.v_page_size") + return VirtualMemoryWithContext(context.Background()) +} + +func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { + pageSize, err := unix.SysctlUint32("vm.stats.vm.v_page_size") if err != nil { return nil, err } - p, err := strconv.ParseUint(pageSize[0], 10, 64) + pageCount, err := unix.SysctlUint32("vm.stats.vm.v_page_count") + if err != nil { + return nil, err + } + free, err := unix.SysctlUint32("vm.stats.vm.v_free_count") + if err != nil { + return nil, err + } + active, err := unix.SysctlUint32("vm.stats.vm.v_active_count") + if err != nil { + return nil, err + } + inactive, err := unix.SysctlUint32("vm.stats.vm.v_inactive_count") + if err != nil { + return nil, err + } + cached, err := unix.SysctlUint32("vm.stats.vm.v_cache_count") + if err != nil { + return nil, err + } + buffers, err := unix.SysctlUint32("vfs.bufspace") + if err != nil { + return nil, err + } + wired, err := unix.SysctlUint32("vm.stats.vm.v_wire_count") if err != nil { return nil, err } - pageCount, err := common.DoSysctrl("vm.stats.vm.v_page_count") - if err != nil { - return nil, err - } - free, err := common.DoSysctrl("vm.stats.vm.v_free_count") - if err != nil { - return nil, err - } - active, err := common.DoSysctrl("vm.stats.vm.v_active_count") - if err != nil { - return nil, err - } - inactive, err := common.DoSysctrl("vm.stats.vm.v_inactive_count") - if err != nil { - return nil, err - } - cache, err := common.DoSysctrl("vm.stats.vm.v_cache_count") - if err != nil { - return nil, err - } - buffer, err := common.DoSysctrl("vfs.bufspace") - if err != nil { - return nil, err - } - wired, err := common.DoSysctrl("vm.stats.vm.v_wire_count") - if err != nil { - return nil, err - } - - parsed := make([]uint64, 0, 7) - vv := []string{ - pageCount[0], - free[0], - active[0], - inactive[0], - cache[0], - buffer[0], - wired[0], - } - for _, target := range vv { - t, err := strconv.ParseUint(target, 10, 64) - if err != nil { - return nil, err - } - parsed = append(parsed, t) - } - + p := uint64(pageSize) ret := &VirtualMemoryStat{ - Total: parsed[0] * p, - Free: parsed[1] * p, - Active: parsed[2] * p, - Inactive: parsed[3] * p, - Cached: parsed[4] * p, - Buffers: parsed[5], - Wired: parsed[6] * p, + Total: uint64(pageCount) * p, + Free: uint64(free) * p, + Active: uint64(active) * p, + Inactive: uint64(inactive) * p, + Cached: uint64(cached) * p, + Buffers: uint64(buffers), + Wired: uint64(wired) * p, } ret.Available = ret.Inactive + ret.Cached + ret.Free @@ -88,6 +71,10 @@ func VirtualMemory() (*VirtualMemoryStat, error) { // Return swapinfo // FreeBSD can have multiple swap devices. but use only first device func SwapMemory() (*SwapMemoryStat, error) { + return SwapMemoryWithContext(context.Background()) +} + +func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { swapinfo, err := exec.LookPath("swapinfo") if err != nil { return nil, err diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_linux.go b/vendor/github.com/shirou/gopsutil/mem/mem_linux.go index fda3345ba..fe6c4e125 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_linux.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_linux.go @@ -3,6 +3,7 @@ package mem import ( + "context" "strconv" "strings" @@ -11,6 +12,10 @@ import ( ) func VirtualMemory() (*VirtualMemoryStat, error) { + return VirtualMemoryWithContext(context.Background()) +} + +func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { filename := common.HostProc("meminfo") lines, _ := common.ReadLines(filename) // flag if MemAvailable is in /proc/meminfo (kernel 3.14+) @@ -72,6 +77,10 @@ func VirtualMemory() (*VirtualMemoryStat, error) { } func SwapMemory() (*SwapMemoryStat, error) { + return SwapMemoryWithContext(context.Background()) +} + +func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { sysinfo := &unix.Sysinfo_t{} if err := unix.Sysinfo(sysinfo); err != nil { diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_openbsd.go b/vendor/github.com/shirou/gopsutil/mem/mem_openbsd.go index 2e94bea11..e4834f383 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_openbsd.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_openbsd.go @@ -4,14 +4,20 @@ package mem import ( "bytes" + "context" "encoding/binary" "errors" "fmt" - "github.com/shirou/gopsutil/internal/common" "os/exec" + + "github.com/shirou/gopsutil/internal/common" ) func GetPageSize() (uint64, error) { + return GetPageSizeWithContext(context.Background()) +} + +func GetPageSizeWithContext(ctx context.Context) (uint64, error) { mib := []int32{CTLVm, VmUvmexp} buf, length, err := common.CallSyscall(mib) if err != nil { @@ -30,6 +36,10 @@ func GetPageSize() (uint64, error) { } func VirtualMemory() (*VirtualMemoryStat, error) { + return VirtualMemoryWithContext(context.Background()) +} + +func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { mib := []int32{CTLVm, VmUvmexp} buf, length, err := common.CallSyscall(mib) if err != nil { @@ -80,6 +90,10 @@ func VirtualMemory() (*VirtualMemoryStat, error) { // Return swapctl summary info func SwapMemory() (*SwapMemoryStat, error) { + return SwapMemoryWithContext(context.Background()) +} + +func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { swapctl, err := exec.LookPath("swapctl") if err != nil { return nil, err diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_solaris.go b/vendor/github.com/shirou/gopsutil/mem/mem_solaris.go index aa4f2538a..d6c6a5fcb 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_solaris.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_solaris.go @@ -1,6 +1,7 @@ package mem import ( + "context" "errors" "fmt" "os/exec" @@ -14,6 +15,10 @@ import ( // VirtualMemory for Solaris is a minimal implementation which only returns // what Nomad needs. It does take into account global vs zone, however. func VirtualMemory() (*VirtualMemoryStat, error) { + return VirtualMemoryWithContext(context.Background()) +} + +func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { result := &VirtualMemoryStat{} zoneName, err := zoneName() @@ -39,6 +44,10 @@ func VirtualMemory() (*VirtualMemoryStat, error) { } func SwapMemory() (*SwapMemoryStat, error) { + return SwapMemoryWithContext(context.Background()) +} + +func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { return nil, common.ErrNotImplementedError } diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_test.go b/vendor/github.com/shirou/gopsutil/mem/mem_test.go new file mode 100644 index 000000000..4a1ae7bf7 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/mem/mem_test.go @@ -0,0 +1,77 @@ +package mem + +import ( + "fmt" + "runtime" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestVirtual_memory(t *testing.T) { + if runtime.GOOS == "solaris" { + t.Skip("Only .Total is supported on Solaris") + } + + v, err := VirtualMemory() + if err != nil { + t.Errorf("error %v", err) + } + empty := &VirtualMemoryStat{} + if v == empty { + t.Errorf("error %v", v) + } + + assert.True(t, v.Total > 0) + assert.True(t, v.Available > 0) + assert.True(t, v.Used > 0) + + assert.Equal(t, v.Total, v.Available+v.Used, + "Total should be computable from available + used: %v", v) + + assert.True(t, v.Free > 0) + assert.True(t, v.Available > v.Free, + "Free should be a subset of Available: %v", v) + + assert.InDelta(t, v.UsedPercent, + 100*float64(v.Used)/float64(v.Total), 0.1, + "UsedPercent should be how many percent of Total is Used: %v", v) +} + +func TestSwap_memory(t *testing.T) { + v, err := SwapMemory() + if err != nil { + t.Errorf("error %v", err) + } + empty := &SwapMemoryStat{} + if v == empty { + t.Errorf("error %v", v) + } +} + +func TestVirtualMemoryStat_String(t *testing.T) { + v := VirtualMemoryStat{ + Total: 10, + Available: 20, + Used: 30, + UsedPercent: 30.1, + Free: 40, + } + e := `{"total":10,"available":20,"used":30,"usedPercent":30.1,"free":40,"active":0,"inactive":0,"wired":0,"buffers":0,"cached":0,"writeback":0,"dirty":0,"writebacktmp":0,"shared":0,"slab":0,"pagetables":0,"swapcached":0}` + if e != fmt.Sprintf("%v", v) { + t.Errorf("VirtualMemoryStat string is invalid: %v", v) + } +} + +func TestSwapMemoryStat_String(t *testing.T) { + v := SwapMemoryStat{ + Total: 10, + Used: 30, + Free: 40, + UsedPercent: 30.1, + } + e := `{"total":10,"used":30,"free":40,"usedPercent":30.1,"sin":0,"sout":0}` + if e != fmt.Sprintf("%v", v) { + t.Errorf("SwapMemoryStat string is invalid: %v", v) + } +} diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_windows.go b/vendor/github.com/shirou/gopsutil/mem/mem_windows.go index b56f25ec2..d40f6cf9d 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_windows.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_windows.go @@ -3,6 +3,7 @@ package mem import ( + "context" "unsafe" "github.com/shirou/gopsutil/internal/common" @@ -11,6 +12,7 @@ import ( var ( procGlobalMemoryStatusEx = common.Modkernel32.NewProc("GlobalMemoryStatusEx") + procGetPerformanceInfo = common.ModPsapi.NewProc("GetPerformanceInfo") ) type memoryStatusEx struct { @@ -26,6 +28,10 @@ type memoryStatusEx struct { } func VirtualMemory() (*VirtualMemoryStat, error) { + return VirtualMemoryWithContext(context.Background()) +} + +func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { var memInfo memoryStatusEx memInfo.cbSize = uint32(unsafe.Sizeof(memInfo)) mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo))) @@ -43,8 +49,43 @@ func VirtualMemory() (*VirtualMemoryStat, error) { return ret, nil } +type performanceInformation struct { + cb uint32 + commitTotal uint64 + commitLimit uint64 + commitPeak uint64 + physicalTotal uint64 + physicalAvailable uint64 + systemCache uint64 + kernelTotal uint64 + kernelPaged uint64 + kernelNonpaged uint64 + pageSize uint64 + handleCount uint32 + processCount uint32 + threadCount uint32 +} + func SwapMemory() (*SwapMemoryStat, error) { - ret := &SwapMemoryStat{} + return SwapMemoryWithContext(context.Background()) +} + +func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { + var perfInfo performanceInformation + perfInfo.cb = uint32(unsafe.Sizeof(perfInfo)) + mem, _, _ := procGetPerformanceInfo.Call(uintptr(unsafe.Pointer(&perfInfo)), uintptr(perfInfo.cb)) + if mem == 0 { + return nil, windows.GetLastError() + } + tot := perfInfo.commitLimit * perfInfo.pageSize + used := perfInfo.commitTotal * perfInfo.pageSize + free := tot - used + ret := &SwapMemoryStat{ + Total: tot, + Used: used, + Free: free, + UsedPercent: float64(used / tot), + } return ret, nil } diff --git a/vendor/github.com/shirou/gopsutil/net/net.go b/vendor/github.com/shirou/gopsutil/net/net.go index 48660ec74..428e68e1e 100644 --- a/vendor/github.com/shirou/gopsutil/net/net.go +++ b/vendor/github.com/shirou/gopsutil/net/net.go @@ -1,6 +1,7 @@ package net import ( + "context" "encoding/json" "fmt" "net" @@ -111,6 +112,10 @@ func (n InterfaceAddr) String() string { } func Interfaces() ([]InterfaceStat, error) { + return InterfacesWithContext(context.Background()) +} + +func InterfacesWithContext(ctx context.Context) ([]InterfaceStat, error) { is, err := net.Interfaces() if err != nil { return nil, err diff --git a/vendor/github.com/shirou/gopsutil/net/net_darwin.go b/vendor/github.com/shirou/gopsutil/net/net_darwin.go index c60a00457..2afb0f089 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_darwin.go +++ b/vendor/github.com/shirou/gopsutil/net/net_darwin.go @@ -3,6 +3,7 @@ package net import ( + "context" "errors" "fmt" "os/exec" @@ -164,6 +165,10 @@ func (min mapInterfaceNameUsage) notTruncated() []string { // lo0 16384 ::1/128 ::1 869107 - 169411755 869107 - 169411755 - - // lo0 16384 127 127.0.0.1 869107 - 169411755 869107 - 169411755 - - func IOCounters(pernic bool) ([]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), pernic) +} + +func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { var ( ret []IOCountersStat retIndex int @@ -251,10 +256,18 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { // NetIOCountersByFile is an method which is added just a compatibility for linux. func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { + return IOCountersByFileWithContext(context.Background(), pernic, filename) +} + +func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) { return IOCounters(pernic) } func FilterCounters() ([]FilterStat, error) { + return FilterCountersWithContext(context.Background()) +} + +func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { return nil, errors.New("NetFilterCounters not implemented for darwin") } @@ -263,5 +276,9 @@ func FilterCounters() ([]FilterStat, error) { // just the protocols in the list are returned. // Not Implemented for Darwin func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { + return ProtoCountersWithContext(context.Background(), protocols) +} + +func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { return nil, errors.New("NetProtoCounters not implemented for darwin") } diff --git a/vendor/github.com/shirou/gopsutil/net/net_darwin_test.go b/vendor/github.com/shirou/gopsutil/net/net_darwin_test.go new file mode 100644 index 000000000..e4c33bba9 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/net/net_darwin_test.go @@ -0,0 +1,140 @@ +package net + +import ( + "testing" + + assert "github.com/stretchr/testify/require" +) + +const ( + netstatTruncated = `Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll Drop +lo0 16384 31241 0 3769823 31241 0 3769823 0 0 +lo0 16384 ::1/128 ::1 31241 - 3769823 31241 - 3769823 - - +lo0 16384 127 127.0.0.1 31241 - 3769823 31241 - 3769823 - - +lo0 16384 fe80::1%lo0 fe80:1::1 31241 - 3769823 31241 - 3769823 - - +gif0* 1280 0 0 0 0 0 0 0 0 +stf0* 1280 0 0 0 0 0 0 0 0 +utun8 1500 286 0 27175 0 0 0 0 0 +utun8 1500 286 0 29554 0 0 0 0 0 +utun8 1500 286 0 29244 0 0 0 0 0 +utun8 1500 286 0 28267 0 0 0 0 0 +utun8 1500 286 0 28593 0 0 0 0 0` + netstatNotTruncated = `Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll Drop +lo0 16384 27190978 0 12824763793 27190978 0 12824763793 0 0 +lo0 16384 ::1/128 ::1 27190978 - 12824763793 27190978 - 12824763793 - - +lo0 16384 127 127.0.0.1 27190978 - 12824763793 27190978 - 12824763793 - - +lo0 16384 fe80::1%lo0 fe80:1::1 27190978 - 12824763793 27190978 - 12824763793 - - +gif0* 1280 0 0 0 0 0 0 0 0 +stf0* 1280 0 0 0 0 0 0 0 0 +en0 1500 a8:66:7f:dd:ee:ff 5708989 0 7295722068 3494252 0 379533492 0 230 +en0 1500 fe80::aa66: fe80:4::aa66:7fff 5708989 - 7295722068 3494252 - 379533492 - -` +) + +func TestparseNetstatLineHeader(t *testing.T) { + stat, linkIkd, err := parseNetstatLine(`Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll Drop`) + assert.Nil(t, linkIkd) + assert.Nil(t, stat) + assert.Error(t, err) + assert.Equal(t, errNetstatHeader, err) +} + +func assertLoopbackStat(t *testing.T, err error, stat *IOCountersStat) { + assert.NoError(t, err) + assert.Equal(t, 869107, stat.PacketsRecv) + assert.Equal(t, 0, stat.Errin) + assert.Equal(t, 169411755, stat.BytesRecv) + assert.Equal(t, 869108, stat.PacketsSent) + assert.Equal(t, 1, stat.Errout) + assert.Equal(t, 169411756, stat.BytesSent) +} + +func TestparseNetstatLineLink(t *testing.T) { + stat, linkID, err := parseNetstatLine( + `lo0 16384 869107 0 169411755 869108 1 169411756 0 0`, + ) + assertLoopbackStat(t, err, stat) + assert.NotNil(t, linkID) + assert.Equal(t, uint(1), *linkID) +} + +func TestparseNetstatLineIPv6(t *testing.T) { + stat, linkID, err := parseNetstatLine( + `lo0 16384 ::1/128 ::1 869107 - 169411755 869108 1 169411756 - -`, + ) + assertLoopbackStat(t, err, stat) + assert.Nil(t, linkID) +} + +func TestparseNetstatLineIPv4(t *testing.T) { + stat, linkID, err := parseNetstatLine( + `lo0 16384 127 127.0.0.1 869107 - 169411755 869108 1 169411756 - -`, + ) + assertLoopbackStat(t, err, stat) + assert.Nil(t, linkID) +} + +func TestParseNetstatOutput(t *testing.T) { + nsInterfaces, err := parseNetstatOutput(netstatNotTruncated) + assert.NoError(t, err) + assert.Len(t, nsInterfaces, 8) + for index := range nsInterfaces { + assert.NotNil(t, nsInterfaces[index].stat, "Index %d", index) + } + + assert.NotNil(t, nsInterfaces[0].linkID) + assert.Equal(t, uint(1), *nsInterfaces[0].linkID) + + assert.Nil(t, nsInterfaces[1].linkID) + assert.Nil(t, nsInterfaces[2].linkID) + assert.Nil(t, nsInterfaces[3].linkID) + + assert.NotNil(t, nsInterfaces[4].linkID) + assert.Equal(t, uint(2), *nsInterfaces[4].linkID) + + assert.NotNil(t, nsInterfaces[5].linkID) + assert.Equal(t, uint(3), *nsInterfaces[5].linkID) + + assert.NotNil(t, nsInterfaces[6].linkID) + assert.Equal(t, uint(4), *nsInterfaces[6].linkID) + + assert.Nil(t, nsInterfaces[7].linkID) + + mapUsage := newMapInterfaceNameUsage(nsInterfaces) + assert.False(t, mapUsage.isTruncated()) + assert.Len(t, mapUsage.notTruncated(), 4) +} + +func TestParseNetstatTruncated(t *testing.T) { + nsInterfaces, err := parseNetstatOutput(netstatTruncated) + assert.NoError(t, err) + assert.Len(t, nsInterfaces, 11) + for index := range nsInterfaces { + assert.NotNil(t, nsInterfaces[index].stat, "Index %d", index) + } + + const truncatedIface = "utun8" + + assert.NotNil(t, nsInterfaces[6].linkID) + assert.Equal(t, uint(88), *nsInterfaces[6].linkID) + assert.Equal(t, truncatedIface, nsInterfaces[6].stat.Name) + + assert.NotNil(t, nsInterfaces[7].linkID) + assert.Equal(t, uint(90), *nsInterfaces[7].linkID) + assert.Equal(t, truncatedIface, nsInterfaces[7].stat.Name) + + assert.NotNil(t, nsInterfaces[8].linkID) + assert.Equal(t, uint(92), *nsInterfaces[8].linkID) + assert.Equal(t, truncatedIface, nsInterfaces[8].stat.Name) + + assert.NotNil(t, nsInterfaces[9].linkID) + assert.Equal(t, uint(93), *nsInterfaces[9].linkID) + assert.Equal(t, truncatedIface, nsInterfaces[9].stat.Name) + + assert.NotNil(t, nsInterfaces[10].linkID) + assert.Equal(t, uint(95), *nsInterfaces[10].linkID) + assert.Equal(t, truncatedIface, nsInterfaces[10].stat.Name) + + mapUsage := newMapInterfaceNameUsage(nsInterfaces) + assert.True(t, mapUsage.isTruncated()) + assert.Equal(t, 3, len(mapUsage.notTruncated()), "en0, gif0 and stf0") +} diff --git a/vendor/github.com/shirou/gopsutil/net/net_fallback.go b/vendor/github.com/shirou/gopsutil/net/net_fallback.go index 653bd47e5..7c5e632f8 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_fallback.go +++ b/vendor/github.com/shirou/gopsutil/net/net_fallback.go @@ -2,24 +2,48 @@ package net -import "github.com/shirou/gopsutil/internal/common" +import ( + "context" + + "github.com/shirou/gopsutil/internal/common" +) func IOCounters(pernic bool) ([]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), pernic) +} + +func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { return []IOCountersStat{}, common.ErrNotImplementedError } func FilterCounters() ([]FilterStat, error) { + return FilterCountersWithContext(context.Background()) +} + +func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { return []FilterStat{}, common.ErrNotImplementedError } func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { + return ProtoCountersWithContext(context.Background(), protocols) +} + +func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { return []ProtoCountersStat{}, common.ErrNotImplementedError } func Connections(kind string) ([]ConnectionStat, error) { + return ConnectionsWithContext(context.Background(), kind) +} + +func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { return []ConnectionStat{}, common.ErrNotImplementedError } func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) { + return ConnectionsMaxWithContext(context.Background(), kind, max) +} + +func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) { return []ConnectionStat{}, common.ErrNotImplementedError } diff --git a/vendor/github.com/shirou/gopsutil/net/net_freebsd.go b/vendor/github.com/shirou/gopsutil/net/net_freebsd.go index 2b546550e..9daed8d71 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/net/net_freebsd.go @@ -3,6 +3,7 @@ package net import ( + "context" "errors" "os/exec" "strconv" @@ -12,6 +13,10 @@ import ( ) func IOCounters(pernic bool) ([]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), pernic) +} + +func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { netstat, err := exec.LookPath("/usr/bin/netstat") if err != nil { return nil, err @@ -92,10 +97,18 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { // NetIOCountersByFile is an method which is added just a compatibility for linux. func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { + return IOCountersByFileWithContext(context.Background(), pernic, filename) +} + +func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) { return IOCounters(pernic) } func FilterCounters() ([]FilterStat, error) { + return FilterCountersWithContext(context.Background()) +} + +func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { return nil, errors.New("NetFilterCounters not implemented for freebsd") } @@ -104,5 +117,9 @@ func FilterCounters() ([]FilterStat, error) { // just the protocols in the list are returned. // Not Implemented for FreeBSD func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { + return ProtoCountersWithContext(context.Background(), protocols) +} + +func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { return nil, errors.New("NetProtoCounters not implemented for freebsd") } diff --git a/vendor/github.com/shirou/gopsutil/net/net_linux.go b/vendor/github.com/shirou/gopsutil/net/net_linux.go index 9ed453369..fc2b22ea5 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_linux.go +++ b/vendor/github.com/shirou/gopsutil/net/net_linux.go @@ -4,6 +4,7 @@ package net import ( "bytes" + "context" "encoding/hex" "errors" "fmt" @@ -23,11 +24,19 @@ import ( // every network interface installed on the system is returned // separately. func IOCounters(pernic bool) ([]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), pernic) +} + +func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { filename := common.HostProc("net/dev") return IOCountersByFile(pernic, filename) } func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { + return IOCountersByFileWithContext(context.Background(), pernic, filename) +} + +func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) { lines, err := common.ReadLines(filename) if err != nil { return nil, err @@ -132,6 +141,10 @@ var netProtocols = []string{ // Available protocols: // ip,icmp,icmpmsg,tcp,udp,udplite func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { + return ProtoCountersWithContext(context.Background(), protocols) +} + +func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { if len(protocols) == 0 { protocols = netProtocols } @@ -191,6 +204,10 @@ func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { // the currently in use conntrack count and the max. // If the file does not exist or is invalid it will return nil. func FilterCounters() ([]FilterStat, error) { + return FilterCountersWithContext(context.Background()) +} + +func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { countfile := common.HostProc("sys/net/netfilter/nf_conntrack_count") maxfile := common.HostProc("sys/net/netfilter/nf_conntrack_max") @@ -294,17 +311,29 @@ type connTmp struct { // Return a list of network connections opened. func Connections(kind string) ([]ConnectionStat, error) { + return ConnectionsWithContext(context.Background(), kind) +} + +func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { return ConnectionsPid(kind, 0) } // Return a list of network connections opened returning at most `max` // connections for each running process. func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) { + return ConnectionsMaxWithContext(context.Background(), kind, max) +} + +func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) { return ConnectionsPidMax(kind, 0, max) } // Return a list of network connections opened by a process. func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) { + return ConnectionsPidWithContext(context.Background(), kind, pid) +} + +func ConnectionsPidWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) { tmap, ok := netConnectionKindMap[kind] if !ok { return nil, fmt.Errorf("invalid kind, %s", kind) @@ -322,13 +351,17 @@ func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) { } } if err != nil { - return nil, fmt.Errorf("cound not get pid(s), %d", pid) + return nil, fmt.Errorf("cound not get pid(s), %d: %s", pid, err) } return statsFromInodes(root, pid, tmap, inodes) } // Return up to `max` network connections opened by a process. func ConnectionsPidMax(kind string, pid int32, max int) ([]ConnectionStat, error) { + return ConnectionsPidMaxWithContext(context.Background(), kind, pid, max) +} + +func ConnectionsPidMaxWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) { tmap, ok := netConnectionKindMap[kind] if !ok { return nil, fmt.Errorf("invalid kind, %s", kind) @@ -459,6 +492,10 @@ func getProcInodes(root string, pid int32, max int) (map[string][]inodeMap, erro // FIXME: Import process occures import cycle. // move to common made other platform breaking. Need consider. func Pids() ([]int32, error) { + return PidsWithContext(context.Background()) +} + +func PidsWithContext(ctx context.Context) ([]int32, error) { var ret []int32 d, err := os.Open(common.HostProc()) @@ -541,6 +578,10 @@ func getProcInodesAll(root string, max int) (map[string][]inodeMap, error) { for _, pid := range pids { t, err := getProcInodes(root, pid, max) if err != nil { + // skip if permission error or no longer exists + if os.IsPermission(err) || os.IsNotExist(err) { + continue + } return ret, err } if len(t) == 0 { @@ -588,6 +629,10 @@ func decodeAddress(family uint32, src string) (Addr, error) { // Reverse reverses array of bytes. func Reverse(s []byte) []byte { + return ReverseWithContext(context.Background(), s) +} + +func ReverseWithContext(ctx context.Context, s []byte) []byte { for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { s[i], s[j] = s[j], s[i] } diff --git a/vendor/github.com/shirou/gopsutil/net/net_linux_test.go b/vendor/github.com/shirou/gopsutil/net/net_linux_test.go new file mode 100644 index 000000000..566a17b34 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/net/net_linux_test.go @@ -0,0 +1,163 @@ +package net + +import ( + "fmt" + "io/ioutil" + "os" + "strings" + "syscall" + "testing" + + "github.com/shirou/gopsutil/internal/common" + "github.com/stretchr/testify/assert" +) + +func TestIOCountersByFileParsing(t *testing.T) { + // Prpare a temporary file, which will be read during the test + tmpfile, err := ioutil.TempFile("", "proc_dev_net") + defer os.Remove(tmpfile.Name()) // clean up + + assert.Nil(t, err, "Temporary file creation failed: ", err) + + cases := [4][2]string{ + [2]string{"eth0: ", "eth1: "}, + [2]string{"eth0:0: ", "eth1:0: "}, + [2]string{"eth0:", "eth1:"}, + [2]string{"eth0:0:", "eth1:0:"}, + } + for _, testCase := range cases { + err = tmpfile.Truncate(0) + assert.Nil(t, err, "Temporary file truncating problem: ", err) + + // Parse interface name for assertion + interface0 := strings.TrimSpace(testCase[0]) + interface0 = interface0[:len(interface0)-1] + + interface1 := strings.TrimSpace(testCase[1]) + interface1 = interface1[:len(interface1)-1] + + // Replace the interfaces from the test case + proc := []byte(fmt.Sprintf("Inter-| Receive | Transmit\n face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed\n %s1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16\n %s100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600\n", testCase[0], testCase[1])) + + // Write /proc/net/dev sample output + _, err = tmpfile.Write(proc) + assert.Nil(t, err, "Temporary file writing failed: ", err) + + counters, err := IOCountersByFile(true, tmpfile.Name()) + + assert.Nil(t, err) + assert.NotEmpty(t, counters) + assert.Equal(t, 2, len(counters)) + assert.Equal(t, interface0, counters[0].Name) + assert.Equal(t, 1, int(counters[0].BytesRecv)) + assert.Equal(t, 2, int(counters[0].PacketsRecv)) + assert.Equal(t, 3, int(counters[0].Errin)) + assert.Equal(t, 4, int(counters[0].Dropin)) + assert.Equal(t, 5, int(counters[0].Fifoin)) + assert.Equal(t, 9, int(counters[0].BytesSent)) + assert.Equal(t, 10, int(counters[0].PacketsSent)) + assert.Equal(t, 11, int(counters[0].Errout)) + assert.Equal(t, 12, int(counters[0].Dropout)) + assert.Equal(t, 13, int(counters[0].Fifoout)) + assert.Equal(t, interface1, counters[1].Name) + assert.Equal(t, 100, int(counters[1].BytesRecv)) + assert.Equal(t, 200, int(counters[1].PacketsRecv)) + assert.Equal(t, 300, int(counters[1].Errin)) + assert.Equal(t, 400, int(counters[1].Dropin)) + assert.Equal(t, 500, int(counters[1].Fifoin)) + assert.Equal(t, 900, int(counters[1].BytesSent)) + assert.Equal(t, 1000, int(counters[1].PacketsSent)) + assert.Equal(t, 1100, int(counters[1].Errout)) + assert.Equal(t, 1200, int(counters[1].Dropout)) + assert.Equal(t, 1300, int(counters[1].Fifoout)) + } + + err = tmpfile.Close() + assert.Nil(t, err, "Temporary file closing failed: ", err) +} + +func TestGetProcInodesAll(t *testing.T) { + if os.Getenv("CIRCLECI") == "true" { + t.Skip("Skip CI") + } + + root := common.HostProc("") + v, err := getProcInodesAll(root, 0) + assert.Nil(t, err) + assert.NotEmpty(t, v) +} + +func TestConnectionsMax(t *testing.T) { + if os.Getenv("CIRCLECI") == "true" { + t.Skip("Skip CI") + } + + max := 10 + v, err := ConnectionsMax("tcp", max) + assert.Nil(t, err) + assert.NotEmpty(t, v) + + cxByPid := map[int32]int{} + for _, cx := range v { + if cx.Pid > 0 { + cxByPid[cx.Pid]++ + } + } + for _, c := range cxByPid { + assert.True(t, c <= max) + } +} + +type AddrTest struct { + IP string + Port int + Error bool +} + +func TestDecodeAddress(t *testing.T) { + assert := assert.New(t) + + addr := map[string]AddrTest{ + "0500000A:0016": { + IP: "10.0.0.5", + Port: 22, + }, + "0100007F:D1C2": { + IP: "127.0.0.1", + Port: 53698, + }, + "11111:0035": { + Error: true, + }, + "0100007F:BLAH": { + Error: true, + }, + "0085002452100113070057A13F025401:0035": { + IP: "2400:8500:1301:1052:a157:7:154:23f", + Port: 53, + }, + "00855210011307F025401:0035": { + Error: true, + }, + } + + for src, dst := range addr { + family := syscall.AF_INET + if len(src) > 13 { + family = syscall.AF_INET6 + } + addr, err := decodeAddress(uint32(family), src) + if dst.Error { + assert.NotNil(err, src) + } else { + assert.Nil(err, src) + assert.Equal(dst.IP, addr.IP, src) + assert.Equal(dst.Port, int(addr.Port), src) + } + } +} + +func TestReverse(t *testing.T) { + src := []byte{0x01, 0x02, 0x03} + assert.Equal(t, []byte{0x03, 0x02, 0x01}, Reverse(src)) +} diff --git a/vendor/github.com/shirou/gopsutil/net/net_openbsd.go b/vendor/github.com/shirou/gopsutil/net/net_openbsd.go index 85cc70c49..4b194eb6e 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_openbsd.go +++ b/vendor/github.com/shirou/gopsutil/net/net_openbsd.go @@ -3,14 +3,20 @@ package net import ( + "context" "errors" + "fmt" "os/exec" + "regexp" "strconv" "strings" + "syscall" "github.com/shirou/gopsutil/internal/common" ) +var portMatch = regexp.MustCompile(`(.*)\.(\d+)$`) + func ParseNetstat(output string, mode string, iocs map[string]IOCountersStat) error { lines := strings.Split(output, "\n") @@ -92,7 +98,11 @@ func ParseNetstat(output string, mode string, } func IOCounters(pernic bool) ([]IOCountersStat, error) { - netstat, err := exec.LookPath("/usr/bin/netstat") + return IOCountersWithContext(context.Background(), pernic) +} + +func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { + netstat, err := exec.LookPath("netstat") if err != nil { return nil, err } @@ -131,10 +141,18 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { // NetIOCountersByFile is an method which is added just a compatibility for linux. func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { + return IOCountersByFileWithContext(context.Background(), pernic, filename) +} + +func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) { return IOCounters(pernic) } func FilterCounters() ([]FilterStat, error) { + return FilterCountersWithContext(context.Background()) +} + +func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { return nil, errors.New("NetFilterCounters not implemented for openbsd") } @@ -143,11 +161,152 @@ func FilterCounters() ([]FilterStat, error) { // just the protocols in the list are returned. // Not Implemented for OpenBSD func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { + return ProtoCountersWithContext(context.Background(), protocols) +} + +func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { return nil, errors.New("NetProtoCounters not implemented for openbsd") } -// Return a list of network connections opened. -// Not Implemented for OpenBSD -func Connections(kind string) ([]ConnectionStat, error) { - return nil, errors.New("Connections not implemented for openbsd") +func parseNetstatLine(line string) (ConnectionStat, error) { + f := strings.Fields(line) + if len(f) < 5 { + return ConnectionStat{}, fmt.Errorf("wrong line,%s", line) + } + + var netType, netFamily uint32 + switch f[0] { + case "tcp": + netType = syscall.SOCK_STREAM + netFamily = syscall.AF_INET + case "udp": + netType = syscall.SOCK_DGRAM + netFamily = syscall.AF_INET + case "tcp6": + netType = syscall.SOCK_STREAM + netFamily = syscall.AF_INET6 + case "udp6": + netType = syscall.SOCK_DGRAM + netFamily = syscall.AF_INET6 + default: + return ConnectionStat{}, fmt.Errorf("unknown type, %s", f[0]) + } + + laddr, raddr, err := parseNetstatAddr(f[3], f[4], netFamily) + if err != nil { + return ConnectionStat{}, fmt.Errorf("failed to parse netaddr, %s %s", f[3], f[4]) + } + + n := ConnectionStat{ + Fd: uint32(0), // not supported + Family: uint32(netFamily), + Type: uint32(netType), + Laddr: laddr, + Raddr: raddr, + Pid: int32(0), // not supported + } + if len(f) == 6 { + n.Status = f[5] + } + + return n, nil +} + +func parseNetstatAddr(local string, remote string, family uint32) (laddr Addr, raddr Addr, err error) { + parse := func(l string) (Addr, error) { + matches := portMatch.FindStringSubmatch(l) + if matches == nil { + return Addr{}, fmt.Errorf("wrong addr, %s", l) + } + host := matches[1] + port := matches[2] + if host == "*" { + switch family { + case syscall.AF_INET: + host = "0.0.0.0" + case syscall.AF_INET6: + host = "::" + default: + return Addr{}, fmt.Errorf("unknown family, %d", family) + } + } + lport, err := strconv.Atoi(port) + if err != nil { + return Addr{}, err + } + return Addr{IP: host, Port: uint32(lport)}, nil + } + + laddr, err = parse(local) + if remote != "*.*" { // remote addr exists + raddr, err = parse(remote) + if err != nil { + return laddr, raddr, err + } + } + + return laddr, raddr, err +} + +// Return a list of network connections opened. +func Connections(kind string) ([]ConnectionStat, error) { + return ConnectionsWithContext(context.Background(), kind) +} + +func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { + var ret []ConnectionStat + + args := []string{"-na"} + switch strings.ToLower(kind) { + default: + fallthrough + case "": + fallthrough + case "all": + fallthrough + case "inet": + // nothing to add + case "inet4": + args = append(args, "-finet") + case "inet6": + args = append(args, "-finet6") + case "tcp": + args = append(args, "-ptcp") + case "tcp4": + args = append(args, "-ptcp", "-finet") + case "tcp6": + args = append(args, "-ptcp", "-finet6") + case "udp": + args = append(args, "-pudp") + case "udp4": + args = append(args, "-pudp", "-finet") + case "udp6": + args = append(args, "-pudp", "-finet6") + case "unix": + return ret, common.ErrNotImplementedError + } + + netstat, err := exec.LookPath("netstat") + if err != nil { + return nil, err + } + out, err := invoke.Command(netstat, args...) + + if err != nil { + return nil, err + } + lines := strings.Split(string(out), "\n") + for _, line := range lines { + if !(strings.HasPrefix(line, "tcp") || strings.HasPrefix(line, "udp")) { + continue + } + n, err := parseNetstatLine(line) + if err != nil { + continue + } + + ret = append(ret, n) + } + + return ret, nil } diff --git a/vendor/github.com/shirou/gopsutil/net/net_test.go b/vendor/github.com/shirou/gopsutil/net/net_test.go new file mode 100644 index 000000000..155938707 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/net/net_test.go @@ -0,0 +1,229 @@ +package net + +import ( + "fmt" + "os" + "runtime" + "testing" + + "github.com/shirou/gopsutil/internal/common" +) + +func TestAddrString(t *testing.T) { + v := Addr{IP: "192.168.0.1", Port: 8000} + + s := fmt.Sprintf("%v", v) + if s != "{\"ip\":\"192.168.0.1\",\"port\":8000}" { + t.Errorf("Addr string is invalid: %v", v) + } +} + +func TestNetIOCountersStatString(t *testing.T) { + v := IOCountersStat{ + Name: "test", + BytesSent: 100, + } + e := `{"name":"test","bytesSent":100,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0}` + if e != fmt.Sprintf("%v", v) { + t.Errorf("NetIOCountersStat string is invalid: %v", v) + } +} + +func TestNetProtoCountersStatString(t *testing.T) { + v := ProtoCountersStat{ + Protocol: "tcp", + Stats: map[string]int64{ + "MaxConn": -1, + "ActiveOpens": 4000, + "PassiveOpens": 3000, + }, + } + e := `{"protocol":"tcp","stats":{"ActiveOpens":4000,"MaxConn":-1,"PassiveOpens":3000}}` + if e != fmt.Sprintf("%v", v) { + t.Errorf("NetProtoCountersStat string is invalid: %v", v) + } + +} + +func TestNetConnectionStatString(t *testing.T) { + v := ConnectionStat{ + Fd: 10, + Family: 10, + Type: 10, + Uids: []int32{10, 10}, + } + e := `{"fd":10,"family":10,"type":10,"localaddr":{"ip":"","port":0},"remoteaddr":{"ip":"","port":0},"status":"","uids":[10,10],"pid":0}` + if e != fmt.Sprintf("%v", v) { + t.Errorf("NetConnectionStat string is invalid: %v", v) + } + +} + +func TestNetIOCountersAll(t *testing.T) { + v, err := IOCounters(false) + per, err := IOCounters(true) + if err != nil { + t.Errorf("Could not get NetIOCounters: %v", err) + } + if len(v) != 1 { + t.Errorf("Could not get NetIOCounters: %v", v) + } + if v[0].Name != "all" { + t.Errorf("Invalid NetIOCounters: %v", v) + } + var pr uint64 + for _, p := range per { + pr += p.PacketsRecv + } + if v[0].PacketsRecv != pr { + t.Errorf("invalid sum value: %v, %v", v[0].PacketsRecv, pr) + } +} + +func TestNetIOCountersPerNic(t *testing.T) { + v, err := IOCounters(true) + if err != nil { + t.Errorf("Could not get NetIOCounters: %v", err) + } + if len(v) == 0 { + t.Errorf("Could not get NetIOCounters: %v", v) + } + for _, vv := range v { + if vv.Name == "" { + t.Errorf("Invalid NetIOCounters: %v", vv) + } + } +} + +func TestGetNetIOCountersAll(t *testing.T) { + n := []IOCountersStat{ + { + Name: "a", + BytesRecv: 10, + PacketsRecv: 10, + }, + { + Name: "b", + BytesRecv: 10, + PacketsRecv: 10, + Errin: 10, + }, + } + ret, err := getIOCountersAll(n) + if err != nil { + t.Error(err) + } + if len(ret) != 1 { + t.Errorf("invalid return count") + } + if ret[0].Name != "all" { + t.Errorf("invalid return name") + } + if ret[0].BytesRecv != 20 { + t.Errorf("invalid count bytesrecv") + } + if ret[0].Errin != 10 { + t.Errorf("invalid count errin") + } +} + +func TestNetInterfaces(t *testing.T) { + v, err := Interfaces() + if err != nil { + t.Errorf("Could not get NetInterfaceStat: %v", err) + } + if len(v) == 0 { + t.Errorf("Could not get NetInterfaceStat: %v", err) + } + for _, vv := range v { + if vv.Name == "" { + t.Errorf("Invalid NetInterface: %v", vv) + } + } +} + +func TestNetProtoCountersStatsAll(t *testing.T) { + v, err := ProtoCounters(nil) + if err != nil { + t.Fatalf("Could not get NetProtoCounters: %v", err) + } + if len(v) == 0 { + t.Fatalf("Could not get NetProtoCounters: %v", err) + } + for _, vv := range v { + if vv.Protocol == "" { + t.Errorf("Invalid NetProtoCountersStat: %v", vv) + } + if len(vv.Stats) == 0 { + t.Errorf("Invalid NetProtoCountersStat: %v", vv) + } + } +} + +func TestNetProtoCountersStats(t *testing.T) { + v, err := ProtoCounters([]string{"tcp", "ip"}) + if err != nil { + t.Fatalf("Could not get NetProtoCounters: %v", err) + } + if len(v) == 0 { + t.Fatalf("Could not get NetProtoCounters: %v", err) + } + if len(v) != 2 { + t.Fatalf("Go incorrect number of NetProtoCounters: %v", err) + } + for _, vv := range v { + if vv.Protocol != "tcp" && vv.Protocol != "ip" { + t.Errorf("Invalid NetProtoCountersStat: %v", vv) + } + if len(vv.Stats) == 0 { + t.Errorf("Invalid NetProtoCountersStat: %v", vv) + } + } +} + +func TestNetConnections(t *testing.T) { + if ci := os.Getenv("CI"); ci != "" { // skip if test on drone.io + return + } + + v, err := Connections("inet") + if err != nil { + t.Errorf("could not get NetConnections: %v", err) + } + if len(v) == 0 { + t.Errorf("could not get NetConnections: %v", v) + } + for _, vv := range v { + if vv.Family == 0 { + t.Errorf("invalid NetConnections: %v", vv) + } + } + +} + +func TestNetFilterCounters(t *testing.T) { + if ci := os.Getenv("CI"); ci != "" { // skip if test on drone.io + return + } + + if runtime.GOOS == "linux" { + // some test environment has not the path. + if !common.PathExists("/proc/sys/net/netfilter/nf_conntrackCount") { + t.SkipNow() + } + } + + v, err := FilterCounters() + if err != nil { + t.Errorf("could not get NetConnections: %v", err) + } + if len(v) == 0 { + t.Errorf("could not get NetConnections: %v", v) + } + for _, vv := range v { + if vv.ConnTrackMax == 0 { + t.Errorf("nf_conntrackMax needs to be greater than zero: %v", vv) + } + } + +} diff --git a/vendor/github.com/shirou/gopsutil/net/net_unix.go b/vendor/github.com/shirou/gopsutil/net/net_unix.go index 1224128ab..5ceb9cc54 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_unix.go +++ b/vendor/github.com/shirou/gopsutil/net/net_unix.go @@ -3,6 +3,7 @@ package net import ( + "context" "strings" "github.com/shirou/gopsutil/internal/common" @@ -10,17 +11,29 @@ import ( // Return a list of network connections opened. func Connections(kind string) ([]ConnectionStat, error) { + return ConnectionsWithContext(context.Background(), kind) +} + +func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { return ConnectionsPid(kind, 0) } // Return a list of network connections opened returning at most `max` // connections for each running process. func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) { + return ConnectionsMaxWithContext(context.Background(), kind, max) +} + +func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) { return []ConnectionStat{}, common.ErrNotImplementedError } // Return a list of network connections opened by a process. func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) { + return ConnectionsPidWithContext(context.Background(), kind, pid) +} + +func ConnectionsPidWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) { var ret []ConnectionStat args := []string{"-i"} @@ -75,5 +88,9 @@ func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) { // Return up to `max` network connections opened by a process. func ConnectionsPidMax(kind string, pid int32, max int) ([]ConnectionStat, error) { + return ConnectionsPidMaxWithContext(context.Background(), kind, pid, max) +} + +func ConnectionsPidMaxWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) { return []ConnectionStat{}, common.ErrNotImplementedError } diff --git a/vendor/github.com/shirou/gopsutil/net/net_windows.go b/vendor/github.com/shirou/gopsutil/net/net_windows.go index e26a13079..7fff20e2b 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_windows.go +++ b/vendor/github.com/shirou/gopsutil/net/net_windows.go @@ -3,6 +3,7 @@ package net import ( + "context" "errors" "net" "os" @@ -30,6 +31,10 @@ const ( ) func IOCounters(pernic bool) ([]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), pernic) +} + +func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { ifs, err := net.Interfaces() if err != nil { return nil, err @@ -66,11 +71,19 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { // NetIOCountersByFile is an method which is added just a compatibility for linux. func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { + return IOCountersByFileWithContext(context.Background(), pernic, filename) +} + +func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) { return IOCounters(pernic) } // Return a list of network connections opened by a process func Connections(kind string) ([]ConnectionStat, error) { + return ConnectionsWithContext(context.Background(), kind) +} + +func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { var ret []ConnectionStat return ret, common.ErrNotImplementedError @@ -79,10 +92,18 @@ func Connections(kind string) ([]ConnectionStat, error) { // Return a list of network connections opened returning at most `max` // connections for each running process. func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) { + return ConnectionsMaxWithContext(context.Background(), kind, max) +} + +func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) { return []ConnectionStat{}, common.ErrNotImplementedError } func FilterCounters() ([]FilterStat, error) { + return FilterCountersWithContext(context.Background()) +} + +func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { return nil, errors.New("NetFilterCounters not implemented for windows") } @@ -91,5 +112,9 @@ func FilterCounters() ([]FilterStat, error) { // just the protocols in the list are returned. // Not Implemented for Windows func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { + return ProtoCountersWithContext(context.Background(), protocols) +} + +func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { return nil, errors.New("NetProtoCounters not implemented for windows") } diff --git a/vendor/github.com/shirou/gopsutil/process/expected/darwin/%2Fbin%2Fps-x-opid_fail b/vendor/github.com/shirou/gopsutil/process/expected/darwin/%2Fbin%2Fps-x-opid_fail deleted file mode 100644 index fce59efc0..000000000 --- a/vendor/github.com/shirou/gopsutil/process/expected/darwin/%2Fbin%2Fps-x-opid_fail +++ /dev/null @@ -1,10 +0,0 @@ - PID - 245 - 247 - 248 - 249 - 254 - 262 - 264 - 265 - 267 diff --git a/vendor/github.com/shirou/gopsutil/process/process_posix_test.go b/vendor/github.com/shirou/gopsutil/process/process_posix_test.go new file mode 100644 index 000000000..a5cacb3b1 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/process/process_posix_test.go @@ -0,0 +1,20 @@ +// +build linux freebsd + +package process + +import ( + "os" + "testing" + + "golang.org/x/sys/unix" +) + +func Test_SendSignal(t *testing.T) { + checkPid := os.Getpid() + + p, _ := NewProcess(int32(checkPid)) + err := p.SendSignal(unix.SIGCONT) + if err != nil { + t.Errorf("send signal %v", err) + } +} diff --git a/vendor/github.com/shirou/gopsutil/process/process_test.go b/vendor/github.com/shirou/gopsutil/process/process_test.go new file mode 100644 index 000000000..d8eb483b1 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/process/process_test.go @@ -0,0 +1,446 @@ +package process + +import ( + "fmt" + "os" + "os/exec" + "os/user" + "reflect" + "runtime" + "strings" + "sync" + "testing" + "time" + + "github.com/shirou/gopsutil/internal/common" + "github.com/stretchr/testify/assert" +) + +var mu sync.Mutex + +func testGetProcess() Process { + checkPid := os.Getpid() // process.test + ret, _ := NewProcess(int32(checkPid)) + return *ret +} + +func Test_Pids(t *testing.T) { + ret, err := Pids() + if err != nil { + t.Errorf("error %v", err) + } + if len(ret) == 0 { + t.Errorf("could not get pids %v", ret) + } +} + +func Test_Pids_Fail(t *testing.T) { + if runtime.GOOS != "darwin" { + t.Skip("darwin only") + } + + mu.Lock() + defer mu.Unlock() + + invoke = common.FakeInvoke{Suffix: "fail"} + ret, err := Pids() + invoke = common.Invoke{} + if err != nil { + t.Errorf("error %v", err) + } + if len(ret) != 9 { + t.Errorf("wrong getted pid nums: %v/%d", ret, len(ret)) + } +} +func Test_Pid_exists(t *testing.T) { + checkPid := os.Getpid() + + ret, err := PidExists(int32(checkPid)) + if err != nil { + t.Errorf("error %v", err) + } + + if ret == false { + t.Errorf("could not get process exists: %v", ret) + } +} + +func Test_NewProcess(t *testing.T) { + checkPid := os.Getpid() + + ret, err := NewProcess(int32(checkPid)) + if err != nil { + t.Errorf("error %v", err) + } + empty := &Process{} + if runtime.GOOS != "windows" { // Windows pid is 0 + if empty == ret { + t.Errorf("error %v", ret) + } + } + +} + +func Test_Process_memory_maps(t *testing.T) { + checkPid := os.Getpid() + + ret, err := NewProcess(int32(checkPid)) + + mmaps, err := ret.MemoryMaps(false) + if err != nil { + t.Errorf("memory map get error %v", err) + } + empty := MemoryMapsStat{} + for _, m := range *mmaps { + if m == empty { + t.Errorf("memory map get error %v", m) + } + } +} +func Test_Process_MemoryInfo(t *testing.T) { + p := testGetProcess() + + v, err := p.MemoryInfo() + if err != nil { + t.Errorf("geting memory info error %v", err) + } + empty := MemoryInfoStat{} + if v == nil || *v == empty { + t.Errorf("could not get memory info %v", v) + } +} + +func Test_Process_CmdLine(t *testing.T) { + p := testGetProcess() + + v, err := p.Cmdline() + if err != nil { + t.Errorf("geting cmdline error %v", err) + } + if !strings.Contains(v, "process.test") { + t.Errorf("invalid cmd line %v", v) + } +} + +func Test_Process_CmdLineSlice(t *testing.T) { + p := testGetProcess() + + v, err := p.CmdlineSlice() + if err != nil { + t.Fatalf("geting cmdline slice error %v", err) + } + if !reflect.DeepEqual(v, os.Args) { + t.Errorf("returned cmdline slice not as expected:\nexp: %v\ngot: %v", os.Args, v) + } +} + +func Test_Process_Ppid(t *testing.T) { + p := testGetProcess() + + v, err := p.Ppid() + if err != nil { + t.Errorf("geting ppid error %v", err) + } + if v == 0 { + t.Errorf("return value is 0 %v", v) + } +} + +func Test_Process_Status(t *testing.T) { + p := testGetProcess() + + v, err := p.Status() + if err != nil { + t.Errorf("geting status error %v", err) + } + if v != "R" && v != "S" { + t.Errorf("could not get state %v", v) + } +} + +func Test_Process_Terminal(t *testing.T) { + p := testGetProcess() + + _, err := p.Terminal() + if err != nil { + t.Errorf("geting terminal error %v", err) + } + + /* + if v == "" { + t.Errorf("could not get terminal %v", v) + } + */ +} + +func Test_Process_IOCounters(t *testing.T) { + p := testGetProcess() + + v, err := p.IOCounters() + if err != nil { + t.Errorf("geting iocounter error %v", err) + return + } + empty := &IOCountersStat{} + if v == empty { + t.Errorf("error %v", v) + } +} + +func Test_Process_NumCtx(t *testing.T) { + p := testGetProcess() + + _, err := p.NumCtxSwitches() + if err != nil { + t.Errorf("geting numctx error %v", err) + return + } +} + +func Test_Process_Nice(t *testing.T) { + p := testGetProcess() + + n, err := p.Nice() + if err != nil { + t.Errorf("geting nice error %v", err) + } + if n != 0 && n != 20 && n != 8 { + t.Errorf("invalid nice: %d", n) + } +} +func Test_Process_NumThread(t *testing.T) { + p := testGetProcess() + + n, err := p.NumThreads() + if err != nil { + t.Errorf("geting NumThread error %v", err) + } + if n < 0 { + t.Errorf("invalid NumThread: %d", n) + } +} + +func Test_Process_Threads(t *testing.T) { + p := testGetProcess() + + n, err := p.NumThreads() + if err != nil { + t.Errorf("geting NumThread error %v", err) + } + if n < 0 { + t.Errorf("invalid NumThread: %d", n) + } + + ts, err := p.Threads() + if err != nil { + t.Errorf("geting Threads error %v", err) + } + if len(ts) != int(n) { + t.Errorf("unexpected number of threads: %v vs %v", len(ts), n) + } +} + +func Test_Process_Name(t *testing.T) { + p := testGetProcess() + + n, err := p.Name() + if err != nil { + t.Errorf("geting name error %v", err) + } + if !strings.Contains(n, "process.test") { + t.Errorf("invalid Exe %s", n) + } +} +func Test_Process_Exe(t *testing.T) { + p := testGetProcess() + + n, err := p.Exe() + if err != nil { + t.Errorf("geting Exe error %v", err) + } + if !strings.Contains(n, "process.test") { + t.Errorf("invalid Exe %s", n) + } +} + +func Test_Process_CpuPercent(t *testing.T) { + p := testGetProcess() + percent, err := p.Percent(0) + if err != nil { + t.Errorf("error %v", err) + } + duration := time.Duration(1000) * time.Microsecond + time.Sleep(duration) + percent, err = p.Percent(0) + if err != nil { + t.Errorf("error %v", err) + } + + numcpu := runtime.NumCPU() + // if percent < 0.0 || percent > 100.0*float64(numcpu) { // TODO + if percent < 0.0 { + t.Fatalf("CPUPercent value is invalid: %f, %d", percent, numcpu) + } +} + +func Test_Process_CpuPercentLoop(t *testing.T) { + p := testGetProcess() + numcpu := runtime.NumCPU() + + for i := 0; i < 2; i++ { + duration := time.Duration(100) * time.Microsecond + percent, err := p.Percent(duration) + if err != nil { + t.Errorf("error %v", err) + } + // if percent < 0.0 || percent > 100.0*float64(numcpu) { // TODO + if percent < 0.0 { + t.Fatalf("CPUPercent value is invalid: %f, %d", percent, numcpu) + } + } +} + +func Test_Process_CreateTime(t *testing.T) { + if os.Getenv("CIRCLECI") == "true" { + t.Skip("Skip CI") + } + + p := testGetProcess() + + c, err := p.CreateTime() + if err != nil { + t.Errorf("error %v", err) + } + + if c < 1420000000 { + t.Errorf("process created time is wrong.") + } + + gotElapsed := time.Since(time.Unix(int64(c/1000), 0)) + maxElapsed := time.Duration(5 * time.Second) + + if gotElapsed >= maxElapsed { + t.Errorf("this process has not been running for %v", gotElapsed) + } +} + +func Test_Parent(t *testing.T) { + p := testGetProcess() + + c, err := p.Parent() + if err != nil { + t.Fatalf("error %v", err) + } + if c == nil { + t.Fatalf("could not get parent") + } + if c.Pid == 0 { + t.Fatalf("wrong parent pid") + } +} + +func Test_Connections(t *testing.T) { + p := testGetProcess() + + c, err := p.Connections() + if err != nil { + t.Fatalf("error %v", err) + } + // TODO: + // Since go test open no conneciton, ret is empty. + // should invoke child process or other solutions. + if len(c) != 0 { + t.Fatalf("wrong connections") + } +} + +func Test_Children(t *testing.T) { + p, err := NewProcess(1) + if err != nil { + t.Fatalf("new process error %v", err) + } + + c, err := p.Children() + if err != nil { + t.Fatalf("error %v", err) + } + if len(c) == 0 { + t.Fatalf("children is empty") + } +} + +func Test_Username(t *testing.T) { + myPid := os.Getpid() + currentUser, _ := user.Current() + myUsername := currentUser.Username + + process, _ := NewProcess(int32(myPid)) + pidUsername, _ := process.Username() + assert.Equal(t, myUsername, pidUsername) + + t.Log(pidUsername) +} + +func Test_CPUTimes(t *testing.T) { + pid := os.Getpid() + process, err := NewProcess(int32(pid)) + assert.Nil(t, err) + + spinSeconds := 0.2 + cpuTimes0, err := process.Times() + assert.Nil(t, err) + + // Spin for a duration of spinSeconds + t0 := time.Now() + tGoal := t0.Add(time.Duration(spinSeconds*1000) * time.Millisecond) + assert.Nil(t, err) + for time.Now().Before(tGoal) { + // This block intentionally left blank + } + + cpuTimes1, err := process.Times() + assert.Nil(t, err) + + if cpuTimes0 == nil || cpuTimes1 == nil { + t.FailNow() + } + measuredElapsed := cpuTimes1.Total() - cpuTimes0.Total() + message := fmt.Sprintf("Measured %fs != spun time of %fs\ncpuTimes0=%v\ncpuTimes1=%v", + measuredElapsed, spinSeconds, cpuTimes0, cpuTimes1) + assert.True(t, measuredElapsed > float64(spinSeconds)/5, message) + assert.True(t, measuredElapsed < float64(spinSeconds)*5, message) +} + +func Test_OpenFiles(t *testing.T) { + pid := os.Getpid() + p, err := NewProcess(int32(pid)) + assert.Nil(t, err) + + v, err := p.OpenFiles() + assert.Nil(t, err) + assert.NotEmpty(t, v) // test always open files. + + for _, vv := range v { + assert.NotEqual(t, "", vv.Path) + } +} + +func Test_Kill(t *testing.T) { + var cmd *exec.Cmd + if runtime.GOOS == "windows" { + cmd = exec.Command("choice", "/C", "YN", "/D", "Y", "/t", "3") + } else { + cmd = exec.Command("sleep", "3") + } + var wg sync.WaitGroup + wg.Add(1) + go func() { + assert.NotNil(t, cmd.Run()) + wg.Done() + }() + time.Sleep(100 * time.Millisecond) + p, err := NewProcess(int32(cmd.Process.Pid)) + assert.Nil(t, err) + assert.Nil(t, p.Kill()) + wg.Wait() +} diff --git a/vendor/github.com/shirou/gopsutil/process/process_windows.go b/vendor/github.com/shirou/gopsutil/process/process_windows.go index f4c8fe2c1..9304e2dd5 100644 --- a/vendor/github.com/shirou/gopsutil/process/process_windows.go +++ b/vendor/github.com/shirou/gopsutil/process/process_windows.go @@ -400,7 +400,7 @@ func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) } // User and kernel times are represented as a FILETIME structure - // wich contains a 64-bit value representing the number of + // which contains a 64-bit value representing the number of // 100-nanosecond intervals since January 1, 1601 (UTC): // http://msdn.microsoft.com/en-us/library/ms724284(VS.85).aspx // To convert it into a float representing the seconds that the diff --git a/vendor/github.com/shirou/gopsutil/process/types_darwin.go b/vendor/github.com/shirou/gopsutil/process/types_darwin.go new file mode 100644 index 000000000..21216cd09 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/process/types_darwin.go @@ -0,0 +1,160 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Hand Writing +// - all pointer in ExternProc to uint64 + +// +build ignore + +/* +Input to cgo -godefs. +*/ + +// +godefs map struct_in_addr [4]byte /* in_addr */ +// +godefs map struct_in6_addr [16]byte /* in6_addr */ +// +godefs map struct_ [16]byte /* in6_addr */ + +package process + +/* +#define __DARWIN_UNIX03 0 +#define KERNEL +#define _DARWIN_USE_64_BIT_INODE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + sizeofPtr = sizeof(void*), +}; + +union sockaddr_all { + struct sockaddr s1; // this one gets used for fields + struct sockaddr_in s2; // these pad it out + struct sockaddr_in6 s3; + struct sockaddr_un s4; + struct sockaddr_dl s5; +}; + +struct sockaddr_any { + struct sockaddr addr; + char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; +}; + +struct ucred_queue { + struct ucred *tqe_next; + struct ucred **tqe_prev; + TRACEBUF +}; + +*/ +import "C" + +// Machine characteristics; for internal use. + +const ( + sizeofPtr = C.sizeofPtr + sizeofShort = C.sizeof_short + sizeofInt = C.sizeof_int + sizeofLong = C.sizeof_long + sizeofLongLong = C.sizeof_longlong +) + +// Basic types + +type ( + _C_short C.short + _C_int C.int + _C_long C.long + _C_long_long C.longlong +) + +// Time + +type Timespec C.struct_timespec + +type Timeval C.struct_timeval + +// Processes + +type Rusage C.struct_rusage + +type Rlimit C.struct_rlimit + +type UGid_t C.gid_t + +type KinfoProc C.struct_kinfo_proc + +type Eproc C.struct_eproc + +type Proc C.struct_proc + +type Session C.struct_session + +type ucred C.struct_ucred + +type Uucred C.struct__ucred + +type Upcred C.struct__pcred + +type Vmspace C.struct_vmspace + +type Sigacts C.struct_sigacts + +type ExternProc C.struct_extern_proc + +type Itimerval C.struct_itimerval + +type Vnode C.struct_vnode + +type Pgrp C.struct_pgrp + +type UserStruct C.struct_user + +type Au_session C.struct_au_session + +type Posix_cred C.struct_posix_cred + +type Label C.struct_label + +type AuditinfoAddr C.struct_auditinfo_addr +type AuMask C.struct_au_mask +type AuTidAddr C.struct_au_tid_addr + +// TAILQ(ucred) +type UcredQueue C.struct_ucred_queue diff --git a/vendor/github.com/shirou/gopsutil/process/types_freebsd.go b/vendor/github.com/shirou/gopsutil/process/types_freebsd.go new file mode 100644 index 000000000..aa7b3462d --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/process/types_freebsd.go @@ -0,0 +1,95 @@ +// +build ignore + +// We still need editing by hands. +// go tool cgo -godefs types_freebsd.go | sed 's/\*int64/int64/' | sed 's/\*byte/int64/' > process_freebsd_amd64.go + +/* +Input to cgo -godefs. +*/ + +// +godefs map struct_pargs int64 /* pargs */ +// +godefs map struct_proc int64 /* proc */ +// +godefs map struct_user int64 /* user */ +// +godefs map struct_vnode int64 /* vnode */ +// +godefs map struct_vnode int64 /* vnode */ +// +godefs map struct_filedesc int64 /* filedesc */ +// +godefs map struct_vmspace int64 /* vmspace */ +// +godefs map struct_pcb int64 /* pcb */ +// +godefs map struct_thread int64 /* thread */ +// +godefs map struct___sigset [16]byte /* sigset */ + +package process + +/* +#include +#include + +enum { + sizeofPtr = sizeof(void*), +}; + + +*/ +import "C" + +// Machine characteristics; for internal use. + +const ( + CTLKern = 1 // "high kernel": proc, limits + KernProc = 14 // struct: process entries + KernProcPID = 1 // by process id + KernProcProc = 8 // only return procs + KernProcPathname = 12 // path to executable + KernProcArgs = 7 // get/set arguments/proctitle +) + +const ( + sizeofPtr = C.sizeofPtr + sizeofShort = C.sizeof_short + sizeofInt = C.sizeof_int + sizeofLong = C.sizeof_long + sizeofLongLong = C.sizeof_longlong +) + +const ( + sizeOfKinfoVmentry = C.sizeof_struct_kinfo_vmentry + sizeOfKinfoProc = C.sizeof_struct_kinfo_proc +) + +// from sys/proc.h +const ( + SIDL = 1 /* Process being created by fork. */ + SRUN = 2 /* Currently runnable. */ + SSLEEP = 3 /* Sleeping on an address. */ + SSTOP = 4 /* Process debugging or suspension. */ + SZOMB = 5 /* Awaiting collection by parent. */ + SWAIT = 6 /* Waiting for interrupt. */ + SLOCK = 7 /* Blocked on a lock. */ +) + +// Basic types + +type ( + _C_short C.short + _C_int C.int + _C_long C.long + _C_long_long C.longlong +) + +// Time + +type Timespec C.struct_timespec + +type Timeval C.struct_timeval + +// Processes + +type Rusage C.struct_rusage + +type Rlimit C.struct_rlimit + +type KinfoProc C.struct_kinfo_proc + +type Priority C.struct_priority + +type KinfoVmentry C.struct_kinfo_vmentry diff --git a/vendor/github.com/shirou/gopsutil/process/types_openbsd.go b/vendor/github.com/shirou/gopsutil/process/types_openbsd.go new file mode 100644 index 000000000..09ac59028 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/process/types_openbsd.go @@ -0,0 +1,103 @@ +// +build ignore + +// We still need editing by hands. +// go tool cgo -godefs types_openbsd.go | sed 's/\*int64/int64/' | sed 's/\*byte/int64/' > process_openbsd_amd64.go + +/* +Input to cgo -godefs. +*/ + +// +godefs map struct_pargs int64 /* pargs */ +// +godefs map struct_proc int64 /* proc */ +// +godefs map struct_user int64 /* user */ +// +godefs map struct_vnode int64 /* vnode */ +// +godefs map struct_vnode int64 /* vnode */ +// +godefs map struct_filedesc int64 /* filedesc */ +// +godefs map struct_vmspace int64 /* vmspace */ +// +godefs map struct_pcb int64 /* pcb */ +// +godefs map struct_thread int64 /* thread */ +// +godefs map struct___sigset [16]byte /* sigset */ + +package process + +/* +#include +#include +#include + +enum { + sizeofPtr = sizeof(void*), +}; + + +*/ +import "C" + +// Machine characteristics; for internal use. + +const ( + CTLKern = 1 // "high kernel": proc, limits + KernProc = 66 // struct: process entries + KernProcAll = 0 + KernProcPID = 1 // by process id + KernProcProc = 8 // only return procs + KernProcPathname = 12 // path to executable + KernProcArgs = 55 // get/set arguments/proctitle + KernProcArgv = 1 + KernProcEnv = 3 +) + +const ( + ArgMax = 256 * 1024 // sys/syslimits.h:#define ARG_MAX +) + +const ( + sizeofPtr = C.sizeofPtr + sizeofShort = C.sizeof_short + sizeofInt = C.sizeof_int + sizeofLong = C.sizeof_long + sizeofLongLong = C.sizeof_longlong +) + +const ( + sizeOfKinfoVmentry = C.sizeof_struct_kinfo_vmentry + sizeOfKinfoProc = C.sizeof_struct_kinfo_proc +) + +// from sys/proc.h +const ( + SIDL = 1 /* Process being created by fork. */ + SRUN = 2 /* Currently runnable. */ + SSLEEP = 3 /* Sleeping on an address. */ + SSTOP = 4 /* Process debugging or suspension. */ + SZOMB = 5 /* Awaiting collection by parent. */ + SDEAD = 6 /* Thread is almost gone */ + SONPROC = 7 /* Thread is currently on a CPU. */ +) + +// Basic types + +type ( + _C_short C.short + _C_int C.int + _C_long C.long + _C_long_long C.longlong +) + +// Time + +type Timespec C.struct_timespec + +type Timeval C.struct_timeval + +// Processes + +type Rusage C.struct_rusage + +type Rlimit C.struct_rlimit + +type KinfoProc C.struct_kinfo_proc + +type Priority C.struct_priority + +type KinfoVmentry C.struct_kinfo_vmentry diff --git a/vendor/vendor.json b/vendor/vendor.json index 3cc370332..d47eaa070 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -223,13 +223,13 @@ {"path":"github.com/ryanuber/columnize","checksumSHA1":"M57Rrfc8Z966p+IBtQ91QOcUtcg=","comment":"v2.0.1-8-g983d3a5","revision":"abc90934186a77966e2beeac62ed966aac0561d5","revisionTime":"2017-07-03T20:58:27Z"}, {"path":"github.com/sean-/seed","checksumSHA1":"tnMZLo/kR9Kqx6GtmWwowtTLlA8=","revision":"e2103e2c35297fb7e17febb81e49b312087a2372","revisionTime":"2017-03-13T16:33:22Z"}, {"path":"github.com/sethgrid/pester","checksumSHA1":"8Lm8nsMCFz4+gr9EvQLqK8+w+Ks=","revision":"8053687f99650573b28fb75cddf3f295082704d7","revisionTime":"2016-04-29T17:20:22Z"}, - {"path":"github.com/shirou/gopsutil/cpu","checksumSHA1":"T2ThCk35wXAZGh37nrgA07199dA=","revision":"1c211f0807a3436707409fa313599dd8c7a48664","revisionTime":"2017-08-17T03:45:37Z"}, - {"path":"github.com/shirou/gopsutil/disk","checksumSHA1":"T4uyVXPqCS5rj4vYLgv04as0Avw=","revision":"1c211f0807a3436707409fa313599dd8c7a48664","revisionTime":"2017-08-17T03:45:37Z"}, - {"path":"github.com/shirou/gopsutil/host","checksumSHA1":"YBXpUckp1TtJf2mfMLx/bpnm22Q=","revision":"1c211f0807a3436707409fa313599dd8c7a48664","revisionTime":"2017-08-17T03:45:37Z"}, - {"path":"github.com/shirou/gopsutil/internal/common","checksumSHA1":"jUWM0P4G1bHpO9CPS8gcr4rt1t0=","revision":"1c211f0807a3436707409fa313599dd8c7a48664","revisionTime":"2017-08-17T03:45:37Z"}, - {"path":"github.com/shirou/gopsutil/mem","checksumSHA1":"xIAuacHA0LNq1yM5Wd1q4lnbzxU=","revision":"1c211f0807a3436707409fa313599dd8c7a48664","revisionTime":"2017-08-17T03:45:37Z"}, - {"path":"github.com/shirou/gopsutil/net","checksumSHA1":"moxD+mq0dMHnbTeFyeEHK0Iq7i8=","revision":"1c211f0807a3436707409fa313599dd8c7a48664","revisionTime":"2017-08-17T03:45:37Z"}, - {"path":"github.com/shirou/gopsutil/process","checksumSHA1":"Ylp6t7kozHBFREv3tBcK4B1SMI4=","revision":"12ab94e8042b4639d3cbd6bdafd0be9be8a33e88","revisionTime":"2018-02-21T07:26:18Z"}, + {"path":"github.com/shirou/gopsutil/cpu","checksumSHA1":"k+PmW/6PFt0FVFTTnfMbWwrm9hU=","revision":"5776ff9c7c5d063d574ef53d740f75c68b448e53","revisionTime":"2018-02-27T22:58:47Z","tree":true}, + {"path":"github.com/shirou/gopsutil/disk","checksumSHA1":"4DZwA8Xf2Zs8vhIc9kx8TIBMmSY=","revision":"5776ff9c7c5d063d574ef53d740f75c68b448e53","revisionTime":"2018-02-27T22:58:47Z","tree":true}, + {"path":"github.com/shirou/gopsutil/host","checksumSHA1":"EwRUlC1p+bryrvxV3UqgDcauZ0U=","revision":"5776ff9c7c5d063d574ef53d740f75c68b448e53","revisionTime":"2018-02-27T22:58:47Z","tree":true}, + {"path":"github.com/shirou/gopsutil/internal/common","checksumSHA1":"S31u6j9yi6MOblZ1x83k/HDuNtA=","revision":"5776ff9c7c5d063d574ef53d740f75c68b448e53","revisionTime":"2018-02-27T22:58:47Z","tree":true}, + {"path":"github.com/shirou/gopsutil/mem","checksumSHA1":"1u1St5K2LtEcQsh5ySmvoTZ8k0I=","revision":"5776ff9c7c5d063d574ef53d740f75c68b448e53","revisionTime":"2018-02-27T22:58:47Z","tree":true}, + {"path":"github.com/shirou/gopsutil/net","checksumSHA1":"ME2P9hiaHO/YdVrNInDmb/dB6us=","revision":"5776ff9c7c5d063d574ef53d740f75c68b448e53","revisionTime":"2018-02-27T22:58:47Z","tree":true}, + {"path":"github.com/shirou/gopsutil/process","checksumSHA1":"JuBAKUuSyR7RdJELt6tQMn79Y6w=","revision":"5776ff9c7c5d063d574ef53d740f75c68b448e53","revisionTime":"2018-02-27T22:58:47Z","tree":true}, {"path":"github.com/shirou/w32","checksumSHA1":"Nve7SpDmjsv6+rhkXAkfg/UQx94=","revision":"bb4de0191aa41b5507caa14b0650cdbddcd9280b","revisionTime":"2016-09-30T03:27:40Z"}, {"path":"github.com/skratchdot/open-golang/open","checksumSHA1":"h/HMhokbQHTdLUbruoBBTee+NYw=","revision":"75fb7ed4208cf72d323d7d02fd1a5964a7a9073c","revisionTime":"2016-03-02T14:40:31Z"}, {"path":"github.com/spf13/pflag","checksumSHA1":"Q52Y7t0lEtk/wcDn5q7tS7B+jqs=","revision":"7aff26db30c1be810f9de5038ec5ef96ac41fd7c","revisionTime":"2017-08-24T17:57:12Z"},