From 9e466671210d441d377e63ec6445d5ad49f5e0b1 Mon Sep 17 00:00:00 2001 From: Pier-Hugues Pellerin Date: Tue, 13 Feb 2018 16:08:16 -0500 Subject: [PATCH] Update to Golang 1.9.4 (#6326) * Update to Golang 1.9.4 Keep up with the latest version of Golang. Version prior to 1.9.4 are affected by security issues on build. `go get` could have been used to do unwanted code execution[1] CVE-2018-6574 during build. The changes in golang now enforce more restrictive pragma declaration when linking and compiling. This commits, disable crosscompiling under solaris which requires an update on the standard library. ``` ../vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go:13:3: //go:cgo_import_dynamic libc_pipe pipe "libc.so" only allowed in cgo-generated code ../vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go:14:3: //go:cgo_import_dynamic libc_getsockname getsockname "libsocket.so" only allowed in cgo-generated code ``` We also update popsutil, thag was incorrectly defining an ldflags in a previous release making the build fails under the new restriction. [1] https://github.com/golang/go/issues/23672 * update vendor correctly --- .go-version | 2 +- CHANGELOG.asciidoc | 1 + NOTICE.txt | 4 +- Vagrantfile | 2 +- .../xgo-image-deb6/beats-builder/Dockerfile | 2 +- .../packer/docker/xgo-image-deb6/build.sh | 2 +- .../{go-1.9.2 => go-1.9.4}/Dockerfile | 6 +- .../docker/xgo-image/beats-builder/Dockerfile | 2 +- dev-tools/packer/docker/xgo-image/build.sh | 2 +- .../{go-1.9.2 => go-1.9.4}/Dockerfile | 6 +- filebeat/Dockerfile | 2 +- generator/beat/{beat}/.travis.yml | 2 +- libbeat/Dockerfile | 2 +- libbeat/docs/version.asciidoc | 2 +- libbeat/scripts/Makefile | 2 +- metricbeat/Dockerfile | 2 +- metricbeat/Makefile | 2 +- metricbeat/module/http/_meta/Dockerfile | 2 +- .../shirou/gopsutil/disk/disk_darwin.go | 15 +- .../shirou/gopsutil/disk/disk_darwin_cgo.go | 8 +- .../shirou/gopsutil/disk/disk_darwin_nocgo.go | 10 +- .../shirou/gopsutil/disk/disk_fallback.go | 20 ++- .../shirou/gopsutil/disk/disk_freebsd.go | 24 ++- .../shirou/gopsutil/disk/disk_linux.go | 28 ++- .../shirou/gopsutil/disk/disk_openbsd.go | 31 +++- .../shirou/gopsutil/disk/disk_solaris.go | 127 ++++++++++++++ .../shirou/gopsutil/disk/disk_unix.go | 17 +- .../shirou/gopsutil/disk/disk_windows.go | 35 ++-- .../shirou/gopsutil/disk/types_freebsd.go | 88 ---------- .../shirou/gopsutil/disk/types_openbsd.go | 70 -------- vendor/github.com/shirou/gopsutil/doc.go | 1 + .../shirou/gopsutil/internal/common/common.go | 78 ++++----- .../gopsutil/internal/common/common_darwin.go | 20 +-- .../internal/common/common_freebsd.go | 19 +- .../gopsutil/internal/common/common_linux.go | 10 +- .../internal/common/common_openbsd.go | 19 +- .../internal/common/common_windows.go | 39 +++-- vendor/github.com/shirou/gopsutil/net/net.go | 5 + .../shirou/gopsutil/net/net_darwin.go | 35 +++- .../shirou/gopsutil/net/net_fallback.go | 26 ++- .../shirou/gopsutil/net/net_freebsd.go | 17 ++ .../shirou/gopsutil/net/net_linux.go | 98 +++++++++-- .../shirou/gopsutil/net/net_openbsd.go | 165 +++++++++++++++++- .../shirou/gopsutil/net/net_unix.go | 17 ++ .../shirou/gopsutil/net/net_windows.go | 33 +++- vendor/vendor.json | 30 ++-- 46 files changed, 773 insertions(+), 357 deletions(-) rename dev-tools/packer/docker/xgo-image-deb6/{go-1.9.2 => go-1.9.4}/Dockerfile (66%) rename dev-tools/packer/docker/xgo-image/{go-1.9.2 => go-1.9.4}/Dockerfile (66%) create mode 100644 vendor/github.com/shirou/gopsutil/disk/disk_solaris.go delete mode 100644 vendor/github.com/shirou/gopsutil/disk/types_freebsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/disk/types_openbsd.go create mode 100644 vendor/github.com/shirou/gopsutil/doc.go 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=",