diff --git a/.go-version b/.go-version index 8fdcf386946..d615fd0c04a 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.9.2 +1.9.4 diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 00845d8dfa8..1009a7e0e73 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -82,6 +82,7 @@ https://github.com/elastic/beats/compare/v6.0.0-beta2...master[Check the HEAD di - Fix isolation of modules when merging local and global field settings. {issue}5795[5795] - Fix panic when Events containing a float32 value are normalized. {pull}6129[6129] - Fix `setup.dashboards.always_kibana` when using Kibana 5.6. {issue}6090[6090] +- Update Golang 1.9.4 {pull}6326[6326] *Auditbeat* diff --git a/NOTICE.txt b/NOTICE.txt index 058dde242fd..6ebd90f9a66 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -2843,8 +2843,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------- Dependency: github.com/shirou/gopsutil -Version: v2.17.04 -Revision: 9af92986dda65a8c367157a82b484553e1ec1c55 +Version: v2.18.01 +Revision: c432be29ccce470088d07eea25b3ea7e68a8afbb License type (autodetected): BSD-3-Clause ./vendor/github.com/shirou/gopsutil/LICENSE: -------------------------------------------------------------------- diff --git a/Vagrantfile b/Vagrantfile index 404172a5362..d36b2f742d2 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -63,7 +63,7 @@ if [ ! -e "~/bin/gvm" ]; then chmod +x ~/bin/gvm echo 'export GOPATH=$HOME/go' >> ~/.bash_profile echo 'export PATH=$HOME/bin:$GOPATH/bin:$PATH' >> ~/.bash_profile - echo 'eval "$(gvm 1.9.2)"' >> ~/.bash_profile + echo 'eval "$(gvm 1.9.4)"' >> ~/.bash_profile fi SCRIPT diff --git a/dev-tools/packer/docker/xgo-image-deb6/beats-builder/Dockerfile b/dev-tools/packer/docker/xgo-image-deb6/beats-builder/Dockerfile index 87be67de9ef..658b446ac88 100644 --- a/dev-tools/packer/docker/xgo-image-deb6/beats-builder/Dockerfile +++ b/dev-tools/packer/docker/xgo-image-deb6/beats-builder/Dockerfile @@ -1,4 +1,4 @@ -FROM tudorg/xgo-deb6-1.9.2 +FROM tudorg/xgo-deb6-1.9.4 MAINTAINER Tudor Golubenco diff --git a/dev-tools/packer/docker/xgo-image-deb6/build.sh b/dev-tools/packer/docker/xgo-image-deb6/build.sh index 4d266530346..5dfd985eb72 100755 --- a/dev-tools/packer/docker/xgo-image-deb6/build.sh +++ b/dev-tools/packer/docker/xgo-image-deb6/build.sh @@ -1,5 +1,5 @@ #!/bin/sh docker build --rm=true -t tudorg/xgo-deb6-base base/ && \ - docker build --rm=true -t tudorg/xgo-deb6-1.9.2 go-1.9.2/ && + docker build --rm=true -t tudorg/xgo-deb6-1.9.4 go-1.9.4/ && docker build --rm=true -t tudorg/beats-builder-deb6 beats-builder diff --git a/dev-tools/packer/docker/xgo-image-deb6/go-1.9.2/Dockerfile b/dev-tools/packer/docker/xgo-image-deb6/go-1.9.4/Dockerfile similarity index 66% rename from dev-tools/packer/docker/xgo-image-deb6/go-1.9.2/Dockerfile rename to dev-tools/packer/docker/xgo-image-deb6/go-1.9.4/Dockerfile index 915a304ac47..fa49ded933e 100644 --- a/dev-tools/packer/docker/xgo-image-deb6/go-1.9.2/Dockerfile +++ b/dev-tools/packer/docker/xgo-image-deb6/go-1.9.4/Dockerfile @@ -1,4 +1,4 @@ -# Go cross compiler (xgo): Go 1.9.2 layer +# Go cross compiler (xgo): Go 1.9.4 layer # Copyright (c) 2014 Péter Szilágyi. All rights reserved. # # Released under the MIT license. @@ -9,7 +9,7 @@ MAINTAINER Tudor Golubenco # Configure the root Go distribution and bootstrap based on it RUN \ - export ROOT_DIST="https://storage.googleapis.com/golang/go1.9.2.linux-amd64.tar.gz" && \ - export ROOT_DIST_SHA1="94c889e039e3d2e94ed95e8f8cb747c5bc1c2b58" && \ + export ROOT_DIST="https://storage.googleapis.com/golang/go1.9.4.linux-amd64.tar.gz" && \ + export ROOT_DIST_SHA1="15b0937615809f87321a457bb1265f946f9f6e736c563d6c5e0bd2c22e44f779" && \ \ $BOOTSTRAP_PURE diff --git a/dev-tools/packer/docker/xgo-image/beats-builder/Dockerfile b/dev-tools/packer/docker/xgo-image/beats-builder/Dockerfile index c1623d76d4f..b4428d6bd6b 100644 --- a/dev-tools/packer/docker/xgo-image/beats-builder/Dockerfile +++ b/dev-tools/packer/docker/xgo-image/beats-builder/Dockerfile @@ -1,4 +1,4 @@ -FROM tudorg/xgo-1.9.2 +FROM tudorg/xgo-1.9.4 MAINTAINER Tudor Golubenco diff --git a/dev-tools/packer/docker/xgo-image/build.sh b/dev-tools/packer/docker/xgo-image/build.sh index ac6c4e71578..4bdf09a9eef 100755 --- a/dev-tools/packer/docker/xgo-image/build.sh +++ b/dev-tools/packer/docker/xgo-image/build.sh @@ -1,5 +1,5 @@ #!/bin/sh docker build --rm=true -t tudorg/xgo-base base/ && \ - docker build --rm=true -t tudorg/xgo-1.9.2 go-1.9.2/ && + docker build --rm=true -t tudorg/xgo-1.9.4 go-1.9.4/ && docker build --rm=true -t tudorg/beats-builder beats-builder diff --git a/dev-tools/packer/docker/xgo-image/go-1.9.2/Dockerfile b/dev-tools/packer/docker/xgo-image/go-1.9.4/Dockerfile similarity index 66% rename from dev-tools/packer/docker/xgo-image/go-1.9.2/Dockerfile rename to dev-tools/packer/docker/xgo-image/go-1.9.4/Dockerfile index 28a60254297..14c2035ab53 100644 --- a/dev-tools/packer/docker/xgo-image/go-1.9.2/Dockerfile +++ b/dev-tools/packer/docker/xgo-image/go-1.9.4/Dockerfile @@ -1,4 +1,4 @@ -# Go cross compiler (xgo): Go 1.9.2 layer +# Go cross compiler (xgo): Go 1.9.4 layer # Copyright (c) 2014 Péter Szilágyi. All rights reserved. # # Released under the MIT license. @@ -9,7 +9,7 @@ MAINTAINER Tudor Golubenco # Configure the root Go distribution and bootstrap based on it RUN \ - export ROOT_DIST="https://storage.googleapis.com/golang/go1.9.2.linux-amd64.tar.gz" && \ - export ROOT_DIST_SHA1="94c889e039e3d2e94ed95e8f8cb747c5bc1c2b58" && \ + export ROOT_DIST="https://storage.googleapis.com/golang/go1.9.4.linux-amd64.tar.gz" && \ + export ROOT_DIST_SHA1="15b0937615809f87321a457bb1265f946f9f6e736c563d6c5e0bd2c22e44f779" && \ \ $BOOTSTRAP_PURE diff --git a/filebeat/Dockerfile b/filebeat/Dockerfile index b5557a4f64a..fcd088da096 100644 --- a/filebeat/Dockerfile +++ b/filebeat/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.9.2 +FROM golang:1.9.4 MAINTAINER Nicolas Ruflin RUN set -x && \ diff --git a/generator/beat/{beat}/.travis.yml b/generator/beat/{beat}/.travis.yml index 30a20005658..1fa58d5d93f 100644 --- a/generator/beat/{beat}/.travis.yml +++ b/generator/beat/{beat}/.travis.yml @@ -6,7 +6,7 @@ services: language: go go: - - 1.9.2 + - 1.9.4 os: - linux diff --git a/libbeat/Dockerfile b/libbeat/Dockerfile index 9b45ebbf5f3..994fe630744 100644 --- a/libbeat/Dockerfile +++ b/libbeat/Dockerfile @@ -1,5 +1,5 @@ # Beats dockerfile used for testing -FROM golang:1.9.2 +FROM golang:1.9.4 MAINTAINER Nicolas Ruflin RUN set -x && \ diff --git a/libbeat/docs/version.asciidoc b/libbeat/docs/version.asciidoc index 2dc336a7c60..6298a5b5fb4 100644 --- a/libbeat/docs/version.asciidoc +++ b/libbeat/docs/version.asciidoc @@ -1,6 +1,6 @@ :stack-version: 7.0.0-alpha1 :doc-branch: master -:go-version: 1.9.2 +:go-version: 1.9.4 :release-state: unreleased :python: 2.7.9 :docker: 1.12 diff --git a/libbeat/scripts/Makefile b/libbeat/scripts/Makefile index efa3739fc5a..614f1a1c65f 100755 --- a/libbeat/scripts/Makefile +++ b/libbeat/scripts/Makefile @@ -52,7 +52,7 @@ NOSETESTS_OPTIONS?=--process-timeout=$(TIMEOUT) --with-timer -v --with-xunit --x TEST_ENVIRONMENT?=false ## @testing if true, "make testsuite" runs integration tests and system tests in a dockerized test environment SYSTEM_TESTS?=false ## @testing if true, "make test" and "make testsuite" run unit tests and system tests STRESS_TESTS?=false ## @testing if true, "make test" and "make testsuite" run also run the stress tests -GOX_OS?=linux darwin windows solaris freebsd netbsd openbsd ## @Building List of all OS to be supported by "make crosscompile". +GOX_OS?=linux darwin windows freebsd netbsd openbsd ## @Building List of all OS to be supported by "make crosscompile". GOX_OSARCH?=!darwin/arm !darwin/arm64 !darwin/386 ## @building Space separated list of GOOS/GOARCH pairs to build by "make crosscompile". GOX_FLAGS?= ## @building Additional flags to append to the gox command used by "make crosscompile". TESTING_ENVIRONMENT?=snapshot## @testing The name of the environment under test diff --git a/metricbeat/Dockerfile b/metricbeat/Dockerfile index 8a1fad093c4..a4c4b4276c6 100644 --- a/metricbeat/Dockerfile +++ b/metricbeat/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.9.2 +FROM golang:1.9.4 MAINTAINER Nicolas Ruflin RUN set -x && \ diff --git a/metricbeat/Makefile b/metricbeat/Makefile index 76e1d2e2450..f8ca364eac8 100644 --- a/metricbeat/Makefile +++ b/metricbeat/Makefile @@ -11,7 +11,7 @@ GOPACKAGES=$(shell go list ${BEAT_PATH}/... | grep -v /vendor/) ES_BEATS?=.. # Metricbeat can only be cross-compiled on platforms not requiring CGO. -GOX_OS=solaris netbsd linux windows +GOX_OS=netbsd linux windows GOX_FLAGS=-arch="amd64 386 arm ppc64 ppc64le" diff --git a/metricbeat/module/http/_meta/Dockerfile b/metricbeat/module/http/_meta/Dockerfile index 3cb268505db..b422466c174 100644 --- a/metricbeat/module/http/_meta/Dockerfile +++ b/metricbeat/module/http/_meta/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.9.2 +FROM golang:1.9.4 COPY test/main.go main.go diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_darwin.go b/vendor/github.com/shirou/gopsutil/disk/disk_darwin.go index dc642df3e11..82ffacbd0a1 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_darwin.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_darwin.go @@ -3,14 +3,19 @@ package disk import ( + "context" "path" - "syscall" "unsafe" "github.com/shirou/gopsutil/internal/common" + "golang.org/x/sys/unix" ) 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,13 +93,17 @@ 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 { _p0 = unsafe.Pointer(&buf[0]) bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf)) } - r0, _, e1 := syscall.Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags)) + r0, _, e1 := unix.Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags)) n = int(r0) if e1 != 0 { err = e1 @@ -102,6 +111,6 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { return } -func getFsType(stat syscall.Statfs_t) string { +func getFsType(stat unix.Statfs_t) string { return common.IntToString(stat.Fstypename[:]) } 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 2f5e22b64e2..480e2377075 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_darwin_cgo.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_darwin_cgo.go @@ -4,8 +4,7 @@ package disk /* -#cgo CFLAGS: -mmacosx-version-min=10.10 -DMACOSX_DEPLOYMENT_TARGET=10.10 -#cgo LDFLAGS: -mmacosx-version-min=10.10 -lobjc -framework Foundation -framework IOKit +#cgo LDFLAGS: -lobjc -framework Foundation -framework IOKit #include // ### enough? @@ -27,6 +26,7 @@ typedef struct import "C" import ( + "context" "errors" "strings" "unsafe" @@ -35,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 60fd7a6cebc..fe76d83e5b3 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 db521842d82..22eb50794b3 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_fallback.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_fallback.go @@ -1,17 +1,33 @@ -// +build !darwin,!linux,!freebsd,!openbsd,!windows +// +build !darwin,!linux,!freebsd,!openbsd,!windows,!solaris 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 8569d14c478..bfb6580c2fe 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_freebsd.go @@ -4,20 +4,26 @@ package disk import ( "bytes" + "context" "encoding/binary" "path" "strconv" - "syscall" "unsafe" + "golang.org/x/sys/unix" + "github.com/shirou/gopsutil/internal/common" ) 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 - count, err := syscall.Getfsstat(nil, MNT_WAIT) + count, err := unix.Getfsstat(nil, MNT_WAIT) if err != nil { return ret, err } @@ -95,11 +101,15 @@ 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) - r, err := syscall.Sysctl("kern.devstat.all") + r, err := unix.Sysctl("kern.devstat.all") if err != nil { return nil, err } @@ -149,13 +159,17 @@ 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 { _p0 = unsafe.Pointer(&buf[0]) bufsize = unsafe.Sizeof(Statfs{}) * uintptr(len(buf)) } - r0, _, e1 := syscall.Syscall(syscall.SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) + r0, _, e1 := unix.Syscall(unix.SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) n = int(r0) if e1 != 0 { err = e1 @@ -175,6 +189,6 @@ func parseDevstat(buf []byte) (Devstat, error) { return ds, nil } -func getFsType(stat syscall.Statfs_t) string { +func getFsType(stat unix.Statfs_t) string { return common.IntToString(stat.Fstypename[:]) } diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_linux.go b/vendor/github.com/shirou/gopsutil/disk/disk_linux.go index 5595b764a46..f5eb5261bdc 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_linux.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_linux.go @@ -3,11 +3,14 @@ package disk import ( + "context" "fmt" "os/exec" + "path/filepath" "strconv" "strings" - "syscall" + + "golang.org/x/sys/unix" "github.com/shirou/gopsutil/internal/common" ) @@ -214,10 +217,12 @@ var fsTypeMap = map[int64]string{ // Partitions returns disk partitions. If all is false, returns // physical devices only (e.g. hard disks, cd-rom drives, USB keys) // and ignore all others (e.g. memory partitions such as /dev/shm) -// -// should use setmntent(3) but this implement use /etc/mtab file func Partitions(all bool) ([]PartitionStat, error) { - filename := common.HostEtc("mtab") + 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 { return nil, err @@ -273,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 { @@ -281,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 { @@ -364,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 { @@ -388,7 +406,7 @@ func GetDiskSerialNumber(name string) string { return "" } -func getFsType(stat syscall.Statfs_t) string { +func getFsType(stat unix.Statfs_t) string { t := int64(stat.Type) ret, ok := fsTypeMap[t] if !ok { diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_openbsd.go b/vendor/github.com/shirou/gopsutil/disk/disk_openbsd.go index 28866df76f4..0ac752a5ab8 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_openbsd.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_openbsd.go @@ -4,19 +4,24 @@ package disk import ( "bytes" + "context" "encoding/binary" "path" - "syscall" "unsafe" "github.com/shirou/gopsutil/internal/common" + "golang.org/x/sys/unix" ) 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 - count, err := syscall.Getfsstat(nil, MNT_WAIT) + count, err := unix.Getfsstat(nil, MNT_WAIT) if err != nil { return ret, err } @@ -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 := syscall.Sysctl("hw.diskstats") + r, err := unix.SysctlRaw("hw.diskstats") if err != nil { return nil, err } @@ -106,13 +115,17 @@ 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 { _p0 = unsafe.Pointer(&buf[0]) bufsize = unsafe.Sizeof(Statfs{}) * uintptr(len(buf)) } - r0, _, e1 := syscall.Syscall(syscall.SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) + r0, _, e1 := unix.Syscall(unix.SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags)) n = int(r0) if e1 != 0 { err = e1 @@ -133,8 +146,12 @@ func parseDiskstats(buf []byte) (Diskstats, error) { } func Usage(path string) (*UsageStat, error) { - stat := syscall.Statfs_t{} - err := syscall.Statfs(path, &stat) + 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 { return nil, err } @@ -157,6 +174,6 @@ func Usage(path string) (*UsageStat, error) { return ret, nil } -func getFsType(stat syscall.Statfs_t) string { +func getFsType(stat unix.Statfs_t) string { return common.IntToString(stat.F_fstypename[:]) } 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 00000000000..c660835777e --- /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 f0616c30aaa..bafef513d45 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_unix.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_unix.go @@ -2,11 +2,22 @@ package disk -import "syscall" +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) { - stat := syscall.Statfs_t{} - err := syscall.Statfs(path, &stat) + 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 { return nil, err } diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_windows.go b/vendor/github.com/shirou/gopsutil/disk/disk_windows.go index ca16a4aa24c..7389b5a7c51 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_windows.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_windows.go @@ -4,12 +4,11 @@ package disk import ( "bytes" - "syscall" + "context" "unsafe" - "github.com/StackExchange/wmi" - "github.com/shirou/gopsutil/internal/common" + "golang.org/x/sys/windows" ) var ( @@ -37,13 +36,17 @@ 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) lpTotalNumberOfBytes := int64(0) lpTotalNumberOfFreeBytes := int64(0) diskret, _, err := procGetDiskFreeSpaceExW.Call( - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), + uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(path))), uintptr(unsafe.Pointer(&lpFreeBytesAvailable)), uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)), uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes))) @@ -65,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( @@ -79,20 +86,20 @@ func Partitions(all bool) ([]PartitionStat, error) { if path == "A:" || path == "B:" { // skip floppy drives continue } - typepath, _ := syscall.UTF16PtrFromString(path) + typepath, _ := windows.UTF16PtrFromString(path) typeret, _, _ := procGetDriveType.Call(uintptr(unsafe.Pointer(typepath))) if typeret == 0 { - return ret, syscall.GetLastError() + return ret, windows.GetLastError() } - // 2: DRIVE_REMOVABLE 3: DRIVE_FIXED 5: DRIVE_CDROM + // 2: DRIVE_REMOVABLE 3: DRIVE_FIXED 4: DRIVE_REMOTE 5: DRIVE_CDROM - if typeret == 2 || typeret == 3 || typeret == 5 { + if typeret == 2 || typeret == 3 || typeret == 4 || typeret == 5 { lpVolumeNameBuffer := make([]byte, 256) lpVolumeSerialNumber := int64(0) lpMaximumComponentLength := int64(0) lpFileSystemFlags := int64(0) lpFileSystemNameBuffer := make([]byte, 256) - volpath, _ := syscall.UTF16PtrFromString(string(v) + ":/") + volpath, _ := windows.UTF16PtrFromString(string(v) + ":/") driveret, _, err := provGetVolumeInformation.Call( uintptr(unsafe.Pointer(volpath)), uintptr(unsafe.Pointer(&lpVolumeNameBuffer[0])), @@ -103,7 +110,7 @@ func Partitions(all bool) ([]PartitionStat, error) { uintptr(unsafe.Pointer(&lpFileSystemNameBuffer[0])), uintptr(len(lpFileSystemNameBuffer))) if driveret == 0 { - if typeret == 5 { + if typeret == 5 || typeret == 2 { continue //device is not ready will happen if there is no disk in the drive } return ret, err @@ -130,10 +137,16 @@ 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) + ctx, cancel := context.WithTimeout(context.Background(), common.Timeout) + defer cancel() + 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 dd6ddc4f728..00000000000 --- 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 1e3ddef5cfb..00000000000 --- 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/doc.go b/vendor/github.com/shirou/gopsutil/doc.go new file mode 100644 index 00000000000..6a65fe268a9 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/doc.go @@ -0,0 +1 @@ +package gopsutil diff --git a/vendor/github.com/shirou/gopsutil/internal/common/common.go b/vendor/github.com/shirou/gopsutil/internal/common/common.go index cb6d3f3a75f..fcee6be85a6 100644 --- a/vendor/github.com/shirou/gopsutil/internal/common/common.go +++ b/vendor/github.com/shirou/gopsutil/internal/common/common.go @@ -9,10 +9,10 @@ package common import ( "bufio" "bytes" + "context" "errors" "fmt" "io/ioutil" - "log" "net/url" "os" "os/exec" @@ -27,7 +27,7 @@ import ( var ( Timeout = 3 * time.Second - ErrTimeout = errors.New("Command timed out.") + ErrTimeout = errors.New("command timed out") ) type Invoker interface { @@ -37,8 +37,24 @@ type Invoker interface { type Invoke struct{} func (i Invoke) Command(name string, arg ...string) ([]byte, error) { - cmd := exec.Command(name, arg...) - return CombinedOutputTimeout(cmd, Timeout) + ctxt, cancel := context.WithTimeout(context.Background(), Timeout) + defer cancel() + + cmd := exec.CommandContext(ctxt, name, arg...) + + var buf bytes.Buffer + cmd.Stdout = &buf + cmd.Stderr = &buf + + if err := cmd.Start(); err != nil { + return buf.Bytes(), err + } + + if err := cmd.Wait(); err != nil { + return buf.Bytes(), err + } + + return buf.Bytes(), nil } type FakeInvoke struct { @@ -300,42 +316,8 @@ func HostEtc(combineWith ...string) string { return GetEnv("HOST_ETC", "/etc", combineWith...) } -// CombinedOutputTimeout runs the given command with the given timeout and -// returns the combined output of stdout and stderr. -// If the command times out, it attempts to kill the process. -// copied from https://github.com/influxdata/telegraf -func CombinedOutputTimeout(c *exec.Cmd, timeout time.Duration) ([]byte, error) { - var b bytes.Buffer - c.Stdout = &b - c.Stderr = &b - if err := c.Start(); err != nil { - return nil, err - } - err := WaitTimeout(c, timeout) - return b.Bytes(), err -} - -// WaitTimeout waits for the given command to finish with a timeout. -// It assumes the command has already been started. -// If the command times out, it attempts to kill the process. -// copied from https://github.com/influxdata/telegraf -func WaitTimeout(c *exec.Cmd, timeout time.Duration) error { - timer := time.NewTimer(timeout) - done := make(chan error) - go func() { done <- c.Wait() }() - select { - case err := <-done: - timer.Stop() - return err - case <-timer.C: - if err := c.Process.Kill(); err != nil { - log.Printf("FATAL error killing process: %s", err) - return err - } - // wait for the command to return after killing it - <-done - return ErrTimeout - } +func HostVar(combineWith ...string) string { + return GetEnv("HOST_VAR", "/var", combineWith...) } // https://gist.github.com/kylelemons/1525278 @@ -380,3 +362,19 @@ func Pipeline(cmds ...*exec.Cmd) ([]byte, []byte, error) { // Return the pipeline output and the collected standard error return output.Bytes(), stderr.Bytes(), nil } + +// getSysctrlEnv sets LC_ALL=C in a list of env vars for use when running +// sysctl commands (see DoSysctrl). +func getSysctrlEnv(env []string) []string { + foundLC := false + for i, line := range env { + if strings.HasPrefix(line, "LC_ALL") { + env[i] = "LC_ALL=C" + foundLC = true + } + } + if !foundLC { + env = append(env, "LC_ALL=C") + } + return env +} diff --git a/vendor/github.com/shirou/gopsutil/internal/common/common_darwin.go b/vendor/github.com/shirou/gopsutil/internal/common/common_darwin.go index 2e1552aeee3..2b6d4c149d0 100644 --- a/vendor/github.com/shirou/gopsutil/internal/common/common_darwin.go +++ b/vendor/github.com/shirou/gopsutil/internal/common/common_darwin.go @@ -6,21 +6,19 @@ import ( "os" "os/exec" "strings" - "syscall" "unsafe" + + "golang.org/x/sys/unix" ) func DoSysctrl(mib string) ([]string, error) { - err := os.Setenv("LC_ALL", "C") - if err != nil { - return []string{}, err - } - sysctl, err := exec.LookPath("/usr/sbin/sysctl") if err != nil { return []string{}, err } - out, err := exec.Command(sysctl, "-n", mib).Output() + cmd := exec.Command(sysctl, "-n", mib) + cmd.Env = getSysctrlEnv(os.Environ()) + out, err := cmd.Output() if err != nil { return []string{}, err } @@ -36,8 +34,8 @@ func CallSyscall(mib []int32) ([]byte, uint64, error) { // get required buffer size length := uint64(0) - _, _, err := syscall.Syscall6( - syscall.SYS___SYSCTL, + _, _, err := unix.Syscall6( + unix.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), uintptr(miblen), 0, @@ -54,8 +52,8 @@ func CallSyscall(mib []int32) ([]byte, uint64, error) { } // get proc info itself buf := make([]byte, length) - _, _, err = syscall.Syscall6( - syscall.SYS___SYSCTL, + _, _, err = unix.Syscall6( + unix.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), uintptr(miblen), uintptr(unsafe.Pointer(&buf[0])), diff --git a/vendor/github.com/shirou/gopsutil/internal/common/common_freebsd.go b/vendor/github.com/shirou/gopsutil/internal/common/common_freebsd.go index bda4ecfa526..107e2c9cf92 100644 --- a/vendor/github.com/shirou/gopsutil/internal/common/common_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/internal/common/common_freebsd.go @@ -6,20 +6,19 @@ import ( "os" "os/exec" "strings" - "syscall" "unsafe" + + "golang.org/x/sys/unix" ) func DoSysctrl(mib string) ([]string, error) { - err := os.Setenv("LC_ALL", "C") - if err != nil { - return []string{}, err - } sysctl, err := exec.LookPath("/sbin/sysctl") if err != nil { return []string{}, err } - out, err := exec.Command(sysctl, "-n", mib).Output() + cmd := exec.Command(sysctl, "-n", mib) + cmd.Env = getSysctrlEnv(os.Environ()) + out, err := cmd.Output() if err != nil { return []string{}, err } @@ -36,8 +35,8 @@ func CallSyscall(mib []int32) ([]byte, uint64, error) { // get required buffer size length := uint64(0) - _, _, err := syscall.Syscall6( - syscall.SYS___SYSCTL, + _, _, err := unix.Syscall6( + unix.SYS___SYSCTL, uintptr(mibptr), uintptr(miblen), 0, @@ -54,8 +53,8 @@ func CallSyscall(mib []int32) ([]byte, uint64, error) { } // get proc info itself buf := make([]byte, length) - _, _, err = syscall.Syscall6( - syscall.SYS___SYSCTL, + _, _, err = unix.Syscall6( + unix.SYS___SYSCTL, uintptr(mibptr), uintptr(miblen), uintptr(unsafe.Pointer(&buf[0])), diff --git a/vendor/github.com/shirou/gopsutil/internal/common/common_linux.go b/vendor/github.com/shirou/gopsutil/internal/common/common_linux.go index 3d0fc50d668..4e829e057fd 100644 --- a/vendor/github.com/shirou/gopsutil/internal/common/common_linux.go +++ b/vendor/github.com/shirou/gopsutil/internal/common/common_linux.go @@ -9,15 +9,13 @@ import ( ) func DoSysctrl(mib string) ([]string, error) { - err := os.Setenv("LC_ALL", "C") - if err != nil { - return []string{}, err - } sysctl, err := exec.LookPath("/sbin/sysctl") if err != nil { return []string{}, err } - out, err := exec.Command(sysctl, "-n", mib).Output() + cmd := exec.Command(sysctl, "-n", mib) + cmd.Env = getSysctrlEnv(os.Environ()) + out, err := cmd.Output() if err != nil { return []string{}, err } @@ -35,7 +33,7 @@ func NumProcs() (uint64, error) { } defer f.Close() - list, err := f.Readdir(-1) + list, err := f.Readdirnames(-1) if err != nil { return 0, err } diff --git a/vendor/github.com/shirou/gopsutil/internal/common/common_openbsd.go b/vendor/github.com/shirou/gopsutil/internal/common/common_openbsd.go index 959d9e56df9..398f78542e9 100644 --- a/vendor/github.com/shirou/gopsutil/internal/common/common_openbsd.go +++ b/vendor/github.com/shirou/gopsutil/internal/common/common_openbsd.go @@ -6,20 +6,19 @@ import ( "os" "os/exec" "strings" - "syscall" "unsafe" + + "golang.org/x/sys/unix" ) func DoSysctrl(mib string) ([]string, error) { - err := os.Setenv("LC_ALL", "C") - if err != nil { - return []string{}, err - } sysctl, err := exec.LookPath("/sbin/sysctl") if err != nil { return []string{}, err } - out, err := exec.Command(sysctl, "-n", mib).Output() + cmd := exec.Command(sysctl, "-n", mib) + cmd.Env = getSysctrlEnv(os.Environ()) + out, err := cmd.Output() if err != nil { return []string{}, err } @@ -36,8 +35,8 @@ func CallSyscall(mib []int32) ([]byte, uint64, error) { // get required buffer size length := uint64(0) - _, _, err := syscall.Syscall6( - syscall.SYS___SYSCTL, + _, _, err := unix.Syscall6( + unix.SYS___SYSCTL, uintptr(mibptr), uintptr(miblen), 0, @@ -54,8 +53,8 @@ func CallSyscall(mib []int32) ([]byte, uint64, error) { } // get proc info itself buf := make([]byte, length) - _, _, err = syscall.Syscall6( - syscall.SYS___SYSCTL, + _, _, err = unix.Syscall6( + unix.SYS___SYSCTL, uintptr(mibptr), uintptr(miblen), uintptr(unsafe.Pointer(&buf[0])), 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 d727378cbeb..1dffe615856 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,11 @@ package common import ( - "syscall" + "context" "unsafe" + + "github.com/StackExchange/wmi" + "golang.org/x/sys/windows" ) // for double values @@ -44,9 +47,10 @@ const ( ) var ( - Modkernel32 = syscall.NewLazyDLL("kernel32.dll") - ModNt = syscall.NewLazyDLL("ntdll.dll") - ModPdh = syscall.NewLazyDLL("pdh.dll") + 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") @@ -77,13 +81,13 @@ func BytePtrToString(p *uint8) string { type CounterInfo struct { PostName string CounterName string - Counter syscall.Handle + Counter windows.Handle } // CreateQuery XXX // copied from https://github.com/mackerelio/mackerel-agent/ -func CreateQuery() (syscall.Handle, error) { - var query syscall.Handle +func CreateQuery() (windows.Handle, error) { + var query windows.Handle r, _, err := PdhOpenQuery.Call(0, 0, uintptr(unsafe.Pointer(&query))) if r != 0 { return 0, err @@ -92,11 +96,11 @@ func CreateQuery() (syscall.Handle, error) { } // CreateCounter XXX -func CreateCounter(query syscall.Handle, pname, cname string) (*CounterInfo, error) { - var counter syscall.Handle +func CreateCounter(query windows.Handle, pname, cname string) (*CounterInfo, error) { + var counter windows.Handle r, _, err := PdhAddCounter.Call( uintptr(query), - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(cname))), + uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(cname))), 0, uintptr(unsafe.Pointer(&counter))) if r != 0 { @@ -108,3 +112,18 @@ func CreateCounter(query syscall.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 { + 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/net/net.go b/vendor/github.com/shirou/gopsutil/net/net.go index 48660ec747e..428e68e1eb3 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 f1065c6d01f..2afb0f0898a 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" @@ -18,7 +19,7 @@ var ( const endOfLine = "\n" -func parseNetstatLine(line string) (stat *IOCountersStat, linkId *uint, err error) { +func parseNetstatLine(line string) (stat *IOCountersStat, linkID *uint, err error) { var ( numericValue uint64 columns = strings.Fields(line) @@ -35,8 +36,8 @@ func parseNetstatLine(line string) (stat *IOCountersStat, linkId *uint, err erro if err != nil { return } - linkIdUint := uint(numericValue) - linkId = &linkIdUint + linkIDUint := uint(numericValue) + linkID = &linkIDUint } base := 1 @@ -91,7 +92,7 @@ func parseNetstatLine(line string) (stat *IOCountersStat, linkId *uint, err erro } type netstatInterface struct { - linkId *uint + linkID *uint stat *IOCountersStat } @@ -112,7 +113,7 @@ func parseNetstatOutput(output string) ([]netstatInterface, error) { for index := 0; index < numberInterfaces; index++ { nsIface := netstatInterface{} - if nsIface.stat, nsIface.linkId, err = parseNetstatLine(lines[index+1]); err != nil { + if nsIface.stat, nsIface.linkID, err = parseNetstatLine(lines[index+1]); err != nil { return nil, err } interfaces[index] = nsIface @@ -126,7 +127,7 @@ type mapInterfaceNameUsage map[string]uint func newMapInterfaceNameUsage(ifaces []netstatInterface) mapInterfaceNameUsage { output := make(mapInterfaceNameUsage) for index := range ifaces { - if ifaces[index].linkId != nil { + if ifaces[index].linkID != nil { ifaceName := ifaces[index].stat.Name usage, ok := output[ifaceName] if ok { @@ -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 @@ -192,7 +197,7 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { if !ifaceUsage.isTruncated() { // no truncated interface name, return stats of all interface with for index := range nsInterfaces { - if nsInterfaces[index].linkId != nil { + if nsInterfaces[index].linkID != nil { ret[retIndex] = *nsInterfaces[index].stat retIndex++ } @@ -212,7 +217,7 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { for _, interfaceName := range interfaceNames { truncated := true for index := range nsInterfaces { - if nsInterfaces[index].linkId != nil && nsInterfaces[index].stat.Name == interfaceName { + if nsInterfaces[index].linkID != nil && nsInterfaces[index].stat.Name == interfaceName { // handle the non truncated name to avoid execute netstat for them again ret[retIndex] = *nsInterfaces[index].stat retIndex++ @@ -234,7 +239,7 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { continue } for index := range parsedIfaces { - if parsedIfaces[index].linkId != nil { + if parsedIfaces[index].linkID != nil { ret = append(ret, *parsedIfaces[index].stat) break } @@ -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_fallback.go b/vendor/github.com/shirou/gopsutil/net/net_fallback.go index 653bd47e5e3..7c5e632f870 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 2b546550e57..9daed8d71f3 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 12214d9255c..fc2b22ea553 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_linux.go +++ b/vendor/github.com/shirou/gopsutil/net/net_linux.go @@ -3,6 +3,8 @@ package net import ( + "bytes" + "context" "encoding/hex" "errors" "fmt" @@ -22,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 @@ -131,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 } @@ -190,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") @@ -261,17 +279,17 @@ var kindUNIX = netConnectionKindType{ } var netConnectionKindMap = map[string][]netConnectionKindType{ - "all": []netConnectionKindType{kindTCP4, kindTCP6, kindUDP4, kindUDP6, kindUNIX}, - "tcp": []netConnectionKindType{kindTCP4, kindTCP6}, - "tcp4": []netConnectionKindType{kindTCP4}, - "tcp6": []netConnectionKindType{kindTCP6}, - "udp": []netConnectionKindType{kindUDP4, kindUDP6}, - "udp4": []netConnectionKindType{kindUDP4}, - "udp6": []netConnectionKindType{kindUDP6}, - "unix": []netConnectionKindType{kindUNIX}, - "inet": []netConnectionKindType{kindTCP4, kindTCP6, kindUDP4, kindUDP6}, - "inet4": []netConnectionKindType{kindTCP4, kindUDP4}, - "inet6": []netConnectionKindType{kindTCP6, kindUDP6}, + "all": {kindTCP4, kindTCP6, kindUDP4, kindUDP6, kindUNIX}, + "tcp": {kindTCP4, kindTCP6}, + "tcp4": {kindTCP4}, + "tcp6": {kindTCP6}, + "udp": {kindUDP4, kindUDP6}, + "udp4": {kindUDP4}, + "udp6": {kindUDP6}, + "unix": {kindUNIX}, + "inet": {kindTCP4, kindTCP6, kindUDP4, kindUDP6}, + "inet4": {kindTCP4, kindUDP4}, + "inet6": {kindTCP6, kindUDP6}, } type inodeMap struct { @@ -293,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) @@ -321,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) @@ -415,12 +449,12 @@ func getProcInodes(root string, pid int32, max int) (map[string][]inodeMap, erro dir := fmt.Sprintf("%s/%d/fd", root, pid) f, err := os.Open(dir) if err != nil { - return ret, nil + return ret, err } defer f.Close() files, err := f.Readdir(max) if err != nil { - return ret, nil + return ret, err } for _, fd := range files { inodePath := fmt.Sprintf("%s/%d/fd/%s", root, pid, fd.Name()) @@ -458,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()) @@ -540,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 { @@ -587,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] } @@ -613,14 +659,22 @@ func processInet(file string, kind netConnectionKindType, inodes map[string][]in // IPv6 not supported, return empty. return []connTmp{}, nil } - lines, err := common.ReadLines(file) + + // Read the contents of the /proc file with a single read sys call. + // This minimizes duplicates in the returned connections + // For more info: + // https://github.com/shirou/gopsutil/pull/361 + contents, err := ioutil.ReadFile(file) if err != nil { return nil, err } + + lines := bytes.Split(contents, []byte("\n")) + var ret []connTmp // skip first line for _, line := range lines[1:] { - l := strings.Fields(line) + l := strings.Fields(string(line)) if len(l) < 10 { continue } @@ -667,15 +721,21 @@ func processInet(file string, kind netConnectionKindType, inodes map[string][]in } func processUnix(file string, kind netConnectionKindType, inodes map[string][]inodeMap, filterPid int32) ([]connTmp, error) { - lines, err := common.ReadLines(file) + // Read the contents of the /proc file with a single read sys call. + // This minimizes duplicates in the returned connections + // For more info: + // https://github.com/shirou/gopsutil/pull/361 + contents, err := ioutil.ReadFile(file) if err != nil { return nil, err } + lines := bytes.Split(contents, []byte("\n")) + var ret []connTmp // skip first line for _, line := range lines[1:] { - tokens := strings.Fields(line) + tokens := strings.Fields(string(line)) if len(tokens) < 6 { continue } @@ -690,7 +750,7 @@ func processUnix(file string, kind netConnectionKindType, inodes map[string][]in pairs, exists := inodes[inode] if !exists { pairs = []inodeMap{ - inodeMap{}, + {}, } } for _, pair := range pairs { diff --git a/vendor/github.com/shirou/gopsutil/net/net_openbsd.go b/vendor/github.com/shirou/gopsutil/net/net_openbsd.go index 85cc70c4977..4b194eb6e32 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") } +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. -// Not Implemented for OpenBSD func Connections(kind string) ([]ConnectionStat, error) { - return nil, errors.New("Connections not implemented for openbsd") + 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_unix.go b/vendor/github.com/shirou/gopsutil/net/net_unix.go index 1224128ab66..5ceb9cc5425 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 996e83226ac..7fff20e2bba 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_windows.go +++ b/vendor/github.com/shirou/gopsutil/net/net_windows.go @@ -3,16 +3,17 @@ package net import ( + "context" "errors" "net" "os" - "syscall" "github.com/shirou/gopsutil/internal/common" + "golang.org/x/sys/windows" ) var ( - modiphlpapi = syscall.NewLazyDLL("iphlpapi.dll") + modiphlpapi = windows.NewLazyDLL("iphlpapi.dll") procGetExtendedTCPTable = modiphlpapi.NewProc("GetExtendedTcpTable") procGetExtendedUDPTable = modiphlpapi.NewProc("GetExtendedUdpTable") ) @@ -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 @@ -41,8 +46,8 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { Name: ifi.Name, } - row := syscall.MibIfRow{Index: uint32(ifi.Index)} - e := syscall.GetIfEntry(&row) + row := windows.MibIfRow{Index: uint32(ifi.Index)} + e := windows.GetIfEntry(&row) if e != nil { return nil, os.NewSyscallError("GetIfEntry", e) } @@ -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/vendor.json b/vendor/vendor.json index 2da22e28770..0ddcf1d6eda 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1026,28 +1026,28 @@ "revisionTime": "2017-03-21T23:07:31Z" }, { - "checksumSHA1": "9ev6lHyQOxl1/VndOHAnMfbLmvs=", + "checksumSHA1": "lZRqG0Rl5w+mkaTUOuEjcKvNU6c=", "path": "github.com/shirou/gopsutil/disk", - "revision": "9af92986dda65a8c367157a82b484553e1ec1c55", - "revisionTime": "2017-04-30T14:39:46Z", - "version": "v2.17.04", - "versionExact": "v2.17.04" + "revision": "c432be29ccce470088d07eea25b3ea7e68a8afbb", + "revisionTime": "2018-01-30T01:13:38Z", + "version": "v2.18.01", + "versionExact": "v2.18.01" }, { - "checksumSHA1": "hKDsT0KAOtA7UqiXYdO0RahnQZ8=", + "checksumSHA1": "jWpwWWcywJPNhKTYxi4RXds+amQ=", "path": "github.com/shirou/gopsutil/internal/common", - "revision": "9af92986dda65a8c367157a82b484553e1ec1c55", - "revisionTime": "2017-04-30T14:39:46Z", - "version": "v2.17.04", - "versionExact": "v2.17.04" + "revision": "c432be29ccce470088d07eea25b3ea7e68a8afbb", + "revisionTime": "2018-01-30T01:13:38Z", + "version": "v2.18.01", + "versionExact": "v2.18.01" }, { - "checksumSHA1": "/MH6TIdlj16nThxkU9Bu+/WBm2w=", + "checksumSHA1": "Z7FjZvR5J5xh6Ne572gD7tRUsc8=", "path": "github.com/shirou/gopsutil/net", - "revision": "9af92986dda65a8c367157a82b484553e1ec1c55", - "revisionTime": "2017-04-30T14:39:46Z", - "version": "v2.17.04", - "versionExact": "v2.17.04" + "revision": "c432be29ccce470088d07eea25b3ea7e68a8afbb", + "revisionTime": "2018-01-30T01:13:38Z", + "version": "v2.18.01", + "versionExact": "v2.18.01" }, { "checksumSHA1": "e7mAb9jMke2ASQGZepFgOmfBFzM=",