From 8bdf159d59335b41eeeb8291dbb2f485da1ffd20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 18:10:13 +0000 Subject: [PATCH] build(deps): bump the go-dependencies group across 1 directory with 6 updates Bumps the go-dependencies group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [github.com/jaypipes/ghw](https://github.com/jaypipes/ghw) | `0.12.0` | `0.13.0` | | [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) | `1.20.2` | `1.20.3` | | [golang.org/x/sys](https://github.com/golang/sys) | `0.24.0` | `0.25.0` | | [k8s.io/api](https://github.com/kubernetes/api) | `0.29.8` | `0.29.9` | | [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.29.8` | `0.29.9` | Updates `github.com/jaypipes/ghw` from 0.12.0 to 0.13.0 - [Release notes](https://github.com/jaypipes/ghw/releases) - [Commits](https://github.com/jaypipes/ghw/compare/v0.12.0...v0.13.0) Updates `github.com/prometheus/client_golang` from 1.20.2 to 1.20.3 - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/v1.20.3/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.20.2...v1.20.3) Updates `golang.org/x/sys` from 0.24.0 to 0.25.0 - [Commits](https://github.com/golang/sys/compare/v0.24.0...v0.25.0) Updates `k8s.io/api` from 0.29.8 to 0.29.9 - [Commits](https://github.com/kubernetes/api/compare/v0.29.8...v0.29.9) Updates `k8s.io/apimachinery` from 0.29.8 to 0.29.9 - [Commits](https://github.com/kubernetes/apimachinery/compare/v0.29.8...v0.29.9) Updates `k8s.io/client-go` from 0.29.8 to 0.29.9 - [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/kubernetes/client-go/compare/v0.29.8...v0.29.9) --- updated-dependencies: - dependency-name: github.com/jaypipes/ghw dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-dependencies - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: golang.org/x/sys dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-dependencies - dependency-name: k8s.io/api dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: k8s.io/apimachinery dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: k8s.io/client-go dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies ... Signed-off-by: dependabot[bot] --- go.mod | 15 +- go.sum | 30 +- vendor/github.com/ghodss/yaml/.gitignore | 20 - vendor/github.com/ghodss/yaml/.travis.yml | 7 - vendor/github.com/ghodss/yaml/LICENSE | 50 - vendor/github.com/ghodss/yaml/README.md | 121 --- vendor/github.com/ghodss/yaml/fields.go | 501 --------- vendor/github.com/ghodss/yaml/yaml.go | 277 ----- vendor/github.com/jaypipes/ghw/Dockerfile | 6 +- vendor/github.com/jaypipes/ghw/Makefile | 31 +- vendor/github.com/jaypipes/ghw/README.md | 958 +++++++++--------- vendor/github.com/jaypipes/ghw/SECURITY.md | 23 + vendor/github.com/jaypipes/ghw/alias.go | 51 +- vendor/github.com/jaypipes/ghw/doc.go | 308 +----- .../jaypipes/ghw/pkg/block/block.go | 228 +++-- .../jaypipes/ghw/pkg/block/block_darwin.go | 15 +- .../jaypipes/ghw/pkg/block/block_linux.go | 92 +- .../jaypipes/ghw/pkg/block/block_windows.go | 48 +- .../jaypipes/ghw/pkg/cpu/cpu_darwin.go | 135 +++ .../jaypipes/ghw/pkg/cpu/cpu_linux.go | 18 +- .../jaypipes/ghw/pkg/cpu/cpu_stub.go | 4 +- .../jaypipes/ghw/pkg/gpu/gpu_linux.go | 3 +- .../jaypipes/ghw/pkg/linuxdmi/dmi_linux.go | 4 +- .../jaypipes/ghw/pkg/marshal/marshal.go | 20 +- .../jaypipes/ghw/pkg/memory/memory.go | 13 + .../jaypipes/ghw/pkg/memory/memory_cache.go | 60 +- .../ghw/pkg/memory/memory_cache_linux.go | 21 +- .../jaypipes/ghw/pkg/memory/memory_linux.go | 19 +- vendor/github.com/jaypipes/ghw/pkg/net/net.go | 73 +- .../jaypipes/ghw/pkg/net/net_linux.go | 14 +- .../jaypipes/ghw/pkg/net/net_windows.go | 2 +- .../jaypipes/ghw/pkg/option/option.go | 5 +- .../jaypipes/ghw/pkg/pci/address/address.go | 11 +- vendor/github.com/jaypipes/ghw/pkg/pci/pci.go | 20 +- .../jaypipes/ghw/pkg/pci/pci_linux.go | 36 +- .../jaypipes/ghw/pkg/snapshot/clonetree.go | 3 +- .../ghw/pkg/snapshot/clonetree_block_linux.go | 13 +- .../ghw/pkg/snapshot/clonetree_linux.go | 3 +- .../ghw/pkg/snapshot/clonetree_pci_linux.go | 5 +- .../jaypipes/ghw/pkg/snapshot/unpack.go | 5 +- .../ghw/pkg/topology/topology_linux.go | 6 +- .../github.com/jaypipes/ghw/pkg/util/util.go | 3 +- vendor/github.com/jaypipes/pcidb/README.md | 2 +- .../client_golang/prometheus/histogram.go | 92 +- vendor/golang.org/x/sys/cpu/cpu.go | 19 + .../golang.org/x/sys/cpu/cpu_linux_noinit.go | 2 +- .../golang.org/x/sys/cpu/cpu_linux_riscv64.go | 137 +++ vendor/golang.org/x/sys/cpu/cpu_riscv64.go | 11 +- vendor/golang.org/x/sys/unix/mkerrors.sh | 1 + .../golang.org/x/sys/unix/syscall_darwin.go | 37 + vendor/golang.org/x/sys/unix/syscall_hurd.go | 1 + .../x/sys/unix/zerrors_darwin_amd64.go | 7 + .../x/sys/unix/zerrors_darwin_arm64.go | 7 + .../x/sys/unix/zerrors_zos_s390x.go | 2 + .../x/sys/unix/zsyscall_darwin_amd64.go | 20 + .../x/sys/unix/zsyscall_darwin_amd64.s | 5 + .../x/sys/unix/zsyscall_darwin_arm64.go | 20 + .../x/sys/unix/zsyscall_darwin_arm64.s | 5 + .../x/sys/unix/ztypes_darwin_amd64.go | 13 + .../x/sys/unix/ztypes_darwin_arm64.go | 13 + .../x/sys/unix/ztypes_freebsd_386.go | 1 + .../x/sys/unix/ztypes_freebsd_amd64.go | 1 + .../x/sys/unix/ztypes_freebsd_arm.go | 1 + .../x/sys/unix/ztypes_freebsd_arm64.go | 1 + .../x/sys/unix/ztypes_freebsd_riscv64.go | 1 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 2 +- .../x/sys/unix/ztypes_linux_riscv64.go | 33 + .../x/sys/windows/syscall_windows.go | 4 + .../golang.org/x/sys/windows/types_windows.go | 1 + .../x/sys/windows/zsyscall_windows.go | 38 + vendor/modules.txt | 21 +- 71 files changed, 1631 insertions(+), 2144 deletions(-) delete mode 100644 vendor/github.com/ghodss/yaml/.gitignore delete mode 100644 vendor/github.com/ghodss/yaml/.travis.yml delete mode 100644 vendor/github.com/ghodss/yaml/LICENSE delete mode 100644 vendor/github.com/ghodss/yaml/README.md delete mode 100644 vendor/github.com/ghodss/yaml/fields.go delete mode 100644 vendor/github.com/ghodss/yaml/yaml.go create mode 100644 vendor/github.com/jaypipes/ghw/SECURITY.md create mode 100644 vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_darwin.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go diff --git a/go.mod b/go.mod index 82f4288fa5..a08f94b0a4 100644 --- a/go.mod +++ b/go.mod @@ -11,23 +11,23 @@ require ( github.com/beevik/etree v1.4.1 github.com/cilium/ebpf v0.16.0 github.com/digitalocean/go-libvirt v0.0.0-20240709142323-d8406205c752 - github.com/jaypipes/ghw v0.12.0 + github.com/jaypipes/ghw v0.13.0 github.com/joho/godotenv v1.5.1 github.com/jszwec/csvutil v1.10.0 github.com/klauspost/cpuid/v2 v2.2.8 github.com/onsi/ginkgo/v2 v2.20.1 github.com/onsi/gomega v1.34.1 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.20.2 + github.com/prometheus/client_golang v1.20.3 github.com/prometheus/prometheus v0.54.1 github.com/shirou/gopsutil v3.21.11+incompatible github.com/sirupsen/logrus v1.9.3 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - golang.org/x/sys v0.24.0 + golang.org/x/sys v0.25.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.29.8 - k8s.io/apimachinery v0.29.8 - k8s.io/client-go v0.29.8 + k8s.io/api v0.29.9 + k8s.io/apimachinery v0.29.9 + k8s.io/client-go v0.29.9 k8s.io/klog/v2 v2.130.1 ) @@ -39,7 +39,6 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/ghodss/yaml v1.0.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect @@ -56,7 +55,7 @@ require ( github.com/gorilla/websocket v1.5.0 // indirect github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect github.com/imdario/mergo v0.3.16 // indirect - github.com/jaypipes/pcidb v1.0.0 // indirect + github.com/jaypipes/pcidb v1.0.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.9 // indirect diff --git a/go.sum b/go.sum index b2c3daa131..c0098c54a9 100644 --- a/go.sum +++ b/go.sum @@ -28,8 +28,6 @@ github.com/digitalocean/go-libvirt v0.0.0-20240709142323-d8406205c752 h1:NI7XEcH github.com/digitalocean/go-libvirt v0.0.0-20240709142323-d8406205c752/go.mod h1:/Ok8PA2qi/ve0Py38+oL+VxoYmlowigYRyLEODRYdgc= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= @@ -72,10 +70,10 @@ github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrR github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/jaypipes/ghw v0.12.0 h1:xU2/MDJfWmBhJnujHY9qwXQLs3DBsf0/Xa9vECY0Tho= -github.com/jaypipes/ghw v0.12.0/go.mod h1:jeJGbkRB2lL3/gxYzNYzEDETV1ZJ56OKr+CSeSEym+g= -github.com/jaypipes/pcidb v1.0.0 h1:vtZIfkiCUE42oYbJS0TAq9XSfSmcsgo9IdxSm9qzYU8= -github.com/jaypipes/pcidb v1.0.0/go.mod h1:TnYUvqhPBzCKnH34KrIX22kAeEbDCSRJ9cqLRCuNDfk= +github.com/jaypipes/ghw v0.13.0 h1:log8MXuB8hzTNnSktqpXMHc0c/2k/WgjOMSUtnI1RV4= +github.com/jaypipes/ghw v0.13.0/go.mod h1:In8SsaDqlb1oTyrbmTC14uy+fbBMvp+xdqX51MidlD8= +github.com/jaypipes/pcidb v1.0.1 h1:WB2zh27T3nwg8AE8ei81sNRb9yWBii3JGNJtT7K9Oic= +github.com/jaypipes/pcidb v1.0.1/go.mod h1:6xYUz/yYEyOkIkUt2t2J2folIuZ4Yg6uByCGFXMCeE4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= @@ -133,8 +131,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= -github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4= +github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= @@ -196,8 +194,8 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -232,12 +230,12 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= -k8s.io/api v0.29.8 h1:ZBKg9clWnIGtQ5yGhNwMw2zyyrsIAQaXhZACcYNflQE= -k8s.io/api v0.29.8/go.mod h1:XlGIpmpzKGrtVca7GlgNryZJ19SvQdI808NN7fy1SgQ= -k8s.io/apimachinery v0.29.8 h1:uBHc9WuKiTHClIspJqtR84WNpG0aOGn45HWqxgXkk8Y= -k8s.io/apimachinery v0.29.8/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y= -k8s.io/client-go v0.29.8 h1:QMRKcIzqE/qawknXcsi51GdIAYN8UP39S/M5KnFu/J0= -k8s.io/client-go v0.29.8/go.mod h1:ZzrAAVrqO2jVXMb8My/jTke8n0a/mIynnA3y/1y1UB0= +k8s.io/api v0.29.9 h1:FwdflpNsfMUYUOblMZNWJ4K/q0OSL5A4jGa0iOgcJco= +k8s.io/api v0.29.9/go.mod h1:fNhmzRfKaSEHCmczA/jRx6CiDKhYOnFLJBERMJAXEk8= +k8s.io/apimachinery v0.29.9 h1:YZ8HUid1TzQVz94cnNlsQjLdH0VoAhWSqz7t0q6B12A= +k8s.io/apimachinery v0.29.9/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y= +k8s.io/client-go v0.29.9 h1:4f/Wz6li3rEyIPFj32XAQMtOGMM1tg7KQi1oeS6ibPg= +k8s.io/client-go v0.29.9/go.mod h1:2N1drQEZ5yiYrWVaE2Un8JiISUhl47D8pyZlYLszke4= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= diff --git a/vendor/github.com/ghodss/yaml/.gitignore b/vendor/github.com/ghodss/yaml/.gitignore deleted file mode 100644 index e256a31e00..0000000000 --- a/vendor/github.com/ghodss/yaml/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -# OSX leaves these everywhere on SMB shares -._* - -# Eclipse files -.classpath -.project -.settings/** - -# Emacs save files -*~ - -# Vim-related files -[._]*.s[a-w][a-z] -[._]s[a-w][a-z] -*.un~ -Session.vim -.netrwhist - -# Go test binaries -*.test diff --git a/vendor/github.com/ghodss/yaml/.travis.yml b/vendor/github.com/ghodss/yaml/.travis.yml deleted file mode 100644 index 0e9d6edc01..0000000000 --- a/vendor/github.com/ghodss/yaml/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: go -go: - - 1.3 - - 1.4 -script: - - go test - - go build diff --git a/vendor/github.com/ghodss/yaml/LICENSE b/vendor/github.com/ghodss/yaml/LICENSE deleted file mode 100644 index 7805d36de7..0000000000 --- a/vendor/github.com/ghodss/yaml/LICENSE +++ /dev/null @@ -1,50 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Sam Ghods - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/ghodss/yaml/README.md b/vendor/github.com/ghodss/yaml/README.md deleted file mode 100644 index 0200f75b4d..0000000000 --- a/vendor/github.com/ghodss/yaml/README.md +++ /dev/null @@ -1,121 +0,0 @@ -# YAML marshaling and unmarshaling support for Go - -[![Build Status](https://travis-ci.org/ghodss/yaml.svg)](https://travis-ci.org/ghodss/yaml) - -## Introduction - -A wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs. - -In short, this library first converts YAML to JSON using go-yaml and then uses `json.Marshal` and `json.Unmarshal` to convert to or from the struct. This means that it effectively reuses the JSON struct tags as well as the custom JSON methods `MarshalJSON` and `UnmarshalJSON` unlike go-yaml. For a detailed overview of the rationale behind this method, [see this blog post](http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/). - -## Compatibility - -This package uses [go-yaml](https://github.com/go-yaml/yaml) and therefore supports [everything go-yaml supports](https://github.com/go-yaml/yaml#compatibility). - -## Caveats - -**Caveat #1:** When using `yaml.Marshal` and `yaml.Unmarshal`, binary data should NOT be preceded with the `!!binary` YAML tag. If you do, go-yaml will convert the binary data from base64 to native binary data, which is not compatible with JSON. You can still use binary in your YAML files though - just store them without the `!!binary` tag and decode the base64 in your code (e.g. in the custom JSON methods `MarshalJSON` and `UnmarshalJSON`). This also has the benefit that your YAML and your JSON binary data will be decoded exactly the same way. As an example: - -``` -BAD: - exampleKey: !!binary gIGC - -GOOD: - exampleKey: gIGC -... and decode the base64 data in your code. -``` - -**Caveat #2:** When using `YAMLToJSON` directly, maps with keys that are maps will result in an error since this is not supported by JSON. This error will occur in `Unmarshal` as well since you can't unmarshal map keys anyways since struct fields can't be keys. - -## Installation and usage - -To install, run: - -``` -$ go get github.com/ghodss/yaml -``` - -And import using: - -``` -import "github.com/ghodss/yaml" -``` - -Usage is very similar to the JSON library: - -```go -package main - -import ( - "fmt" - - "github.com/ghodss/yaml" -) - -type Person struct { - Name string `json:"name"` // Affects YAML field names too. - Age int `json:"age"` -} - -func main() { - // Marshal a Person struct to YAML. - p := Person{"John", 30} - y, err := yaml.Marshal(p) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(string(y)) - /* Output: - age: 30 - name: John - */ - - // Unmarshal the YAML back into a Person struct. - var p2 Person - err = yaml.Unmarshal(y, &p2) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(p2) - /* Output: - {John 30} - */ -} -``` - -`yaml.YAMLToJSON` and `yaml.JSONToYAML` methods are also available: - -```go -package main - -import ( - "fmt" - - "github.com/ghodss/yaml" -) - -func main() { - j := []byte(`{"name": "John", "age": 30}`) - y, err := yaml.JSONToYAML(j) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(string(y)) - /* Output: - name: John - age: 30 - */ - j2, err := yaml.YAMLToJSON(y) - if err != nil { - fmt.Printf("err: %v\n", err) - return - } - fmt.Println(string(j2)) - /* Output: - {"age":30,"name":"John"} - */ -} -``` diff --git a/vendor/github.com/ghodss/yaml/fields.go b/vendor/github.com/ghodss/yaml/fields.go deleted file mode 100644 index 5860074026..0000000000 --- a/vendor/github.com/ghodss/yaml/fields.go +++ /dev/null @@ -1,501 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -package yaml - -import ( - "bytes" - "encoding" - "encoding/json" - "reflect" - "sort" - "strings" - "sync" - "unicode" - "unicode/utf8" -) - -// indirect walks down v allocating pointers as needed, -// until it gets to a non-pointer. -// if it encounters an Unmarshaler, indirect stops and returns that. -// if decodingNull is true, indirect stops at the last pointer so it can be set to nil. -func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { - // If v is a named type and is addressable, - // start with its address, so that if the type has pointer methods, - // we find them. - if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { - v = v.Addr() - } - for { - // Load value from interface, but only if the result will be - // usefully addressable. - if v.Kind() == reflect.Interface && !v.IsNil() { - e := v.Elem() - if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) { - v = e - continue - } - } - - if v.Kind() != reflect.Ptr { - break - } - - if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() { - break - } - if v.IsNil() { - if v.CanSet() { - v.Set(reflect.New(v.Type().Elem())) - } else { - v = reflect.New(v.Type().Elem()) - } - } - if v.Type().NumMethod() > 0 { - if u, ok := v.Interface().(json.Unmarshaler); ok { - return u, nil, reflect.Value{} - } - if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { - return nil, u, reflect.Value{} - } - } - v = v.Elem() - } - return nil, nil, v -} - -// A field represents a single field found in a struct. -type field struct { - name string - nameBytes []byte // []byte(name) - equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent - - tag bool - index []int - typ reflect.Type - omitEmpty bool - quoted bool -} - -func fillField(f field) field { - f.nameBytes = []byte(f.name) - f.equalFold = foldFunc(f.nameBytes) - return f -} - -// byName sorts field by name, breaking ties with depth, -// then breaking ties with "name came from json tag", then -// breaking ties with index sequence. -type byName []field - -func (x byName) Len() int { return len(x) } - -func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -func (x byName) Less(i, j int) bool { - if x[i].name != x[j].name { - return x[i].name < x[j].name - } - if len(x[i].index) != len(x[j].index) { - return len(x[i].index) < len(x[j].index) - } - if x[i].tag != x[j].tag { - return x[i].tag - } - return byIndex(x).Less(i, j) -} - -// byIndex sorts field by index sequence. -type byIndex []field - -func (x byIndex) Len() int { return len(x) } - -func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -func (x byIndex) Less(i, j int) bool { - for k, xik := range x[i].index { - if k >= len(x[j].index) { - return false - } - if xik != x[j].index[k] { - return xik < x[j].index[k] - } - } - return len(x[i].index) < len(x[j].index) -} - -// typeFields returns a list of fields that JSON should recognize for the given type. -// The algorithm is breadth-first search over the set of structs to include - the top struct -// and then any reachable anonymous structs. -func typeFields(t reflect.Type) []field { - // Anonymous fields to explore at the current level and the next. - current := []field{} - next := []field{{typ: t}} - - // Count of queued names for current level and the next. - count := map[reflect.Type]int{} - nextCount := map[reflect.Type]int{} - - // Types already visited at an earlier level. - visited := map[reflect.Type]bool{} - - // Fields found. - var fields []field - - for len(next) > 0 { - current, next = next, current[:0] - count, nextCount = nextCount, map[reflect.Type]int{} - - for _, f := range current { - if visited[f.typ] { - continue - } - visited[f.typ] = true - - // Scan f.typ for fields to include. - for i := 0; i < f.typ.NumField(); i++ { - sf := f.typ.Field(i) - if sf.PkgPath != "" { // unexported - continue - } - tag := sf.Tag.Get("json") - if tag == "-" { - continue - } - name, opts := parseTag(tag) - if !isValidTag(name) { - name = "" - } - index := make([]int, len(f.index)+1) - copy(index, f.index) - index[len(f.index)] = i - - ft := sf.Type - if ft.Name() == "" && ft.Kind() == reflect.Ptr { - // Follow pointer. - ft = ft.Elem() - } - - // Record found field and index sequence. - if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { - tagged := name != "" - if name == "" { - name = sf.Name - } - fields = append(fields, fillField(field{ - name: name, - tag: tagged, - index: index, - typ: ft, - omitEmpty: opts.Contains("omitempty"), - quoted: opts.Contains("string"), - })) - if count[f.typ] > 1 { - // If there were multiple instances, add a second, - // so that the annihilation code will see a duplicate. - // It only cares about the distinction between 1 or 2, - // so don't bother generating any more copies. - fields = append(fields, fields[len(fields)-1]) - } - continue - } - - // Record new anonymous struct to explore in next round. - nextCount[ft]++ - if nextCount[ft] == 1 { - next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft})) - } - } - } - } - - sort.Sort(byName(fields)) - - // Delete all fields that are hidden by the Go rules for embedded fields, - // except that fields with JSON tags are promoted. - - // The fields are sorted in primary order of name, secondary order - // of field index length. Loop over names; for each name, delete - // hidden fields by choosing the one dominant field that survives. - out := fields[:0] - for advance, i := 0, 0; i < len(fields); i += advance { - // One iteration per name. - // Find the sequence of fields with the name of this first field. - fi := fields[i] - name := fi.name - for advance = 1; i+advance < len(fields); advance++ { - fj := fields[i+advance] - if fj.name != name { - break - } - } - if advance == 1 { // Only one field with this name - out = append(out, fi) - continue - } - dominant, ok := dominantField(fields[i : i+advance]) - if ok { - out = append(out, dominant) - } - } - - fields = out - sort.Sort(byIndex(fields)) - - return fields -} - -// dominantField looks through the fields, all of which are known to -// have the same name, to find the single field that dominates the -// others using Go's embedding rules, modified by the presence of -// JSON tags. If there are multiple top-level fields, the boolean -// will be false: This condition is an error in Go and we skip all -// the fields. -func dominantField(fields []field) (field, bool) { - // The fields are sorted in increasing index-length order. The winner - // must therefore be one with the shortest index length. Drop all - // longer entries, which is easy: just truncate the slice. - length := len(fields[0].index) - tagged := -1 // Index of first tagged field. - for i, f := range fields { - if len(f.index) > length { - fields = fields[:i] - break - } - if f.tag { - if tagged >= 0 { - // Multiple tagged fields at the same level: conflict. - // Return no field. - return field{}, false - } - tagged = i - } - } - if tagged >= 0 { - return fields[tagged], true - } - // All remaining fields have the same length. If there's more than one, - // we have a conflict (two fields named "X" at the same level) and we - // return no field. - if len(fields) > 1 { - return field{}, false - } - return fields[0], true -} - -var fieldCache struct { - sync.RWMutex - m map[reflect.Type][]field -} - -// cachedTypeFields is like typeFields but uses a cache to avoid repeated work. -func cachedTypeFields(t reflect.Type) []field { - fieldCache.RLock() - f := fieldCache.m[t] - fieldCache.RUnlock() - if f != nil { - return f - } - - // Compute fields without lock. - // Might duplicate effort but won't hold other computations back. - f = typeFields(t) - if f == nil { - f = []field{} - } - - fieldCache.Lock() - if fieldCache.m == nil { - fieldCache.m = map[reflect.Type][]field{} - } - fieldCache.m[t] = f - fieldCache.Unlock() - return f -} - -func isValidTag(s string) bool { - if s == "" { - return false - } - for _, c := range s { - switch { - case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): - // Backslash and quote chars are reserved, but - // otherwise any punctuation chars are allowed - // in a tag name. - default: - if !unicode.IsLetter(c) && !unicode.IsDigit(c) { - return false - } - } - } - return true -} - -const ( - caseMask = ^byte(0x20) // Mask to ignore case in ASCII. - kelvin = '\u212a' - smallLongEss = '\u017f' -) - -// foldFunc returns one of four different case folding equivalence -// functions, from most general (and slow) to fastest: -// -// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8 -// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S') -// 3) asciiEqualFold, no special, but includes non-letters (including _) -// 4) simpleLetterEqualFold, no specials, no non-letters. -// -// The letters S and K are special because they map to 3 runes, not just 2: -// * S maps to s and to U+017F 'ſ' Latin small letter long s -// * k maps to K and to U+212A 'K' Kelvin sign -// See http://play.golang.org/p/tTxjOc0OGo -// -// The returned function is specialized for matching against s and -// should only be given s. It's not curried for performance reasons. -func foldFunc(s []byte) func(s, t []byte) bool { - nonLetter := false - special := false // special letter - for _, b := range s { - if b >= utf8.RuneSelf { - return bytes.EqualFold - } - upper := b & caseMask - if upper < 'A' || upper > 'Z' { - nonLetter = true - } else if upper == 'K' || upper == 'S' { - // See above for why these letters are special. - special = true - } - } - if special { - return equalFoldRight - } - if nonLetter { - return asciiEqualFold - } - return simpleLetterEqualFold -} - -// equalFoldRight is a specialization of bytes.EqualFold when s is -// known to be all ASCII (including punctuation), but contains an 's', -// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t. -// See comments on foldFunc. -func equalFoldRight(s, t []byte) bool { - for _, sb := range s { - if len(t) == 0 { - return false - } - tb := t[0] - if tb < utf8.RuneSelf { - if sb != tb { - sbUpper := sb & caseMask - if 'A' <= sbUpper && sbUpper <= 'Z' { - if sbUpper != tb&caseMask { - return false - } - } else { - return false - } - } - t = t[1:] - continue - } - // sb is ASCII and t is not. t must be either kelvin - // sign or long s; sb must be s, S, k, or K. - tr, size := utf8.DecodeRune(t) - switch sb { - case 's', 'S': - if tr != smallLongEss { - return false - } - case 'k', 'K': - if tr != kelvin { - return false - } - default: - return false - } - t = t[size:] - - } - if len(t) > 0 { - return false - } - return true -} - -// asciiEqualFold is a specialization of bytes.EqualFold for use when -// s is all ASCII (but may contain non-letters) and contains no -// special-folding letters. -// See comments on foldFunc. -func asciiEqualFold(s, t []byte) bool { - if len(s) != len(t) { - return false - } - for i, sb := range s { - tb := t[i] - if sb == tb { - continue - } - if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') { - if sb&caseMask != tb&caseMask { - return false - } - } else { - return false - } - } - return true -} - -// simpleLetterEqualFold is a specialization of bytes.EqualFold for -// use when s is all ASCII letters (no underscores, etc) and also -// doesn't contain 'k', 'K', 's', or 'S'. -// See comments on foldFunc. -func simpleLetterEqualFold(s, t []byte) bool { - if len(s) != len(t) { - return false - } - for i, b := range s { - if b&caseMask != t[i]&caseMask { - return false - } - } - return true -} - -// tagOptions is the string following a comma in a struct field's "json" -// tag, or the empty string. It does not include the leading comma. -type tagOptions string - -// parseTag splits a struct field's json tag into its name and -// comma-separated options. -func parseTag(tag string) (string, tagOptions) { - if idx := strings.Index(tag, ","); idx != -1 { - return tag[:idx], tagOptions(tag[idx+1:]) - } - return tag, tagOptions("") -} - -// Contains reports whether a comma-separated list of options -// contains a particular substr flag. substr must be surrounded by a -// string boundary or commas. -func (o tagOptions) Contains(optionName string) bool { - if len(o) == 0 { - return false - } - s := string(o) - for s != "" { - var next string - i := strings.Index(s, ",") - if i >= 0 { - s, next = s[:i], s[i+1:] - } - if s == optionName { - return true - } - s = next - } - return false -} diff --git a/vendor/github.com/ghodss/yaml/yaml.go b/vendor/github.com/ghodss/yaml/yaml.go deleted file mode 100644 index 4fb4054a8b..0000000000 --- a/vendor/github.com/ghodss/yaml/yaml.go +++ /dev/null @@ -1,277 +0,0 @@ -package yaml - -import ( - "bytes" - "encoding/json" - "fmt" - "reflect" - "strconv" - - "gopkg.in/yaml.v2" -) - -// Marshals the object into JSON then converts JSON to YAML and returns the -// YAML. -func Marshal(o interface{}) ([]byte, error) { - j, err := json.Marshal(o) - if err != nil { - return nil, fmt.Errorf("error marshaling into JSON: %v", err) - } - - y, err := JSONToYAML(j) - if err != nil { - return nil, fmt.Errorf("error converting JSON to YAML: %v", err) - } - - return y, nil -} - -// Converts YAML to JSON then uses JSON to unmarshal into an object. -func Unmarshal(y []byte, o interface{}) error { - vo := reflect.ValueOf(o) - j, err := yamlToJSON(y, &vo) - if err != nil { - return fmt.Errorf("error converting YAML to JSON: %v", err) - } - - err = json.Unmarshal(j, o) - if err != nil { - return fmt.Errorf("error unmarshaling JSON: %v", err) - } - - return nil -} - -// Convert JSON to YAML. -func JSONToYAML(j []byte) ([]byte, error) { - // Convert the JSON to an object. - var jsonObj interface{} - // We are using yaml.Unmarshal here (instead of json.Unmarshal) because the - // Go JSON library doesn't try to pick the right number type (int, float, - // etc.) when unmarshalling to interface{}, it just picks float64 - // universally. go-yaml does go through the effort of picking the right - // number type, so we can preserve number type throughout this process. - err := yaml.Unmarshal(j, &jsonObj) - if err != nil { - return nil, err - } - - // Marshal this object into YAML. - return yaml.Marshal(jsonObj) -} - -// Convert YAML to JSON. Since JSON is a subset of YAML, passing JSON through -// this method should be a no-op. -// -// Things YAML can do that are not supported by JSON: -// * In YAML you can have binary and null keys in your maps. These are invalid -// in JSON. (int and float keys are converted to strings.) -// * Binary data in YAML with the !!binary tag is not supported. If you want to -// use binary data with this library, encode the data as base64 as usual but do -// not use the !!binary tag in your YAML. This will ensure the original base64 -// encoded data makes it all the way through to the JSON. -func YAMLToJSON(y []byte) ([]byte, error) { - return yamlToJSON(y, nil) -} - -func yamlToJSON(y []byte, jsonTarget *reflect.Value) ([]byte, error) { - // Convert the YAML to an object. - var yamlObj interface{} - err := yaml.Unmarshal(y, &yamlObj) - if err != nil { - return nil, err - } - - // YAML objects are not completely compatible with JSON objects (e.g. you - // can have non-string keys in YAML). So, convert the YAML-compatible object - // to a JSON-compatible object, failing with an error if irrecoverable - // incompatibilties happen along the way. - jsonObj, err := convertToJSONableObject(yamlObj, jsonTarget) - if err != nil { - return nil, err - } - - // Convert this object to JSON and return the data. - return json.Marshal(jsonObj) -} - -func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (interface{}, error) { - var err error - - // Resolve jsonTarget to a concrete value (i.e. not a pointer or an - // interface). We pass decodingNull as false because we're not actually - // decoding into the value, we're just checking if the ultimate target is a - // string. - if jsonTarget != nil { - ju, tu, pv := indirect(*jsonTarget, false) - // We have a JSON or Text Umarshaler at this level, so we can't be trying - // to decode into a string. - if ju != nil || tu != nil { - jsonTarget = nil - } else { - jsonTarget = &pv - } - } - - // If yamlObj is a number or a boolean, check if jsonTarget is a string - - // if so, coerce. Else return normal. - // If yamlObj is a map or array, find the field that each key is - // unmarshaling to, and when you recurse pass the reflect.Value for that - // field back into this function. - switch typedYAMLObj := yamlObj.(type) { - case map[interface{}]interface{}: - // JSON does not support arbitrary keys in a map, so we must convert - // these keys to strings. - // - // From my reading of go-yaml v2 (specifically the resolve function), - // keys can only have the types string, int, int64, float64, binary - // (unsupported), or null (unsupported). - strMap := make(map[string]interface{}) - for k, v := range typedYAMLObj { - // Resolve the key to a string first. - var keyString string - switch typedKey := k.(type) { - case string: - keyString = typedKey - case int: - keyString = strconv.Itoa(typedKey) - case int64: - // go-yaml will only return an int64 as a key if the system - // architecture is 32-bit and the key's value is between 32-bit - // and 64-bit. Otherwise the key type will simply be int. - keyString = strconv.FormatInt(typedKey, 10) - case float64: - // Stolen from go-yaml to use the same conversion to string as - // the go-yaml library uses to convert float to string when - // Marshaling. - s := strconv.FormatFloat(typedKey, 'g', -1, 32) - switch s { - case "+Inf": - s = ".inf" - case "-Inf": - s = "-.inf" - case "NaN": - s = ".nan" - } - keyString = s - case bool: - if typedKey { - keyString = "true" - } else { - keyString = "false" - } - default: - return nil, fmt.Errorf("Unsupported map key of type: %s, key: %+#v, value: %+#v", - reflect.TypeOf(k), k, v) - } - - // jsonTarget should be a struct or a map. If it's a struct, find - // the field it's going to map to and pass its reflect.Value. If - // it's a map, find the element type of the map and pass the - // reflect.Value created from that type. If it's neither, just pass - // nil - JSON conversion will error for us if it's a real issue. - if jsonTarget != nil { - t := *jsonTarget - if t.Kind() == reflect.Struct { - keyBytes := []byte(keyString) - // Find the field that the JSON library would use. - var f *field - fields := cachedTypeFields(t.Type()) - for i := range fields { - ff := &fields[i] - if bytes.Equal(ff.nameBytes, keyBytes) { - f = ff - break - } - // Do case-insensitive comparison. - if f == nil && ff.equalFold(ff.nameBytes, keyBytes) { - f = ff - } - } - if f != nil { - // Find the reflect.Value of the most preferential - // struct field. - jtf := t.Field(f.index[0]) - strMap[keyString], err = convertToJSONableObject(v, &jtf) - if err != nil { - return nil, err - } - continue - } - } else if t.Kind() == reflect.Map { - // Create a zero value of the map's element type to use as - // the JSON target. - jtv := reflect.Zero(t.Type().Elem()) - strMap[keyString], err = convertToJSONableObject(v, &jtv) - if err != nil { - return nil, err - } - continue - } - } - strMap[keyString], err = convertToJSONableObject(v, nil) - if err != nil { - return nil, err - } - } - return strMap, nil - case []interface{}: - // We need to recurse into arrays in case there are any - // map[interface{}]interface{}'s inside and to convert any - // numbers to strings. - - // If jsonTarget is a slice (which it really should be), find the - // thing it's going to map to. If it's not a slice, just pass nil - // - JSON conversion will error for us if it's a real issue. - var jsonSliceElemValue *reflect.Value - if jsonTarget != nil { - t := *jsonTarget - if t.Kind() == reflect.Slice { - // By default slices point to nil, but we need a reflect.Value - // pointing to a value of the slice type, so we create one here. - ev := reflect.Indirect(reflect.New(t.Type().Elem())) - jsonSliceElemValue = &ev - } - } - - // Make and use a new array. - arr := make([]interface{}, len(typedYAMLObj)) - for i, v := range typedYAMLObj { - arr[i], err = convertToJSONableObject(v, jsonSliceElemValue) - if err != nil { - return nil, err - } - } - return arr, nil - default: - // If the target type is a string and the YAML type is a number, - // convert the YAML type to a string. - if jsonTarget != nil && (*jsonTarget).Kind() == reflect.String { - // Based on my reading of go-yaml, it may return int, int64, - // float64, or uint64. - var s string - switch typedVal := typedYAMLObj.(type) { - case int: - s = strconv.FormatInt(int64(typedVal), 10) - case int64: - s = strconv.FormatInt(typedVal, 10) - case float64: - s = strconv.FormatFloat(typedVal, 'g', -1, 32) - case uint64: - s = strconv.FormatUint(typedVal, 10) - case bool: - if typedVal { - s = "true" - } else { - s = "false" - } - } - if len(s) > 0 { - yamlObj = interface{}(s) - } - } - return yamlObj, nil - } - - return nil, nil -} diff --git a/vendor/github.com/jaypipes/ghw/Dockerfile b/vendor/github.com/jaypipes/ghw/Dockerfile index cbd587d6c6..ee5d276170 100644 --- a/vendor/github.com/jaypipes/ghw/Dockerfile +++ b/vendor/github.com/jaypipes/ghw/Dockerfile @@ -1,8 +1,6 @@ -FROM golang:1.15-buster as builder +FROM golang:1.21-buster as builder WORKDIR /go/src/github.com/jaypipes/ghw -# Force the go compiler to use modules. -ENV GO111MODULE=on ENV GOPROXY=direct # go.mod and go.sum go into their own layers. @@ -16,7 +14,7 @@ COPY . . RUN CGO_ENABLED=0 go build -o ghwc ./cmd/ghwc/ -FROM alpine:3.7 +FROM alpine:3.7@sha256:8421d9a84432575381bfabd248f1eb56f3aa21d9d7cd2511583c68c9b7511d10 RUN apk add --no-cache ethtool WORKDIR /bin diff --git a/vendor/github.com/jaypipes/ghw/Makefile b/vendor/github.com/jaypipes/ghw/Makefile index c7e0db4020..75d2bcc8b5 100644 --- a/vendor/github.com/jaypipes/ghw/Makefile +++ b/vendor/github.com/jaypipes/ghw/Makefile @@ -1,39 +1,16 @@ -VENDOR := vendor -PKGS := $(shell go list ./... | grep -v /$(VENDOR)/) -SRC = $(shell find . -type f -name '*.go' -not -path "*/$(VENDOR)/*") -BIN_DIR := $(GOPATH)/bin -GOMETALINTER := $(BIN_DIR)/gometalinter - .PHONY: test test: vet - go test $(PKGS) - -$(GOMETALINTER): - go get -u github.com/alecthomas/gometalinter - $(GOMETALINTER) --install &> /dev/null - -.PHONY: lint -lint: $(GOMETALINTER) - $(GOMETALINTER) ./... --vendor + go test -v ./... .PHONY: fmt fmt: @echo "Running gofmt on all sources..." - @gofmt -s -l -w $(SRC) + @gofmt -s -l -w . .PHONY: fmtcheck fmtcheck: - @bash -c "diff -u <(echo -n) <(gofmt -d $(SRC))" + @bash -c "diff -u <(echo -n) <(gofmt -d .)" .PHONY: vet vet: - go vet $(PKGS) - -.PHONY: cover -cover: - $(shell [ -e coverage.out ] && rm coverage.out) - @echo "mode: count" > coverage-all.out - $(foreach pkg,$(PKGS),\ - go test -coverprofile=coverage.out -covermode=count $(pkg);\ - tail -n +2 coverage.out >> coverage-all.out;) - go tool cover -html=coverage-all.out -o=coverage-all.html + go vet ./... diff --git a/vendor/github.com/jaypipes/ghw/README.md b/vendor/github.com/jaypipes/ghw/README.md index 1f3f04a74f..c1cdb1064a 100644 --- a/vendor/github.com/jaypipes/ghw/README.md +++ b/vendor/github.com/jaypipes/ghw/README.md @@ -1,13 +1,14 @@ -# `ghw` - Golang HardWare discovery/inspection library +# `ghw` - Go HardWare discovery/inspection library -[![Build Status](https://github.com/jaypipes/ghw/actions/workflows/go.yml/badge.svg?branch=main)](https://github.com/jaypipes/ghw/actions) +[![Go Reference](https://pkg.go.dev/badge/github.com/jaypipes/ghw.svg)](https://pkg.go.dev/github.com/jaypipes/ghw) [![Go Report Card](https://goreportcard.com/badge/github.com/jaypipes/ghw)](https://goreportcard.com/report/github.com/jaypipes/ghw) +[![Build Status](https://github.com/jaypipes/ghw/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/jaypipes/ghw/actions) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md) ![ghw mascot](images/ghw-gopher.png) -`ghw` is a small Golang library providing hardware inspection and discovery -for Linux and Windows. There currently exists partial support for MacOSX. +`ghw` is a Go library providing hardware inspection and discovery for Linux and +Windows. There currently exists partial support for MacOSX. ## Design Principles @@ -20,13 +21,12 @@ for Linux and Windows. There currently exists partial support for MacOSX. Elevated privileges are indeed required to query for some information, but `ghw` will never error out if blocked from reading that information. Instead, `ghw` will print a warning message about the information that could not be - retrieved. You may disable these warning messages with `GHW_DISABLE_WARNINGS` - environment variable. + retrieved. You may disable these warning messages with the + `GHW_DISABLE_WARNINGS` environment variable. * Well-documented code and plenty of example code - The code itself should be well-documented with lots of usage - examples. + The code itself should be well-documented with lots of usage examples. * Interfaces should be consistent across modules @@ -42,250 +42,158 @@ and **capabilities**. It is important to point out that `ghw` does **NOT** report information that is temporary or variable. It is **NOT** a system monitor nor is it an appropriate tool for gathering data points for metrics that change over time. If you are -looking for a system that tracks usage of CPU, memory, network I/O or disk I/O, -there are plenty of great open source tools that do this! Check out the +looking for a system that tracks **usage** of CPU, memory, network I/O or disk +I/O, there are plenty of great open source tools that do this! Check out the [Prometheus project](https://prometheus.io/) for a great example. ## Usage -You can use the functions in `ghw` to determine various hardware-related -information about the host computer: - -* [Memory](#memory) -* [CPU](#cpu) -* [Block storage](#block-storage) -* [Topology](#topology) -* [Network](#network) -* [PCI](#pci) -* [GPU](#gpu) -* [Chassis](#chassis) -* [BIOS](#bios) -* [Baseboard](#baseboard) -* [Product](#product) -* [YAML and JSON serialization](#serialization) +`ghw` has functions that return an `Info` object about a particular hardware +domain (e.g. CPU, Memory, Block storage, etc). + +Use the following functions in `ghw` to inspect information about the host +hardware: + +* [`ghw.CPU()`](#cpu) +* [`ghw.Memory()`](#memory) +* [`ghw.Block()`](#block-storage) (block storage) +* [`ghw.Topology()`](#topology) (processor architecture, NUMA topology and + memory cache hierarchy) +* [`ghw.Network()`](#network) +* [`ghw.PCI()`](#pci) +* [`ghw.GPU()`](#gpu) (graphical processing unit) +* [`ghw.Chassis()`](#chassis) +* [`ghw.BIOS()`](#bios) +* [`ghw.Baseboard()`](#baseboard) +* [`ghw.Product()`](#product) -### Overriding the root mountpoint `ghw` uses - -The default root mountpoint that `ghw` uses when looking for information about -the host system is `/`. So, for example, when looking up CPU information on a -Linux system, `ghw.CPU()` will use the path `/proc/cpuinfo`. - -If you are calling `ghw` from a system that has an alternate root mountpoint, -you can either set the `GHW_CHROOT` environment variable to that alternate -path, or call the module constructor function with the `ghw.WithChroot()` -modifier. - -For example, if you are executing from within an application container that has -bind-mounted the root host filesystem to the mount point `/host`, you would set -`GHW_CHROOT` to `/host` so that `ghw` can find `/proc/cpuinfo` at -`/host/proc/cpuinfo`. - -Alternately, you can use the `ghw.WithChroot()` function like so: - -```go -cpu, err := ghw.CPU(ghw.WithChroot("/host")) -``` - -### Overriding the per-mountpoint `ghw` uses - -When running inside containers, it could be a bit cumbersome to just override -the root mountpoint. Inside containers, when granting access to the host -file systems, is more common to bind-mount them in non standard location, -like `/sys` on `/host-sys` or `/proc` on `/host-proc`. -Is rarer to mount them in a common subtree (e.g. `/sys` on `/host/sys` and - `/proc` on /host/proc...) - -To better cover this use case, `ghw` allows to *programmatically* override -the initial component of filesystems subtrees, allowing to access `sysfs` -(or `procfs` or...) mounted on non-standard locations. - - -```go -cpu, err := ghw.CPU(ghw.WithPathOverrides(ghw.PathOverrides{ - "/proc": "/host-proc", - "/sys": "/host-sys", -})) -``` - -Please note -- this feature works in addition and is composable with the - `WithChroot`/`GHW_CHROOT` feature. -- `ghw` doesn't support yet environs variable to override individual - mountpoints, because this could lead to significant environs variables - proliferation. - -### Consuming snapshots - -You can make `ghw` read from snapshots (created with `ghw-snapshot`) using -environment variables or programmatically. -Please check `SNAPSHOT.md` to learn more about how ghw creates and consumes -snapshots. - -The environment variable `GHW_SNAPSHOT_PATH` let users specify a snapshot -that `ghw` will automatically consume. All the needed chroot changes will be -automatically performed. By default, the snapshot is unpacked on a temporary -directory managed by `ghw`, and cleaned up when no longer needed, avoiding -leftovers. - -The rest of the environment variables are relevant iff `GHW_SNAPSHOT_PATH` is given. -`GHW_SNAPSHOT_ROOT` let users specify the directory -on which the snapshot should be unpacked. This moves the ownership of that -directory from `ghw` to users. For this reason, `ghw` will *not* clean up automatically -the content unpacked in `GHW_SNAPSHOT_ROOT`. - -`GHW_SNAPSHOT_EXCLUSIVE` is relevant iff `GHW_SNAPSHOT_ROOT` is given. -Set it to any value to toggle it on. This tells `ghw` that the directory is meant -only to contain the given snapshot, thus `ghw` will *not* attempt to unpack it -(and will go ahead silently!) unless the directory is empty. -You can use both `GHW_SNAPSHOT_ROOT` and `GHW_SNAPSHOT_EXCLUSIVE` to make sure -`ghw` unpacks the snapshot only once regardless of how many `ghw` packages -(e.g. cpu, memory) access it. - -Set `GHW_SNAPSHOT_PRESERVE` to any value to enable it. If set, `ghw` will *not* -clean up the unpacked snapshot once done, leaving it into the system. +### CPU -```go -cpu, err := ghw.CPU(ghw.WithSnapshot(ghw.SnapshotOptions{ - Path: "/path/to/linux-amd64-d4771ed3300339bc75f856be09fc6430.tar.gz", -})) +The `ghw.CPU()` function returns a `ghw.CPUInfo` struct that contains +information about the CPUs on the host system. +`ghw.CPUInfo` contains the following fields: -myRoot := "/my/safe/directory" -cpu, err := ghw.CPU(ghw.WithSnapshot(ghw.SnapshotOptions{ - Path: "/path/to/linux-amd64-d4771ed3300339bc75f856be09fc6430.tar.gz", - Root: &myRoot, -})) +* `ghw.CPUInfo.TotalCores` has the total number of physical cores the host + system contains +* `ghw.CPUInfo.TotalThreads` has the total number of hardware threads the + host system contains +* `ghw.CPUInfo.Processors` is an array of `ghw.Processor` structs, one for each + physical processor package contained in the host -myOtherRoot := "/my/other/safe/directory" -cpu, err := ghw.CPU(ghw.WithSnapshot(ghw.SnapshotOptions{ - Path: "/path/to/linux-amd64-d4771ed3300339bc75f856be09fc6430.tar.gz", - Root: &myOtherRoot, - Exclusive: true, -})) -``` +Each `ghw.Processor` struct contains a number of fields: -### Creating snapshots +* `ghw.Processor.ID` is the physical processor `uint32` ID according to the + system +* `ghw.Processor.NumCores` is the number of physical cores in the processor + package +* `ghw.Processor.NumThreads` is the number of hardware threads in the processor + package +* `ghw.Processor.Vendor` is a string containing the vendor name +* `ghw.Processor.Model` is a string containing the vendor's model name +* `ghw.Processor.Capabilities` (Linux only) is an array of strings indicating + the features the processor has enabled +* `ghw.Processor.Cores` (Linux only) is an array of `ghw.ProcessorCore` structs + that are packed onto this physical processor -You can create ghw snapshots in two ways. -You can just consume the `ghw-snapshot` tool, or you can create them programmatically -from your golang code. We explore now the latter case. +A `ghw.ProcessorCore` has the following fields: -Snapshotting takes two phases: -1. clone the relevant pseudofiles/pseudodirectories into a temporary tree - This tree is usually deleted once the packing is successful. -2. pack the cloned tree into a tar.gz +* `ghw.ProcessorCore.ID` is the `uint32` identifier that the host gave this + core. Note that this does *not* necessarily equate to a zero-based index of + the core within a physical package. For example, the core IDs for an Intel Core + i7 are 0, 1, 2, 8, 9, and 10 +* `ghw.ProcessorCore.NumThreads` is the number of hardware threads associated + with the core +* `ghw.ProcessorCore.LogicalProcessors` is an array of ints representing the + logical processor IDs assigned to any processing unit for the core. These are + sometimes called the "thread siblings". Logical processor IDs are the + *zero-based* index of the processor on the host and are *not* related to the + core ID. ```go +package main import ( "fmt" - "io/ioutil" - "os" + "math" + "strings" - "github.com/jaypipes/ghw/pkg/snapshot" + "github.com/jaypipes/ghw" ) -// ... - -scratchDir, err := ioutil.TempDir("", "ghw-snapshot-*") -if err != nil { - fmt.Printf("Error creating clone directory: %v", err) -} -defer os.RemoveAll(scratchDir) - -// this step clones all the files and directories ghw cares about -if err := snapshot.CloneTreeInto(scratchDir); err != nil { - fmt.Printf("error cloning into %q: %v", scratchDir, err) -} - -// optionally, you may add extra content into your snapshot. -// ghw will ignore the extra content. -// Glob patterns like `filepath.Glob` are supported. -fileSpecs := []string{ - "/proc/cmdline", -} +func main() { + cpu, err := ghw.CPU() + if err != nil { + fmt.Printf("Error getting CPU info: %v", err) + } -// options allows the client code to optionally deference symlinks, or copy -// them into the cloned tree as symlinks -var opts *snapshot.CopyFileOptions -if err := snapshot.CopyFilesInto(fileSpecs, scratchDir, opts); err != nil { - fmt.Printf("error cloning extra files into %q: %v", scratchDir, err) -} + fmt.Printf("%v\n", cpu) -// automates the creation of the gzipped tarball out of the given tree. -if err := snapshot.PackFrom("my-snapshot.tgz", scratchDir); err != nil { - fmt.Printf("error packing %q into %q: %v", scratchDir, *output, err) + for _, proc := range cpu.Processors { + fmt.Printf(" %v\n", proc) + for _, core := range proc.Cores { + fmt.Printf(" %v\n", core) + } + if len(proc.Capabilities) > 0 { + // pretty-print the (large) block of capability strings into rows + // of 6 capability strings + rows := int(math.Ceil(float64(len(proc.Capabilities)) / float64(6))) + for row := 1; row < rows; row = row + 1 { + rowStart := (row * 6) - 1 + rowEnd := int(math.Min(float64(rowStart+6), float64(len(proc.Capabilities)))) + rowElems := proc.Capabilities[rowStart:rowEnd] + capStr := strings.Join(rowElems, " ") + if row == 1 { + fmt.Printf(" capabilities: [%s\n", capStr) + } else if rowEnd < len(proc.Capabilities) { + fmt.Printf(" %s\n", capStr) + } else { + fmt.Printf(" %s]\n", capStr) + } + } + } + } } ``` -### Disabling warning messages - -When `ghw` isn't able to retrieve some information, it may print certain -warning messages to `stderr`. To disable these warnings, simply set the -`GHW_DISABLE_WARNINGS` environs variable: - -``` -$ ghwc memory -WARNING: -Could not determine total physical bytes of memory. This may -be due to the host being a virtual machine or container with no -/var/log/syslog file, or the current user may not have necessary -privileges to read the syslog. We are falling back to setting the -total physical amount of memory to the total usable amount of memory -memory (24GB physical, 24GB usable) -``` +Example output from my personal workstation: ``` -$ GHW_DISABLE_WARNINGS=1 ghwc memory -memory (24GB physical, 24GB usable) -``` - -You can disable warning programmatically using the `WithDisableWarnings` option: - -```go - -import ( - "github.com/jaypipes/ghw" -) - -mem, err := ghw.Memory(ghw.WithDisableWarnings()) +cpu (1 physical package, 6 cores, 12 hardware threads) + physical package #0 (6 cores, 12 hardware threads) + processor core #0 (2 threads), logical processors [0 6] + processor core #1 (2 threads), logical processors [1 7] + processor core #2 (2 threads), logical processors [2 8] + processor core #3 (2 threads), logical processors [3 9] + processor core #4 (2 threads), logical processors [4 10] + processor core #5 (2 threads), logical processors [5 11] + capabilities: [msr pae mce cx8 apic sep + mtrr pge mca cmov pat pse36 + clflush dts acpi mmx fxsr sse + sse2 ss ht tm pbe syscall + nx pdpe1gb rdtscp lm constant_tsc arch_perfmon + pebs bts rep_good nopl xtopology nonstop_tsc + cpuid aperfmperf pni pclmulqdq dtes64 monitor + ds_cpl vmx est tm2 ssse3 cx16 + xtpr pdcm pcid sse4_1 sse4_2 popcnt + aes lahf_lm pti retpoline tpr_shadow vnmi + flexpriority ept vpid dtherm ida arat] ``` -`WithDisableWarnings` is a alias for the `WithNullAlerter` option, which in turn -leverages the more general `Alerter` feature of ghw. - -You may supply a `Alerter` to ghw to redirect all the warnings there, like -logger objects (see for example golang's stdlib `log.Logger`). -`Alerter` is in fact the minimal logging interface `ghw needs. -To learn more, please check the `option.Alerter` interface and the `ghw.WithAlerter()` -function. - ### Memory -The basic building block of the memory support in ghw is the `ghw.MemoryArea` struct. -A "memory area" is a block of memory which share common properties. In the simplest -case, the whole system memory fits in a single memory area; in more complex scenarios, -like multi-NUMA systems, many memory areas may be present in the system (e.g. one for -each NUMA cell). +The `ghw.Memory()` function returns a `ghw.MemoryInfo` struct that contains +information about the RAM on the host system. -The `ghw.MemoryArea` struct contains the following fields: +`ghw.MemoryInfo` contains the following fields: * `ghw.MemoryInfo.TotalPhysicalBytes` contains the amount of physical memory on the host * `ghw.MemoryInfo.TotalUsableBytes` contains the amount of memory the system can actually use. Usable memory accounts for things like the kernel's - resident memory size and some reserved system bits - -Information about the host computer's memory can be retrieved using the -`ghw.Memory()` function which returns a pointer to a `ghw.MemoryInfo` struct. -`ghw.MemoryInfo` is a superset of `ghw.MemoryArea`. Thus, it contains all the -fields found in the `ghw.MemoryArea` (replicated for clarity) plus some: - -* `ghw.MemoryInfo.TotalPhysicalBytes` contains the amount of physical memory on - the host -* `ghw.MemoryInfo.TotalUsableBytes` contains the amount of memory the - system can actually use. Usable memory accounts for things like the kernel's - resident memory size and some reserved system bits + resident memory size and some reserved system bits. Please note this value is + **NOT** the amount of memory currently in use by processes in the system. See + [the discussion][#physical-versus-usage-memory] about the difference. * `ghw.MemoryInfo.SupportedPageSizes` is an array of integers representing the size, in bytes, of memory pages the system supports * `ghw.MemoryInfo.Modules` is an array of pointers to `ghw.MemoryModule` @@ -373,153 +281,43 @@ system with a Linux GRUB bootloader: The bootloader consumes 3832720 bytes of RAM ``` -### CPU - -The `ghw.CPU()` function returns a `ghw.CPUInfo` struct that contains -information about the CPUs on the host system. - -`ghw.CPUInfo` contains the following fields: - -* `ghw.CPUInfo.TotalCores` has the total number of physical cores the host - system contains -* `ghw.CPUInfo.TotalThreads` has the total number of hardware threads the - host system contains -* `ghw.CPUInfo.Processors` is an array of `ghw.Processor` structs, one for each - physical processor package contained in the host - -Each `ghw.Processor` struct contains a number of fields: - -* `ghw.Processor.ID` is the physical processor `uint32` ID according to the - system -* `ghw.Processor.NumCores` is the number of physical cores in the processor - package -* `ghw.Processor.NumThreads` is the number of hardware threads in the processor - package -* `ghw.Processor.Vendor` is a string containing the vendor name -* `ghw.Processor.Model` is a string containing the vendor's model name -* `ghw.Processor.Capabilities` is an array of strings indicating the features - the processor has enabled -* `ghw.Processor.Cores` is an array of `ghw.ProcessorCore` structs that are - packed onto this physical processor - -A `ghw.ProcessorCore` has the following fields: - -* `ghw.ProcessorCore.ID` is the `uint32` identifier that the host gave this - core. Note that this does *not* necessarily equate to a zero-based index of - the core within a physical package. For example, the core IDs for an Intel Core - i7 are 0, 1, 2, 8, 9, and 10 -* `ghw.ProcessorCore.NumThreads` is the number of hardware threads associated - with the core -* `ghw.ProcessorCore.LogicalProcessors` is an array of ints representing the - logical processor IDs assigned to any processing unit for the core. These are - sometimes called the "thread siblings". Logical processor IDs are the - *zero-based* index of the processor on the host and are *not* related to the - core ID. - -```go -package main - -import ( - "fmt" - "math" - "strings" - - "github.com/jaypipes/ghw" -) - -func main() { - cpu, err := ghw.CPU() - if err != nil { - fmt.Printf("Error getting CPU info: %v", err) - } - - fmt.Printf("%v\n", cpu) - - for _, proc := range cpu.Processors { - fmt.Printf(" %v\n", proc) - for _, core := range proc.Cores { - fmt.Printf(" %v\n", core) - } - if len(proc.Capabilities) > 0 { - // pretty-print the (large) block of capability strings into rows - // of 6 capability strings - rows := int(math.Ceil(float64(len(proc.Capabilities)) / float64(6))) - for row := 1; row < rows; row = row + 1 { - rowStart := (row * 6) - 1 - rowEnd := int(math.Min(float64(rowStart+6), float64(len(proc.Capabilities)))) - rowElems := proc.Capabilities[rowStart:rowEnd] - capStr := strings.Join(rowElems, " ") - if row == 1 { - fmt.Printf(" capabilities: [%s\n", capStr) - } else if rowEnd < len(proc.Capabilities) { - fmt.Printf(" %s\n", capStr) - } else { - fmt.Printf(" %s]\n", capStr) - } - } - } - } -} -``` - -Example output from my personal workstation: - -``` -cpu (1 physical package, 6 cores, 12 hardware threads) - physical package #0 (6 cores, 12 hardware threads) - processor core #0 (2 threads), logical processors [0 6] - processor core #1 (2 threads), logical processors [1 7] - processor core #2 (2 threads), logical processors [2 8] - processor core #3 (2 threads), logical processors [3 9] - processor core #4 (2 threads), logical processors [4 10] - processor core #5 (2 threads), logical processors [5 11] - capabilities: [msr pae mce cx8 apic sep - mtrr pge mca cmov pat pse36 - clflush dts acpi mmx fxsr sse - sse2 ss ht tm pbe syscall - nx pdpe1gb rdtscp lm constant_tsc arch_perfmon - pebs bts rep_good nopl xtopology nonstop_tsc - cpuid aperfmperf pni pclmulqdq dtes64 monitor - ds_cpl vmx est tm2 ssse3 cx16 - xtpr pdcm pcid sse4_1 sse4_2 popcnt - aes lahf_lm pti retpoline tpr_shadow vnmi - flexpriority ept vpid dtherm ida arat] -``` - ### Block storage -Information about the host computer's local block storage is returned from the -`ghw.Block()` function. This function returns a pointer to a `ghw.BlockInfo` -struct. +The `ghw.Block()` function returns a `ghw.BlockInfo` struct that contains +information about the block storage on the host system. -The `ghw.BlockInfo` struct contains two fields: +`ghw.BlockInfo` contains the following fields: -* `ghw.BlockInfo.TotalPhysicalBytes` contains the amount of physical block - storage on the host +* `ghw.BlockInfo.TotalSizeBytes` contains the amount of physical block storage + on the host. * `ghw.BlockInfo.Disks` is an array of pointers to `ghw.Disk` structs, one for - each disk drive found by the system + each disk found by the system Each `ghw.Disk` struct contains the following fields: * `ghw.Disk.Name` contains a string with the short name of the disk, e.g. "sda" * `ghw.Disk.SizeBytes` contains the amount of storage the disk provides * `ghw.Disk.PhysicalBlockSizeBytes` contains the size of the physical blocks - used on the disk, in bytes + used on the disk, in bytes. This is typically the minimum amount of data that + will be written in a single write operation for the disk. * `ghw.Disk.IsRemovable` contains a boolean indicating if the disk drive is removable * `ghw.Disk.DriveType` is the type of drive. It is of type `ghw.DriveType` which has a `ghw.DriveType.String()` method that can be called to return a - string representation of the bus. This string will be "HDD", "FDD", "ODD", - or "SSD", which correspond to a hard disk drive (rotational), floppy drive, + string representation of the bus. This string will be `HDD`, `FDD`, `ODD`, + or `SSD`, which correspond to a hard disk drive (rotational), floppy drive, optical (CD/DVD) drive and solid-state drive. -* `ghw.Disk.StorageController` is the type of storage controller/drive. It is - of type `ghw.StorageController` which has a `ghw.StorageController.String()` - method that can be called to return a string representation of the bus. This - string will be "SCSI", "IDE", "virtio", "MMC", or "NVMe" -* `ghw.Disk.NUMANodeID` is the numeric index of the NUMA node this disk is - local to, or -1 +* `ghw.Disk.StorageController` is the type of storage controller. It is of type + `ghw.StorageController` which has a `ghw.StorageController.String()` method + that can be called to return a string representation of the bus. This string + will be `SCSI`, `IDE`, `virtio`, `MMC`, or `NVMe` +* `ghw.Disk.BusPath` (Linux, Darwin only) is the filepath to the bus used by + the disk. +* `ghw.Disk.NUMANodeID` (Linux only) is the numeric index of the NUMA node this + disk is local to, or -1 if the host system is not a NUMA system or is not + Linux. * `ghw.Disk.Vendor` contains a string with the name of the hardware vendor for - the disk drive + the disk * `ghw.Disk.Model` contains a string with the vendor-assigned disk model name * `ghw.Disk.SerialNumber` contains a string with the disk's serial number * `ghw.Disk.WWN` contains a string with the disk's @@ -530,27 +328,27 @@ Each `ghw.Disk` struct contains the following fields: Each `ghw.Partition` struct contains these fields: * `ghw.Partition.Name` contains a string with the short name of the partition, - e.g. "sda1" + e.g. `sda1` * `ghw.Partition.Label` contains the label for the partition itself. On Linux - systems, this is derived from the `ID_PART_ENTRY_NAME` udev entry for the - partition. + systems, this is derived from the `ID_PART_ENTRY_NAME` [udev][udev] entry for + the partition. * `ghw.Partition.FilesystemLabel` contains the label for the filesystem housed on the partition. On Linux systems, this is derived from the `ID_FS_NAME` - udev entry for the partition. + [udev][udev] entry for the partition. * `ghw.Partition.SizeBytes` contains the amount of storage the partition provides * `ghw.Partition.MountPoint` contains a string with the partition's mount - point, or "" if no mount point was discovered + point, or `""` if no mount point was discovered * `ghw.Partition.Type` contains a string indicated the filesystem type for the - partition, or "" if the system could not determine the type + partition, or `""` if the system could not determine the type * `ghw.Partition.IsReadOnly` is a bool indicating the partition is read-only * `ghw.Partition.Disk` is a pointer to the `ghw.Disk` object associated with - the partition. This will be `nil` if the `ghw.Partition` struct was returned - by the `ghw.DiskPartitions()` library function. + the partition. * `ghw.Partition.UUID` is a string containing the partition UUID on Linux, the - partition UUID on MacOS and nothing on Windows. On Linux - systems, this is derived from the `ID_PART_ENTRY_UUID` udev entry for the - partition. + partition UUID on MacOS and nothing on Windows. On Linux systems, this is + derived from the `ID_PART_ENTRY_UUID` [udev][udev] entry for the partition. + +[udev]: https://en.wikipedia.org/wiki/Udev ```go package main @@ -591,7 +389,7 @@ block storage (1 disk, 2TB physical storage) /dev/sda6 (2TB) [ext4] mounted@/ ``` -> Note that `ghw` looks in the udev runtime database for some information. If +> **NOTE**: `ghw` looks in the udev runtime database for some information. If > you are using `ghw` in a container, remember to bind mount `/dev/disk` and > `/run` into your container, otherwise `ghw` won't be able to query the udev > DB or sysfs paths for information. @@ -601,9 +399,9 @@ block storage (1 disk, 2TB physical storage) > **NOTE**: Topology support is currently Linux-only. Windows support is > [planned](https://github.com/jaypipes/ghw/issues/166). -Information about the host computer's architecture (NUMA vs. SMP), the host's -node layout and processor caches can be retrieved from the `ghw.Topology()` -function. This function returns a pointer to a `ghw.TopologyInfo` struct. +The `ghw.Topology()` function returns a `ghw.TopologyInfo` struct that contains +information about the host computer's architecture (NUMA vs. SMP), the host's +NUMA node layout and processor-specific memory caches. The `ghw.TopologyInfo` struct contains two fields: @@ -616,6 +414,8 @@ The `ghw.TopologyInfo` struct contains two fields: Each `ghw.TopologyNode` struct contains the following fields: * `ghw.TopologyNode.ID` is the system's `uint32` identifier for the node +* `ghw.TopologyNode.Memory` is a `ghw.MemoryArea` struct describing the memory + attached to this node. * `ghw.TopologyNode.Cores` is an array of pointers to `ghw.ProcessorCore` structs that are contained in this node * `ghw.TopologyNode.Caches` is an array of pointers to `ghw.MemoryCache` structs that @@ -623,8 +423,25 @@ Each `ghw.TopologyNode` struct contains the following fields: system * `ghw.TopologyNode.Distance` is an array of distances between NUMA nodes as reported by the system. -* `ghw.TopologyNode.Memory` is a struct describing the memory attached to this node. - Please refer to the documentation of `ghw.MemoryArea`. + +`ghw.MemoryArea` describes a collection of *physical* RAM on the host. + +In the simplest and most common case, all system memory fits in a single memory +area. In more complex host systems, like [NUMA systems][numa], many memory +areas may be present in the host system (e.g. one for each NUMA cell). + +[numa]: https://en.wikipedia.org/wiki/Non-uniform_memory_access + +The `ghw.MemoryArea` struct contains the following fields: + +* `ghw.MemoryArea.TotalPhysicalBytes` contains the amount of physical memory + associated with this memory area. +* `ghw.MemoryArea.TotalUsableBytes` contains the amount of memory of this + memory area the system can actually use. Usable memory accounts for things + like the kernel's resident memory size and some reserved system bits. Please + note this value is **NOT** the amount of memory currently in use by processes + in the system. See [the discussion][#physical-versus-usage-memory] about + the difference. See above in the [CPU](#cpu) section for information about the `ghw.ProcessorCore` struct and how to use and query it. @@ -635,7 +452,8 @@ Each `ghw.MemoryCache` struct contains the following fields: `ghw.INSTRUCTION` or `ghw.UNIFIED` depending on whether the cache stores CPU instructions, program data, or both * `ghw.MemoryCache.Level` is a positive integer indicating how close the cache - is to the processor + is to the processor. The lower the number, the closer the cache is to the + processor and the faster the processor can access its contents * `ghw.MemoryCache.SizeBytes` is an integer containing the number of bytes the cache can contain * `ghw.MemoryCache.LogicalProcessors` is an array of integers representing the @@ -695,9 +513,8 @@ topology SMP (1 nodes) ### Network -Information about the host computer's networking hardware is returned from the -`ghw.Network()` function. This function returns a pointer to a -`ghw.NetworkInfo` struct. +The `ghw.Network()` function returns a `ghw.NetworkInfo` struct that contains +information about the host computer's networking hardware. The `ghw.NetworkInfo` struct contains one field: @@ -707,30 +524,32 @@ The `ghw.NetworkInfo` struct contains one field: Each `ghw.NIC` struct contains the following fields: * `ghw.NIC.Name` is the system's identifier for the NIC -* `ghw.NIC.MacAddress` is the MAC address for the NIC, if any +* `ghw.NIC.MACAddress` is the Media Access Control (MAC) address for the NIC, + if any * `ghw.NIC.IsVirtual` is a boolean indicating if the NIC is a virtualized device -* `ghw.NIC.Capabilities` is an array of pointers to `ghw.NICCapability` structs - that can describe the things the NIC supports. These capabilities match the - returned values from the `ethtool -k ` call on Linux as well as the - AutoNegotiation and PauseFrameUse capabilities from `ethtool`. -* `ghw.NIC.PCIAddress` is the PCI device address of the device backing the NIC. - this is not-nil only if the backing device is indeed a PCI device; more backing - devices (e.g. USB) will be added in future versions. -* `ghw.NIC.Speed` is a string showing the current link speed. On Linux, this - field will be present even if `ethtool` is not available. -* `ghw.NIC.Duplex` is a string showing the current link duplex. On Linux, this - field will be present even if `ethtool` is not available. -* `ghw.NIC.SupportedLinkModes` is a string slice containing a list of - supported link modes -* `ghw.NIC.SupportedPorts` is a string slice containing the list of - supported port types (MII, TP, FIBRE) -* `ghw.NIC.SupportedFECModes` is a string slice containing a list of - supported FEC Modes. -* `ghw.NIC.AdvertisedLinkModes` is a string slice containing the +* `ghw.NIC.Capabilities` (Linux only) is an array of pointers to + `ghw.NICCapability` structs that can describe the things the NIC supports. + These capabilities match the returned values from the `ethtool -k ` + call on Linux as well as the AutoNegotiation and PauseFrameUse capabilities + from `ethtool`. +* `ghw.NIC.PCIAddress` (Linux only) is the PCI device address of the device + backing the NIC. this is not-nil only if the backing device is indeed a PCI + device; more backing devices (e.g. USB) will be added in future versions. +* `ghw.NIC.Speed` (Linux only) is a string showing the current link speed. On + Linux, this field will be present even if `ethtool` is not available. +* `ghw.NIC.Duplex` (Linux only) is a string showing the current link duplex. On + Linux, this field will be present even if `ethtool` is not available. +* `ghw.NIC.SupportedLinkModes` (Linux only) is a string slice containing a list + of supported link modes, e.g. "10baseT/Half", "1000baseT/Full". +* `ghw.NIC.SupportedPorts` (Linux only) is a string slice containing the list + of supported port types, e.g. "MII", "TP", "FIBRE", "Twisted Pair". +* `ghw.NIC.SupportedFECModes` (Linux only) is a string slice containing a list + of supported Forward Error Correction (FEC) Modes. +* `ghw.NIC.AdvertisedLinkModes` (Linux only) is a string slice containing the link modes being advertised during auto negotiation. -* `ghw.NIC.AdvertisedFECModes` is a string slice containing the FEC - modes advertised during auto negotiation. +* `ghw.NIC.AdvertisedFECModes` (Linux only) is a string slice containing the + Forward Error Correction (FEC) modes advertised during auto negotiation. The `ghw.NICCapability` struct contains the following fields: @@ -837,35 +656,22 @@ developers to not only gather information about devices on a local PCI bus but also query for information about hardware device classes, vendor and product information. -**NOTE**: Parsing of the PCI-IDS file database is provided by the separate -[github.com/jaypipes/pcidb library](http://github.com/jaypipes/pcidb). You can -read that library's README for more information about the various structs that -are exposed on the `ghw.PCIInfo` struct. +> **NOTE**: Parsing of the PCI-IDS file database is provided by the separate +> [github.com/jaypipes/pcidb library](http://github.com/jaypipes/pcidb). You +> can read that library's README for more information about the various structs +> that are exposed on the `ghw.PCIInfo` struct. + +The `ghw.PCI()` function returns a `ghw.PCIInfo` struct that contains +information about the host computer's PCI devices. -The `ghw.PCI()` function returns a `ghw.PCIInfo` struct. The `ghw.PCIInfo` -struct contains a number of fields that may be queried for PCI information: +The `ghw.PCIInfo` struct contains one field: * `ghw.PCIInfo.Devices` is a slice of pointers to `ghw.PCIDevice` structs that describe the PCI devices on the host system -* `ghw.PCIInfo.Classes` is a map, keyed by the PCI class ID (a hex-encoded - string) of pointers to `pcidb.Class` structs, one for each class of PCI - device known to `ghw` - (**DEPRECATED**, will be removed in `ghw` `v1.0`. Use the - `github.com/jaypipes/pcidb` library for exploring PCI database information) -* `ghw.PCIInfo.Vendors` is a map, keyed by the PCI vendor ID (a hex-encoded - string) of pointers to `pcidb.Vendor` structs, one for each PCI vendor - known to `ghw` - (**DEPRECATED**, will be removed in `ghw` `v1.0`. Use the - `github.com/jaypipes/pcidb` library for exploring PCI database information) -* `ghw.PCIInfo.Products` is a map, keyed by the PCI product ID (a hex-encoded - string) of pointers to `pcidb.Product` structs, one for each PCI product - known to `ghw` - (**DEPRECATED**, will be removed in `ghw` `v1.0`. Use the - `github.com/jaypipes/pcidb` library for exploring PCI database information) - -**NOTE**: PCI products are often referred to by their "device ID". We use -the term "product ID" in `ghw` because it more accurately reflects what the -identifier is for: a specific product line produced by the vendor. + +> **NOTE**: PCI products are often referred to by their "device ID". We use the +> term "product ID" in `ghw` because it more accurately reflects what the +> identifier is for: a specific product line produced by the vendor. The `ghw.PCIDevice` struct has the following fields: @@ -884,9 +690,9 @@ The `ghw.PCIDevice` struct has the following fields: programming interface. This will always be non-nil. * `ghw.PCIDevice.Driver` is a string representing the device driver the system is using to handle this device. Can be empty string if this - information is not available. If the information is not available, - this doesn't mean at all the device is not functioning, but only the - fact `ghw` was not able to retrieve this information. + information is not available. If the information is not available, this does + not mean the device is not functioning, but rather that `ghw` was not able to + retrieve driver information. The `ghw.PCIAddress` (which is an alias for the `ghw.pci.address.Address` struct) contains the PCI address fields. It has a `ghw.PCIAddress.String()` @@ -904,19 +710,12 @@ The `ghw.PCIAddress` struct has the following fields: * `ghw.PCIAddress.Function` is a string representing the PCI function component of the address. -**NOTE**: Older versions (pre-`v0.9.0`) erroneously referred to the `Device` -field as the `Slot` field. As noted by [@pearsonk](https://github.com/pearsonk) -in [#220](https://github.com/jaypipes/ghw/issues/220), this was a misnomer. - -#### Finding a PCI device by PCI address - -In addition to the above information, the `ghw.PCIInfo` struct has the -following method: - -* `ghw.PCIInfo.GetDevice(address string)` +> **NOTE**: Older versions (pre-`v0.9.0`) erroneously referred to the `Device` +> field as the `Slot` field. As noted by [@pearsonk](https://github.com/pearsonk) +> in [#220](https://github.com/jaypipes/ghw/issues/220), this was a misnomer. -The following code snippet shows how to call the `ghw.PCIInfo.ListDevices()` -method and output a simple list of PCI address and vendor/product information: +The following code snippet shows how to list the PCI devices on the host system +and output a simple list of PCI address and vendor/product information: ```go package main @@ -1015,6 +814,13 @@ host PCI devices: 0000:3f:06.3 Intel Corporation Xeon 5600 Series Integrated Memory Co... ``` +#### Finding a PCI device by PCI address + +In addition to the above information, the `ghw.PCIInfo` struct has the +following method: + +* `ghw.PCIInfo.GetDevice(address string)` + The following code snippet shows how to call the `ghw.PCIInfo.GetDevice()` method and use its returned `ghw.PCIDevice` struct pointer: @@ -1081,9 +887,8 @@ Programming Interface: VGA controller [00] ### GPU -Information about the host computer's graphics hardware is returned from the -`ghw.GPU()` function. This function returns a pointer to a `ghw.GPUInfo` -struct. +The `ghw.GPU()` function returns a `ghw.GPUInfo` struct that contains +information about the host computer's graphics hardware. The `ghw.GPUInfo` struct contains one field: @@ -1142,20 +947,21 @@ subsystem ### Chassis -The host's chassis information is accessible with the `ghw.Chassis()` function. This -function returns a pointer to a `ghw.ChassisInfo` struct. +The `ghw.Chassis()` function returns a `ghw.ChassisInfo` struct that contains +information about the host computer's hardware chassis. The `ghw.ChassisInfo` struct contains multiple fields: * `ghw.ChassisInfo.AssetTag` is a string with the chassis asset tag * `ghw.ChassisInfo.SerialNumber` is a string with the chassis serial number * `ghw.ChassisInfo.Type` is a string with the chassis type *code* -* `ghw.ChassisInfo.TypeDescription` is a string with a description of the chassis type +* `ghw.ChassisInfo.TypeDescription` is a string with a description of the + chassis type * `ghw.ChassisInfo.Vendor` is a string with the chassis vendor * `ghw.ChassisInfo.Version` is a string with the chassis version -**NOTE**: These fields are often missing for non-server hardware. Don't be -surprised to see empty string or "None" values. +> **NOTE**: These fields are often missing for non-server hardware. Don't be +> surprised to see empty string or "None" values. ```go package main @@ -1182,10 +988,10 @@ Example output from my personal workstation: chassis type=Desktop vendor=System76 version=thelio-r1 ``` -**NOTE**: Some of the values such as serial numbers are shown as unknown because -the Linux kernel by default disallows access to those fields if you're not running -as root. They will be populated if it runs as root or otherwise you may see warnings -like the following: +> **NOTE**: Some of the values such as serial numbers are shown as unknown +> because the Linux kernel by default disallows access to those fields if +> you're not running as root. They will be populated if it runs as root or +> otherwise you may see warnings like the following: ``` WARNING: Unable to read chassis_serial: open /sys/class/dmi/id/chassis_serial: permission denied @@ -1196,8 +1002,8 @@ feature to quiet things down. ### BIOS -The host's basis input/output system (BIOS) information is accessible with the `ghw.BIOS()` function. This -function returns a pointer to a `ghw.BIOSInfo` struct. +The `ghw.BIOS()` function returns a `ghw.BIOSInfo` struct that contains +information about the host computer's basis input/output system (BIOS). The `ghw.BIOSInfo` struct contains multiple fields: @@ -1232,8 +1038,8 @@ bios vendor=System76 version=F2 Z5 date=11/14/2018 ### Baseboard -The host's baseboard information is accessible with the `ghw.Baseboard()` function. This -function returns a pointer to a `ghw.BaseboardInfo` struct. +The `ghw.Baseboard()` function returns a `ghw.BaseboardInfo` struct that +contains information about the host computer's hardware baseboard. The `ghw.BaseboardInfo` struct contains multiple fields: @@ -1244,8 +1050,8 @@ The `ghw.BaseboardInfo` struct contains multiple fields: Product on Windows * `ghw.BaseboardInfo.Version` is a string with the baseboard version -**NOTE**: These fields are often missing for non-server hardware. Don't be -surprised to see empty string or "None" values. +> **NOTE**: These fields are often missing for non-server hardware. Don't be +> surprised to see empty string or "None" values. ```go package main @@ -1272,10 +1078,10 @@ Example output from my personal workstation: baseboard vendor=System76 version=thelio-r1 ``` -**NOTE**: Some of the values such as serial numbers are shown as unknown because -the Linux kernel by default disallows access to those fields if you're not running -as root. They will be populated if it runs as root or otherwise you may see warnings -like the following: +> **NOTE**: Some of the values such as serial numbers are shown as unknown +> because the Linux kernel by default disallows access to those fields if +> you're not running as root. They will be populated if it runs as root or +> otherwise you may see warnings like the following: ``` WARNING: Unable to read board_serial: open /sys/class/dmi/id/board_serial: permission denied @@ -1286,8 +1092,8 @@ feature to quiet things down. ### Product -The host's product information is accessible with the `ghw.Product()` function. This -function returns a pointer to a `ghw.ProductInfo` struct. +The `ghw.Product()` function returns a `ghw.ProductInfo` struct that +contains information about the host computer's hardware product line. The `ghw.ProductInfo` struct contains multiple fields: @@ -1295,12 +1101,13 @@ The `ghw.ProductInfo` struct contains multiple fields: * `ghw.ProductInfo.Name` is a string with the product name * `ghw.ProductInfo.SerialNumber` is a string with the product serial number * `ghw.ProductInfo.UUID` is a string with the product UUID -* `ghw.ProductInfo.SKU` is a string with the product stock unit identifier (SKU) +* `ghw.ProductInfo.SKU` is a string with the product stock unit identifier + (SKU) * `ghw.ProductInfo.Vendor` is a string with the product vendor * `ghw.ProductInfo.Version` is a string with the product version -**NOTE**: These fields are often missing for non-server hardware. Don't be -surprised to see empty string, "Default string" or "None" values. +> **NOTE**: These fields are often missing for non-server hardware. Don't be +> surprised to see empty string, "Default string" or "None" values. ```go package main @@ -1327,10 +1134,10 @@ Example output from my personal workstation: product family=Default string name=Thelio vendor=System76 sku=Default string version=thelio-r1 ``` -**NOTE**: Some of the values such as serial numbers are shown as unknown because -the Linux kernel by default disallows access to those fields if you're not running -as root. They will be populated if it runs as root or otherwise you may see warnings -like the following: +> **NOTE**: Some of the values such as serial numbers are shown as unknown +> because the Linux kernel by default disallows access to those fields if +> you're not running as root. They will be populated if it runs as root or +> otherwise you may see warnings like the following: ``` WARNING: Unable to read product_serial: open /sys/class/dmi/id/product_serial: permission denied @@ -1339,7 +1146,73 @@ WARNING: Unable to read product_serial: open /sys/class/dmi/id/product_serial: p You can ignore them or use the [Disabling warning messages](#disabling-warning-messages) feature to quiet things down. -## Serialization +## Advanced Usage + +### Disabling warning messages + +When `ghw` isn't able to retrieve some information, it may print certain +warning messages to `stderr`. To disable these warnings, simply set the +`GHW_DISABLE_WARNINGS` environs variable: + +``` +$ ghwc memory +WARNING: +Could not determine total physical bytes of memory. This may +be due to the host being a virtual machine or container with no +/var/log/syslog file, or the current user may not have necessary +privileges to read the syslog. We are falling back to setting the +total physical amount of memory to the total usable amount of memory +memory (24GB physical, 24GB usable) +``` + +``` +$ GHW_DISABLE_WARNINGS=1 ghwc memory +memory (24GB physical, 24GB usable) +``` + +You can disable warning programmatically using the `WithDisableWarnings` option: + +```go + +import ( + "github.com/jaypipes/ghw" +) + +mem, err := ghw.Memory(ghw.WithDisableWarnings()) +``` + +`WithDisableWarnings` is a alias for the `WithNullAlerter` option, which in turn +leverages the more general `Alerter` feature of ghw. + +You may supply a `Alerter` to ghw to redirect all the warnings there, like +logger objects (see for example golang's stdlib `log.Logger`). +`Alerter` is in fact the minimal logging interface `ghw needs. +To learn more, please check the `option.Alerter` interface and the `ghw.WithAlerter()` +function. + +### Overriding the root mountpoint `ghw` uses + +When `ghw` looks for information about the host system, it considers `/` as its +root mountpoint. So, for example, when looking up CPU information on a Linux +system, `ghw.CPU()` will use the path `/proc/cpuinfo`. + +If you are calling `ghw` from a system that has an alternate root mountpoint, +you can either set the `GHW_CHROOT` environment variable to that alternate +path, or call one of the functions like `ghw.CPU()` or `ghw.Memory()` with the +`ghw.WithChroot()` modifier. + +For example, if you are executing from within an application container that has +bind-mounted the root host filesystem to the mount point `/host`, you would set +`GHW_CHROOT` to `/host` so that `ghw` can find `/proc/cpuinfo` at +`/host/proc/cpuinfo`. + +Alternately, you can use the `ghw.WithChroot()` function like so: + +```go +cpu, err := ghw.CPU(ghw.WithChroot("/host")) +``` + +### Serialization to JSON or YAML All of the `ghw` `XXXInfo` structs -- e.g. `ghw.CPUInfo` -- have two methods for producing a serialized JSON or YAML string representation of the contained @@ -1381,36 +1254,153 @@ memory: total_usable_bytes: 25263415296 ``` -## Calling external programs +### Overriding a specific mountpoint (Linux only) -By default ghw may call external programs, for example `ethtool`, to learn about hardware capabilities. -In some rare circumstances it may be useful to opt out from this behaviour and rely only on the data -provided by pseudo-filesystems, like sysfs. -The most common use case is when we want to consume a snapshot from ghw. In these cases the information -provided by tools will be most likely inconsistent with the data from the snapshot - they will run on -a different host! -To prevent ghw from calling external tools, set the environs variable `GHW_DISABLE_TOOLS` to any value, -or, programmatically, check the `WithDisableTools` function. -The default behaviour of ghw is to call external tools when available. - -**WARNING**: -- on all platforms, disabling external tools make ghw return less data. - Unless noted otherwise, there is _no fallback flow_ if external tools are disabled. -- on darwin, disabling external tools disable block support entirely +When running inside containers, it can be cumbersome to only override the root +mountpoint. Inside containers, when granting access to the host file systems, +it is common to bind-mount them to a non-standard location, like `/sys` on +`/host-sys` or `/proc` to `/host-proc`. It is rarer to mount them to a common +subtree (e.g. `/sys` to `/host/sys` and `/proc` to `/host/proc`...) -## Developers +To better cover this use case, `ghw.WithPathOverrides()` can be used to supply +a mapping of directories to mountpoints, like this example shows: -[Contributions](CONTRIBUTING.md) to `ghw` are welcomed! Fork the repo on GitHub -and submit a pull request with your proposed changes. Or, feel free to log an -issue for a feature request or bug report. +```go +cpu, err := ghw.CPU(ghw.WithPathOverrides(ghw.PathOverrides{ + "/proc": "/host-proc", + "/sys": "/host-sys", +})) +``` + +**NOTE**: This feature works in addition and is composable with the +`ghw.WithChroot()` function and `GHW_CHROOT` environment variable. + +### Reading hardware information from a `ghw` snapshot (Linux only) + +The `ghw-snapshot` tool can create a snapshot of a host's hardware information. + +Please read [`SNAPSHOT.md`](SNAPSHOT.md) to learn about creating snapshots with +the `ghw-snapshot` tool. + +You can make `ghw` read hardware information from a snapshot created with +`ghw-snapshot` using environment variables or programmatically. -### Running tests +Use the `GHW_SNAPSHOT_PATH` environment variable to specify the filepath to a +snapshot that `ghw` will read to determine hardware information. All the needed +chroot changes will be automatically performed. By default, the snapshot is +unpacked into a temporary directory managed by `ghw`. This temporary directory +is automatically deleted when `ghw` is finished reading the snapshot. -You can run unit tests easily using the `make test` command, like so: +Three other environment variables are relevant if and only if `GHW_SNAPSHOT_PATH` +is not empty: +* `GHW_SNAPSHOT_ROOT` let users specify the directory on which the snapshot + should be unpacked. This moves the ownership of that directory from `ghw` to + users. For this reason, `ghw` will *not* automatically clean up the content + unpacked into `GHW_SNAPSHOT_ROOT`. +* `GHW_SNAPSHOT_EXCLUSIVE` tells `ghw` that the directory is meant only to + contain the given snapshot, thus `ghw` will *not* attempt to unpack it unless + the directory is empty. You can use both `GHW_SNAPSHOT_ROOT` and + `GHW_SNAPSHOT_EXCLUSIVE` to make sure `ghw` unpacks the snapshot only once + regardless of how many `ghw` packages (e.g. cpu, memory) access it. Set the + value of this environment variable to any non-empty string. +* `GHW_SNAPSHOT_PRESERVE` tells `ghw` not to clean up the unpacked snapshot. + Set the value of this environment variable to any non-empty string. + +```go +cpu, err := ghw.CPU(ghw.WithSnapshot(ghw.SnapshotOptions{ + Path: "/path/to/linux-amd64-d4771ed3300339bc75f856be09fc6430.tar.gz", +})) + + +myRoot := "/my/safe/directory" +cpu, err := ghw.CPU(ghw.WithSnapshot(ghw.SnapshotOptions{ + Path: "/path/to/linux-amd64-d4771ed3300339bc75f856be09fc6430.tar.gz", + Root: &myRoot, +})) + +myOtherRoot := "/my/other/safe/directory" +cpu, err := ghw.CPU(ghw.WithSnapshot(ghw.SnapshotOptions{ + Path: "/path/to/linux-amd64-d4771ed3300339bc75f856be09fc6430.tar.gz", + Root: &myOtherRoot, + Exclusive: true, +})) ``` -[jaypipes@uberbox ghw]$ make test -go test github.com/jaypipes/ghw github.com/jaypipes/ghw/cmd/ghwc -ok github.com/jaypipes/ghw 0.084s -? github.com/jaypipes/ghw/cmd/ghwc [no test files] + +### Creating snapshots + +You can create `ghw` snapshots using the `ghw-snapshot` tool or +programmatically using the `pkg/snapshot` package. + +Below is an example of creating a `ghw` snapshot using the `pkg/snapshot` +package. + +```go + +import ( + "fmt" + "os" + + "github.com/jaypipes/ghw/pkg/snapshot" +) + +// ... + +scratchDir, err := os.MkdirTemp("", "ghw-snapshot-*") +if err != nil { + fmt.Printf("Error creating clone directory: %v", err) +} +defer os.RemoveAll(scratchDir) + +// this step clones all the files and directories ghw cares about +if err := snapshot.CloneTreeInto(scratchDir); err != nil { + fmt.Printf("error cloning into %q: %v", scratchDir, err) +} + +// optionally, you may add extra content into your snapshot. +// ghw will ignore the extra content. +// Glob patterns like `filepath.Glob` are supported. +fileSpecs := []string{ + "/proc/cmdline", +} + +// options allows the client code to optionally deference symlinks, or copy +// them into the cloned tree as symlinks +var opts *snapshot.CopyFileOptions +if err := snapshot.CopyFilesInto(fileSpecs, scratchDir, opts); err != nil { + fmt.Printf("error cloning extra files into %q: %v", scratchDir, err) +} + +// automates the creation of the gzipped tarball out of the given tree. +if err := snapshot.PackFrom("my-snapshot.tgz", scratchDir); err != nil { + fmt.Printf("error packing %q into %q: %v", scratchDir, *output, err) +} ``` + +## Calling external programs + +By default `ghw` may call external programs, for example `ethtool`, to learn +about hardware capabilities. In some rare circumstances it may be useful to +opt out from this behaviour and rely only on the data provided by +pseudo-filesystems, like sysfs. + +The most common use case is when we want to read a snapshot from `ghw`. In +these cases the information provided by tools will be inconsistent with the +data from the snapshot - since they will be run on a different host than the +host the snapshot was created for. + +To prevent `ghw` from calling external tools, set the `GHW_DISABLE_TOOLS` +environment variable to any value, or, programmatically, use the +`ghw.WithDisableTools()` function. The default behaviour of ghw is to call +external tools when available. + +> **WARNING**: on all platforms, disabling external tools make ghw return less +> data. Unless noted otherwise, there is _no fallback flow_ if external tools +> are disabled. On MacOSX/Darwin, disabling external tools disables block +> support entirely + +## Developers + +[Contributions](CONTRIBUTING.md) to `ghw` are welcomed! Fork the repo on GitHub +and submit a pull request with your proposed changes. Or, feel free to log an +issue for a feature request or bug report. diff --git a/vendor/github.com/jaypipes/ghw/SECURITY.md b/vendor/github.com/jaypipes/ghw/SECURITY.md new file mode 100644 index 0000000000..660f2e632f --- /dev/null +++ b/vendor/github.com/jaypipes/ghw/SECURITY.md @@ -0,0 +1,23 @@ +# Security Policy + +We take security vulnerabilities seriously (and so should you!) + +Our policy on reported vulnerabilities (see below on how to report) is that we will +respond to the reporter of a vulnerability within two (2) business days of receiving +the report and notify the reporter whether and when a remediation will be committed. + +When a remediation for a security vulnerability is committed, we will cut a tagged +release of `ghw` and include in the release notes for that tagged release a description +of the vulnerability and a discussion of how it was remediated, along with a note +urging users to update to that fixed version. + +## Reporting a Vulnerability + +While `ghw` does have automated Github Dependabot alerts about security vulnerabilities +in `ghw`'s dependencies, there is always a chance that a vulnerability in a dependency +goes undetected by Dependabot. If you are aware of a vulnerability either in `ghw` or +one of its dependencies, please do not hesitate to reach out to `ghw` maintainers via +email or Slack. **Do not discuss vulnerabilities in a public forum**. + +`ghw`'s primary maintainer is Jay Pipes, who can be found on the Kubernetes Slack +community as `@jaypipes` and reached via email at jaypipes at gmail dot com. diff --git a/vendor/github.com/jaypipes/ghw/alias.go b/vendor/github.com/jaypipes/ghw/alias.go index 2e679a9678..83157d006f 100644 --- a/vendor/github.com/jaypipes/ghw/alias.go +++ b/vendor/github.com/jaypipes/ghw/alias.go @@ -47,13 +47,20 @@ var ( type MemoryArea = memory.Area type MemoryInfo = memory.Info +type MemoryCache = memory.Cache type MemoryCacheType = memory.CacheType type MemoryModule = memory.Module const ( - MEMORY_CACHE_TYPE_UNIFIED = memory.CACHE_TYPE_UNIFIED + MemoryCacheTypeUnified = memory.CacheTypeUnified + // DEPRECATED: Please use MemoryCacheTypeUnified + MEMORY_CACHE_TYPE_UNIFIED = memory.CACHE_TYPE_UNIFIED + MemoryCacheTypeInstruction = memory.CacheTypeInstruction + // DEPRECATED: Please use MemoryCacheTypeInstruction MEMORY_CACHE_TYPE_INSTRUCTION = memory.CACHE_TYPE_INSTRUCTION - MEMORY_CACHE_TYPE_DATA = memory.CACHE_TYPE_DATA + MemoryCacheTypeData = memory.CacheTypeData + // DEPRECATED: Please use MemoryCacheTypeData + MEMORY_CACHE_TYPE_DATA = memory.CACHE_TYPE_DATA ) var ( @@ -71,22 +78,44 @@ var ( type DriveType = block.DriveType const ( + DriveTypeUnknown = block.DriveTypeUnknown + // DEPRECATED: Please use DriveTypeUnknown DRIVE_TYPE_UNKNOWN = block.DRIVE_TYPE_UNKNOWN - DRIVE_TYPE_HDD = block.DRIVE_TYPE_HDD - DRIVE_TYPE_FDD = block.DRIVE_TYPE_FDD - DRIVE_TYPE_ODD = block.DRIVE_TYPE_ODD - DRIVE_TYPE_SSD = block.DRIVE_TYPE_SSD + DriveTypeHDD = block.DriveTypeHDD + // DEPRECATED: Please use DriveTypeHDD + DRIVE_TYPE_HDD = block.DRIVE_TYPE_HDD + DriveTypeFDD = block.DriveTypeFDD + // DEPRECATED: Please use DriveTypeFDD + DRIVE_TYPE_FDD = block.DRIVE_TYPE_FDD + DriveTypeODD = block.DriveTypeODD + // DEPRECATED: Please use DriveTypeODD + DRIVE_TYPE_ODD = block.DRIVE_TYPE_ODD + DriveTypeSSD = block.DriveTypeSSD + // DEPRECATED: Please use DriveTypeSSD + DRIVE_TYPE_SSD = block.DRIVE_TYPE_SSD ) type StorageController = block.StorageController const ( + StorageControllerUnknown = block.StorageControllerUnknown + // DEPRECATED: Please use StorageControllerUnknown STORAGE_CONTROLLER_UNKNOWN = block.STORAGE_CONTROLLER_UNKNOWN - STORAGE_CONTROLLER_IDE = block.STORAGE_CONTROLLER_IDE - STORAGE_CONTROLLER_SCSI = block.STORAGE_CONTROLLER_SCSI - STORAGE_CONTROLLER_NVME = block.STORAGE_CONTROLLER_NVME - STORAGE_CONTROLLER_VIRTIO = block.STORAGE_CONTROLLER_VIRTIO - STORAGE_CONTROLLER_MMC = block.STORAGE_CONTROLLER_MMC + StorageControllerIDE = block.StorageControllerIDE + // DEPRECATED: Please use StorageControllerIDE + STORAGE_CONTROLLER_IDE = block.STORAGE_CONTROLLER_IDE + StorageControllerSCSI = block.StorageControllerSCSI + // DEPRECATED: Please use StorageControllerSCSI + STORAGE_CONTROLLER_SCSI = block.STORAGE_CONTROLLER_SCSI + StorageControllerNVMe = block.StorageControllerNVMe + // DEPRECATED: Please use StorageControllerNVMe + STORAGE_CONTROLLER_NVME = block.STORAGE_CONTROLLER_NVME + StorageControllerVirtIO = block.StorageControllerVirtIO + // DEPRECATED: Please use StorageControllerVirtIO + STORAGE_CONTROLLER_VIRTIO = block.STORAGE_CONTROLLER_VIRTIO + StorageControllerMMC = block.StorageControllerMMC + // DEPRECATED: Please use StorageControllerMMC + STORAGE_CONTROLLER_MMC = block.STORAGE_CONTROLLER_MMC ) type NetworkInfo = net.Info diff --git a/vendor/github.com/jaypipes/ghw/doc.go b/vendor/github.com/jaypipes/ghw/doc.go index 6722cda7d2..826ed7b3a0 100644 --- a/vendor/github.com/jaypipes/ghw/doc.go +++ b/vendor/github.com/jaypipes/ghw/doc.go @@ -5,310 +5,10 @@ // /* -package ghw can determine various hardware-related -information about the host computer: +package ghw discovers hardware-related information about the host computer, +including CPU, memory, block storage, NUMA topology, network devices, PCI, GPU, +and baseboard/BIOS/chassis/product information. -* Memory -* CPU -* Block storage -* Topology -* Network -* PCI -* GPU - -# Memory - -Information about the host computer's memory can be retrieved using the -Memory function which returns a pointer to a MemoryInfo struct. - - package main - - import ( - "fmt" - - "github.com/jaypipes/ghw" - ) - - func main() { - memory, err := ghw.Memory() - if err != nil { - fmt.Printf("Error getting memory info: %v", err) - } - - fmt.Println(memory.String()) - } - -# CPU - -The CPU function returns a CPUInfo struct that contains information about -the CPUs on the host system. - - package main - - import ( - "fmt" - "math" - "strings" - - "github.com/jaypipes/ghw" - ) - - func main() { - cpu, err := ghw.CPU() - if err != nil { - fmt.Printf("Error getting CPU info: %v", err) - } - - fmt.Printf("%v\n", cpu) - - for _, proc := range cpu.Processors { - fmt.Printf(" %v\n", proc) - for _, core := range proc.Cores { - fmt.Printf(" %v\n", core) - } - if len(proc.Capabilities) > 0 { - // pretty-print the (large) block of capability strings into rows - // of 6 capability strings - rows := int(math.Ceil(float64(len(proc.Capabilities)) / float64(6))) - for row := 1; row < rows; row = row + 1 { - rowStart := (row * 6) - 1 - rowEnd := int(math.Min(float64(rowStart+6), float64(len(proc.Capabilities)))) - rowElems := proc.Capabilities[rowStart:rowEnd] - capStr := strings.Join(rowElems, " ") - if row == 1 { - fmt.Printf(" capabilities: [%s\n", capStr) - } else if rowEnd < len(proc.Capabilities) { - fmt.Printf(" %s\n", capStr) - } else { - fmt.Printf(" %s]\n", capStr) - } - } - } - } - } - -# Block storage - -Information about the host computer's local block storage is returned from -the Block function. This function returns a pointer to a BlockInfo struct. - - package main - - import ( - "fmt" - - "github.com/jaypipes/ghw" - ) - - func main() { - block, err := ghw.Block() - if err != nil { - fmt.Printf("Error getting block storage info: %v", err) - } - - fmt.Printf("%v\n", block) - - for _, disk := range block.Disks { - fmt.Printf(" %v\n", disk) - for _, part := range disk.Partitions { - fmt.Printf(" %v\n", part) - } - } - } - -# Topology - -Information about the host computer's architecture (NUMA vs. SMP), the -host's node layout and processor caches can be retrieved from the Topology -function. This function returns a pointer to a TopologyInfo struct. - - package main - - import ( - "fmt" - - "github.com/jaypipes/ghw" - ) - - func main() { - topology, err := ghw.Topology() - if err != nil { - fmt.Printf("Error getting topology info: %v", err) - } - - fmt.Printf("%v\n", topology) - - for _, node := range topology.Nodes { - fmt.Printf(" %v\n", node) - for _, cache := range node.Caches { - fmt.Printf(" %v\n", cache) - } - } - } - -# Network - -Information about the host computer's networking hardware is returned from -the Network function. This function returns a pointer to a NetworkInfo -struct. - - package main - - import ( - "fmt" - - "github.com/jaypipes/ghw" - ) - - func main() { - net, err := ghw.Network() - if err != nil { - fmt.Printf("Error getting network info: %v", err) - } - - fmt.Printf("%v\n", net) - - for _, nic := range net.NICs { - fmt.Printf(" %v\n", nic) - - enabledCaps := make([]int, 0) - for x, cap := range nic.Capabilities { - if cap.IsEnabled { - enabledCaps = append(enabledCaps, x) - } - } - if len(enabledCaps) > 0 { - fmt.Printf(" enabled capabilities:\n") - for _, x := range enabledCaps { - fmt.Printf(" - %s\n", nic.Capabilities[x].Name) - } - } - } - } - -# PCI - -ghw contains a PCI database inspection and querying facility that allows -developers to not only gather information about devices on a local PCI bus -but also query for information about hardware device classes, vendor and -product information. - -**NOTE**: Parsing of the PCI-IDS file database is provided by the separate -http://github.com/jaypipes/pcidb library. You can read that library's -README for more information about the various structs that are exposed on -the PCIInfo struct. - -PCIInfo.ListDevices is used to iterate over a host's PCI devices: - - package main - - import ( - "fmt" - - "github.com/jaypipes/ghw" - ) - - func main() { - pci, err := ghw.PCI() - if err != nil { - fmt.Printf("Error getting PCI info: %v", err) - } - fmt.Printf("host PCI devices:\n") - fmt.Println("====================================================") - devices := pci.ListDevices() - if len(devices) == 0 { - fmt.Printf("error: could not retrieve PCI devices\n") - return - } - - for _, device := range devices { - vendor := device.Vendor - vendorName := vendor.Name - if len(vendor.Name) > 20 { - vendorName = string([]byte(vendorName)[0:17]) + "..." - } - product := device.Product - productName := product.Name - if len(product.Name) > 40 { - productName = string([]byte(productName)[0:37]) + "..." - } - fmt.Printf("%-12s\t%-20s\t%-40s\n", device.Address, vendorName, productName) - } - } - -The following code snippet shows how to call the PCIInfo.GetDevice method -and use its returned PCIDevice struct pointer: - - package main - - import ( - "fmt" - "os" - - "github.com/jaypipes/ghw" - ) - - func main() { - pci, err := ghw.PCI() - if err != nil { - fmt.Printf("Error getting PCI info: %v", err) - } - - addr := "0000:00:00.0" - if len(os.Args) == 2 { - addr = os.Args[1] - } - fmt.Printf("PCI device information for %s\n", addr) - fmt.Println("====================================================") - deviceInfo := pci.GetDevice(addr) - if deviceInfo == nil { - fmt.Printf("could not retrieve PCI device information for %s\n", addr) - return - } - - vendor := deviceInfo.Vendor - fmt.Printf("Vendor: %s [%s]\n", vendor.Name, vendor.ID) - product := deviceInfo.Product - fmt.Printf("Product: %s [%s]\n", product.Name, product.ID) - subsystem := deviceInfo.Subsystem - subvendor := pci.Vendors[subsystem.VendorID] - subvendorName := "UNKNOWN" - if subvendor != nil { - subvendorName = subvendor.Name - } - fmt.Printf("Subsystem: %s [%s] (Subvendor: %s)\n", subsystem.Name, subsystem.ID, subvendorName) - class := deviceInfo.Class - fmt.Printf("Class: %s [%s]\n", class.Name, class.ID) - subclass := deviceInfo.Subclass - fmt.Printf("Subclass: %s [%s]\n", subclass.Name, subclass.ID) - progIface := deviceInfo.ProgrammingInterface - fmt.Printf("Programming Interface: %s [%s]\n", progIface.Name, progIface.ID) - } - -# GPU - -Information about the host computer's graphics hardware is returned from -the GPU function. This function returns a pointer to a GPUInfo struct. - - package main - - import ( - "fmt" - - "github.com/jaypipes/ghw" - ) - - func main() { - gpu, err := ghw.GPU() - if err != nil { - fmt.Printf("Error getting GPU info: %v", err) - } - - fmt.Printf("%v\n", gpu) - - for _, card := range gpu.GraphicsCards { - fmt.Printf(" %v\n", card) - } - } +Please see the extensive README.md document for examples of usage. */ package ghw diff --git a/vendor/github.com/jaypipes/ghw/pkg/block/block.go b/vendor/github.com/jaypipes/ghw/pkg/block/block.go index a495f69c59..5e75eea6f0 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/block/block.go +++ b/vendor/github.com/jaypipes/ghw/pkg/block/block.go @@ -24,22 +24,43 @@ import ( type DriveType int const ( - DRIVE_TYPE_UNKNOWN DriveType = iota - DRIVE_TYPE_HDD // Hard disk drive - DRIVE_TYPE_FDD // Floppy disk drive - DRIVE_TYPE_ODD // Optical disk drive - DRIVE_TYPE_SSD // Solid-state drive - DRIVE_TYPE_VIRTUAL // virtual drive i.e. loop devices + // DriveTypeUnknown means we could not determine the drive type of the disk + DriveTypeUnknown DriveType = iota + // DriveTypeHDD indicates a hard disk drive + DriveTypeHDD + // DriveTypeFDD indicates a floppy disk drive + DriveTypeFDD + // DriveTypeODD indicates an optical disk drive + DriveTypeODD + // DriveTypeSSD indicates a solid-state drive + DriveTypeSSD + // DriveTypeVirtual indicates a virtual drive i.e. loop devices + DriveTypeVirtual +) + +const ( + // DEPRECATED: Please use DriveTypeUnknown + DRIVE_TYPE_UNKNOWN = DriveTypeUnknown + // DEPRECATED: Please use DriveTypeHDD + DRIVE_TYPE_HDD = DriveTypeHDD + // DEPRECATED: Please use DriveTypeFDD + DRIVE_TYPE_FDD = DriveTypeFDD + // DEPRECATED: Please use DriveTypeODD + DRIVE_TYPE_ODD = DriveTypeODD + // DEPRECATED: Please use DriveTypeSSD + DRIVE_TYPE_SSD = DriveTypeSSD + // DEPRECATED: Please use DriveTypeVirtual + DRIVE_TYPE_VIRTUAL = DriveTypeVirtual ) var ( driveTypeString = map[DriveType]string{ - DRIVE_TYPE_UNKNOWN: "Unknown", - DRIVE_TYPE_HDD: "HDD", - DRIVE_TYPE_FDD: "FDD", - DRIVE_TYPE_ODD: "ODD", - DRIVE_TYPE_SSD: "SSD", - DRIVE_TYPE_VIRTUAL: "virtual", + DriveTypeUnknown: "Unknown", + DriveTypeHDD: "HDD", + DriveTypeFDD: "FDD", + DriveTypeODD: "ODD", + DriveTypeSSD: "SSD", + DriveTypeVirtual: "virtual", } // NOTE(fromani): the keys are all lowercase and do not match @@ -48,12 +69,12 @@ var ( // DriveType::MarshalJSON. // We use this table only in UnmarshalJSON, so it should be OK. stringDriveType = map[string]DriveType{ - "unknown": DRIVE_TYPE_UNKNOWN, - "hdd": DRIVE_TYPE_HDD, - "fdd": DRIVE_TYPE_FDD, - "odd": DRIVE_TYPE_ODD, - "ssd": DRIVE_TYPE_SSD, - "virtual": DRIVE_TYPE_VIRTUAL, + "unknown": DriveTypeUnknown, + "hdd": DriveTypeHDD, + "fdd": DriveTypeFDD, + "odd": DriveTypeODD, + "ssd": DriveTypeSSD, + "virtual": DriveTypeVirtual, } ) @@ -90,24 +111,54 @@ func (dt *DriveType) UnmarshalJSON(b []byte) error { type StorageController int const ( - STORAGE_CONTROLLER_UNKNOWN StorageController = iota - STORAGE_CONTROLLER_IDE // Integrated Drive Electronics - STORAGE_CONTROLLER_SCSI // Small computer system interface - STORAGE_CONTROLLER_NVME // Non-volatile Memory Express - STORAGE_CONTROLLER_VIRTIO // Virtualized storage controller/driver - STORAGE_CONTROLLER_MMC // Multi-media controller (used for mobile phone storage devices) - STORAGE_CONTROLLER_LOOP // loop device + // StorageControllerUnknown indicates we could not determine the storage + // controller for the disk + StorageControllerUnknown StorageController = iota + // StorageControllerIDE indicates a Integrated Drive Electronics (IDE) + // controller + StorageControllerIDE + // StorageControllerSCSI indicates a Small computer system interface + // (SCSI) controller + StorageControllerSCSI + // StorageControllerNVMe indicates a Non-volatile Memory Express (NVMe) + // controller + StorageControllerNVMe + // StorageControllerVirtIO indicates a virtualized storage + // controller/driver + StorageControllerVirtIO + // StorageControllerMMC indicates a Multi-media controller (used for mobile + // phone storage devices) + StorageControllerMMC + // StorageControllerLoop indicates a loopback storage controller + StorageControllerLoop +) + +const ( + // DEPRECATED: Please use StorageControllerUnknown + STORAGE_CONTROLLER_UNKNOWN = StorageControllerUnknown + // DEPRECATED: Please use StorageControllerIDE + STORAGE_CONTROLLER_IDE = StorageControllerIDE + // DEPRECATED: Please use StorageControllerSCSI + STORAGE_CONTROLLER_SCSI = StorageControllerSCSI + // DEPRECATED: Please use StorageControllerNVMe + STORAGE_CONTROLLER_NVME = StorageControllerNVMe + // DEPRECATED: Please use StorageControllerVirtIO + STORAGE_CONTROLLER_VIRTIO = StorageControllerVirtIO + // DEPRECATED: Please use StorageControllerMMC + STORAGE_CONTROLLER_MMC = StorageControllerMMC + // DEPRECATED: Please use StorageControllerLoop + STORAGE_CONTROLLER_LOOP = StorageControllerLoop ) var ( storageControllerString = map[StorageController]string{ - STORAGE_CONTROLLER_UNKNOWN: "Unknown", - STORAGE_CONTROLLER_IDE: "IDE", - STORAGE_CONTROLLER_SCSI: "SCSI", - STORAGE_CONTROLLER_NVME: "NVMe", - STORAGE_CONTROLLER_VIRTIO: "virtio", - STORAGE_CONTROLLER_MMC: "MMC", - STORAGE_CONTROLLER_LOOP: "loop", + StorageControllerUnknown: "Unknown", + StorageControllerIDE: "IDE", + StorageControllerSCSI: "SCSI", + StorageControllerNVMe: "NVMe", + StorageControllerVirtIO: "virtio", + StorageControllerMMC: "MMC", + StorageControllerLoop: "loop", } // NOTE(fromani): the keys are all lowercase and do not match @@ -116,13 +167,13 @@ var ( // StorageController::MarshalJSON. // We use this table only in UnmarshalJSON, so it should be OK. stringStorageController = map[string]StorageController{ - "unknown": STORAGE_CONTROLLER_UNKNOWN, - "ide": STORAGE_CONTROLLER_IDE, - "scsi": STORAGE_CONTROLLER_SCSI, - "nvme": STORAGE_CONTROLLER_NVME, - "virtio": STORAGE_CONTROLLER_VIRTIO, - "mmc": STORAGE_CONTROLLER_MMC, - "loop": STORAGE_CONTROLLER_LOOP, + "unknown": StorageControllerUnknown, + "ide": StorageControllerIDE, + "scsi": StorageControllerSCSI, + "nvme": StorageControllerNVMe, + "virtio": StorageControllerVirtIO, + "mmc": StorageControllerMMC, + "loop": StorageControllerLoop, } ) @@ -154,45 +205,88 @@ func (sc StorageController) MarshalJSON() ([]byte, error) { // Disk describes a single disk drive on the host system. Disk drives provide // raw block storage resources. type Disk struct { - Name string `json:"name"` - SizeBytes uint64 `json:"size_bytes"` - PhysicalBlockSizeBytes uint64 `json:"physical_block_size_bytes"` - DriveType DriveType `json:"drive_type"` - IsRemovable bool `json:"removable"` - StorageController StorageController `json:"storage_controller"` - BusPath string `json:"bus_path"` + // Name contains a short name for the disk, e.g. `sda` + Name string `json:"name"` + // SizeBytes contains the total amount of storage, in bytes, for this disk + SizeBytes uint64 `json:"size_bytes"` + // PhysicalBlockSizeBytes is the size, in bytes, of the physical blocks in + // this disk. This is typically the minimum amount of data that can be + // written to a disk in a single write operation. + PhysicalBlockSizeBytes uint64 `json:"physical_block_size_bytes"` + // DriveType is the category of disk drive for this disk. + DriveType DriveType `json:"drive_type"` + // IsRemovable indicates if the disk drive is removable. + IsRemovable bool `json:"removable"` + // StorageController is the category of storage controller used by the + // disk. + StorageController StorageController `json:"storage_controller"` + // BusPath is the filepath to the bus for this disk. + BusPath string `json:"bus_path"` + // NUMANodeID contains the numeric index (0-based) of the NUMA Node this + // disk is affined to, or -1 if the host system is non-NUMA. // TODO(jaypipes): Convert this to a TopologyNode struct pointer and then // add to serialized output as "numa_node,omitempty" - NUMANodeID int `json:"-"` - Vendor string `json:"vendor"` - Model string `json:"model"` - SerialNumber string `json:"serial_number"` - WWN string `json:"wwn"` - Partitions []*Partition `json:"partitions"` + NUMANodeID int `json:"-"` + // Vendor is the manufacturer of the disk. + Vendor string `json:"vendor"` + // Model is the model number of the disk. + Model string `json:"model"` + // SerialNumber is the serial number of the disk. + SerialNumber string `json:"serial_number"` + // WWN is the World-wide Name of the disk. + // See: https://en.wikipedia.org/wiki/World_Wide_Name + WWN string `json:"wwn"` + // WWNNoExtension is the World-wide Name of the disk with any vendor + // extensions excluded. + // See: https://en.wikipedia.org/wiki/World_Wide_Name + WWNNoExtension string `json:"wwnNoExtension"` + // Partitions contains an array of pointers to `Partition` structs, one for + // each partition on the disk. + Partitions []*Partition `json:"partitions"` // TODO(jaypipes): Add PCI field for accessing PCI device information // PCI *PCIDevice `json:"pci"` } // Partition describes a logical division of a Disk. type Partition struct { - Disk *Disk `json:"-"` - Name string `json:"name"` - Label string `json:"label"` - MountPoint string `json:"mount_point"` - SizeBytes uint64 `json:"size_bytes"` - Type string `json:"type"` - IsReadOnly bool `json:"read_only"` - UUID string `json:"uuid"` // This would be volume UUID on macOS, PartUUID on linux, empty on Windows + // Disk is a pointer to the `Disk` struct that houses this partition. + Disk *Disk `json:"-"` + // Name is the system name given to the partition, e.g. "sda1". + Name string `json:"name"` + // Label is the human-readable label given to the partition. On Linux, this + // is derived from the `ID_PART_ENTRY_NAME` udev entry. + Label string `json:"label"` + // MountPoint is the path where this partition is mounted. + MountPoint string `json:"mount_point"` + // SizeBytes contains the total amount of storage, in bytes, this partition + // can consume. + SizeBytes uint64 `json:"size_bytes"` + // Type contains the type of the partition. + Type string `json:"type"` + // IsReadOnly indicates if the partition is marked read-only. + IsReadOnly bool `json:"read_only"` + // UUID is the universally-unique identifier (UUID) for the partition. + // This will be volume UUID on Darwin, PartUUID on linux, empty on Windows. + UUID string `json:"uuid"` + // FilesystemLabel is the label of the filesystem contained on the + // partition. On Linux, this is derived from the `ID_FS_NAME` udev entry. FilesystemLabel string `json:"filesystem_label"` } // Info describes all disk drives and partitions in the host system. type Info struct { ctx *context.Context - // TODO(jaypipes): Deprecate this field and replace with TotalSizeBytes - TotalPhysicalBytes uint64 `json:"total_size_bytes"` - Disks []*Disk `json:"disks"` - Partitions []*Partition `json:"-"` + // TotalSizeBytes contains the total amount of storage, in bytes, on the + // host system. + TotalSizeBytes uint64 `json:"total_size_bytes"` + // DEPRECATED: Please use TotalSizeBytes + TotalPhysicalBytes uint64 `json:"-"` + // Disks contains an array of pointers to `Disk` structs, one for each disk + // drive on the host system. + Disks []*Disk `json:"disks"` + // Partitions contains an array of pointers to `Partition` structs, one for + // each partition on any disk drive on the host system. + Partitions []*Partition `json:"-"` } // New returns a pointer to an Info struct that describes the block storage @@ -206,6 +300,8 @@ func New(opts ...*option.Option) (*Info, error) { return info, nil } +// String returns a short string indicating important information about the +// block storage on the host system. func (i *Info) String() string { tpbs := util.UNKNOWN if i.TotalPhysicalBytes > 0 { @@ -222,6 +318,8 @@ func (i *Info) String() string { len(i.Disks), dplural, tpbs) } +// String returns a short string indicating important information about the +// disk. func (d *Disk) String() string { sizeStr := util.UNKNOWN if d.SizeBytes > 0 { @@ -272,6 +370,8 @@ func (d *Disk) String() string { ) } +// String returns a short string indicating important information about the +// partition. func (p *Partition) String() string { typeStr := "" if p.Type != "" { diff --git a/vendor/github.com/jaypipes/ghw/pkg/block/block_darwin.go b/vendor/github.com/jaypipes/ghw/pkg/block/block_darwin.go index 5115d404ba..c6b6c26647 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/block/block_darwin.go +++ b/vendor/github.com/jaypipes/ghw/pkg/block/block_darwin.go @@ -185,9 +185,9 @@ func makePartition(disk, s diskOrPartitionPlistNode, isAPFS bool) (*Partition, e // driveTypeFromPlist looks at the supplied property list struct and attempts to // determine the disk type func driveTypeFromPlist(infoPlist *diskUtilInfoPlist) DriveType { - dt := DRIVE_TYPE_HDD + dt := DriveTypeHDD if infoPlist.SolidState { - dt = DRIVE_TYPE_SSD + dt = DriveTypeSSD } // TODO(jaypipes): Figure out how to determine floppy and/or CD/optical // drive type on Mac @@ -197,9 +197,9 @@ func driveTypeFromPlist(infoPlist *diskUtilInfoPlist) DriveType { // storageControllerFromPlist looks at the supplied property list struct and // attempts to determine the storage controller in use for the device func storageControllerFromPlist(infoPlist *diskUtilInfoPlist) StorageController { - sc := STORAGE_CONTROLLER_SCSI + sc := StorageControllerSCSI if strings.HasSuffix(infoPlist.DeviceTreePath, "IONVMeController") { - sc = STORAGE_CONTROLLER_NVME + sc = StorageControllerNVMe } // TODO(jaypipes): I don't know if Mac even supports IDE controllers and // the "virtio" controller is libvirt-specific @@ -217,7 +217,7 @@ func (info *Info) load() error { return err } - info.TotalPhysicalBytes = 0 + var tsb uint64 info.Disks = make([]*Disk, 0, len(listPlist.AllDisksAndPartitions)) info.Partitions = []*Partition{} @@ -258,6 +258,7 @@ func (info *Info) load() error { Model: ioregPlist.ModelNumber, SerialNumber: ioregPlist.SerialNumber, WWN: "", + WWNNoExtension: "", Partitions: make([]*Partition, 0, len(disk.Partitions)+len(disk.APFSVolumes)), } @@ -278,10 +279,12 @@ func (info *Info) load() error { diskReport.Partitions = append(diskReport.Partitions, part) } - info.TotalPhysicalBytes += uint64(disk.Size) + tsb += uint64(disk.Size) info.Disks = append(info.Disks, diskReport) info.Partitions = append(info.Partitions, diskReport.Partitions...) } + info.TotalSizeBytes = tsb + info.TotalPhysicalBytes = tsb return nil } diff --git a/vendor/github.com/jaypipes/ghw/pkg/block/block_linux.go b/vendor/github.com/jaypipes/ghw/pkg/block/block_linux.go index ce1641321d..376b5ff591 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/block/block_linux.go +++ b/vendor/github.com/jaypipes/ghw/pkg/block/block_linux.go @@ -8,7 +8,6 @@ package block import ( "bufio" "io" - "io/ioutil" "os" "path/filepath" "strconv" @@ -26,11 +25,12 @@ const ( func (i *Info) load() error { paths := linuxpath.New(i.ctx) i.Disks = disks(i.ctx, paths) - var tpb uint64 + var tsb uint64 for _, d := range i.Disks { - tpb += d.SizeBytes + tsb += d.SizeBytes } - i.TotalPhysicalBytes = tpb + i.TotalSizeBytes = tsb + i.TotalPhysicalBytes = tsb return nil } @@ -38,7 +38,7 @@ func diskPhysicalBlockSizeBytes(paths *linuxpath.Paths, disk string) uint64 { // We can find the sector size in Linux by looking at the // /sys/block/$DEVICE/queue/physical_block_size file in sysfs path := filepath.Join(paths.SysBlock, disk, "queue", "physical_block_size") - contents, err := ioutil.ReadFile(path) + contents, err := os.ReadFile(path) if err != nil { return 0 } @@ -53,7 +53,7 @@ func diskSizeBytes(paths *linuxpath.Paths, disk string) uint64 { // We can find the number of 512-byte sectors by examining the contents of // /sys/block/$DEVICE/size and calculate the physical bytes accordingly. path := filepath.Join(paths.SysBlock, disk, "size") - contents, err := ioutil.ReadFile(path) + contents, err := os.ReadFile(path) if err != nil { return 0 } @@ -70,7 +70,7 @@ func diskNUMANodeID(paths *linuxpath.Paths, disk string) int { return -1 } for partial := link; strings.HasPrefix(partial, "../devices/"); partial = filepath.Base(partial) { - if nodeContents, err := ioutil.ReadFile(filepath.Join(paths.SysBlock, partial, "numa_node")); err != nil { + if nodeContents, err := os.ReadFile(filepath.Join(paths.SysBlock, partial, "numa_node")); err != nil { if nodeInt, err := strconv.Atoi(string(nodeContents)); err != nil { return nodeInt } @@ -83,7 +83,7 @@ func diskVendor(paths *linuxpath.Paths, disk string) string { // In Linux, the vendor for a disk device is found in the // /sys/block/$DEVICE/device/vendor file in sysfs path := filepath.Join(paths.SysBlock, disk, "device", "vendor") - contents, err := ioutil.ReadFile(path) + contents, err := os.ReadFile(path) if err != nil { return util.UNKNOWN } @@ -93,7 +93,7 @@ func diskVendor(paths *linuxpath.Paths, disk string) string { // udevInfoDisk gets the udev info for a disk func udevInfoDisk(paths *linuxpath.Paths, disk string) (map[string]string, error) { // Get device major:minor numbers - devNo, err := ioutil.ReadFile(filepath.Join(paths.SysBlock, disk, "dev")) + devNo, err := os.ReadFile(filepath.Join(paths.SysBlock, disk, "dev")) if err != nil { return nil, err } @@ -103,7 +103,7 @@ func udevInfoDisk(paths *linuxpath.Paths, disk string) (map[string]string, error // udevInfoPartition gets the udev info for a partition func udevInfoPartition(paths *linuxpath.Paths, disk string, partition string) (map[string]string, error) { // Get device major:minor numbers - devNo, err := ioutil.ReadFile(filepath.Join(paths.SysBlock, disk, partition, "dev")) + devNo, err := os.ReadFile(filepath.Join(paths.SysBlock, disk, partition, "dev")) if err != nil { return nil, err } @@ -113,7 +113,7 @@ func udevInfoPartition(paths *linuxpath.Paths, disk string, partition string) (m func udevInfo(paths *linuxpath.Paths, devNo string) (map[string]string, error) { // Look up block device in udev runtime database udevID := "b" + strings.TrimSpace(devNo) - udevBytes, err := ioutil.ReadFile(filepath.Join(paths.RunUdevData, udevID)) + udevBytes, err := os.ReadFile(filepath.Join(paths.RunUdevData, udevID)) if err != nil { return nil, err } @@ -147,6 +147,16 @@ func diskSerialNumber(paths *linuxpath.Paths, disk string) string { return util.UNKNOWN } + // First try to use the serial from sg3_utils + if serial, ok := info["SCSI_IDENT_SERIAL"]; ok { + return serial + } + + // Fall back to ID_SCSI_SERIAL + if serial, ok := info["ID_SCSI_SERIAL"]; ok { + return serial + } + // There are two serial number keys, ID_SERIAL and ID_SERIAL_SHORT The // non-_SHORT version often duplicates vendor information collected // elsewhere, so use _SHORT and fall back to ID_SERIAL if missing... @@ -173,6 +183,18 @@ func diskBusPath(paths *linuxpath.Paths, disk string) string { return util.UNKNOWN } +func diskWWNNoExtension(paths *linuxpath.Paths, disk string) string { + info, err := udevInfoDisk(paths, disk) + if err != nil { + return util.UNKNOWN + } + + if wwn, ok := info["ID_WWN"]; ok { + return wwn + } + return util.UNKNOWN +} + func diskWWN(paths *linuxpath.Paths, disk string) string { info, err := udevInfoDisk(paths, disk) if err != nil { @@ -196,7 +218,7 @@ func diskWWN(paths *linuxpath.Paths, disk string) string { func diskPartitions(ctx *context.Context, paths *linuxpath.Paths, disk string) []*Partition { out := make([]*Partition, 0) path := filepath.Join(paths.SysBlock, disk) - files, err := ioutil.ReadDir(path) + files, err := os.ReadDir(path) if err != nil { ctx.Warn("failed to read disk partitions: %s\n", err) return out @@ -281,7 +303,7 @@ func diskPartUUID(paths *linuxpath.Paths, disk string, partition string) string func diskIsRemovable(paths *linuxpath.Paths, disk string) bool { path := filepath.Join(paths.SysBlock, disk, "removable") - contents, err := ioutil.ReadFile(path) + contents, err := os.ReadFile(path) if err != nil { return false } @@ -295,7 +317,7 @@ func disks(ctx *context.Context, paths *linuxpath.Paths) []*Disk { // run. We can get all of this information by examining the /sys/block // and /sys/class/block files disks := make([]*Disk, 0) - files, err := ioutil.ReadDir(paths.SysBlock) + files, err := os.ReadDir(paths.SysBlock) if err != nil { return nil } @@ -316,6 +338,7 @@ func disks(ctx *context.Context, paths *linuxpath.Paths) []*Disk { model := diskModel(paths, dname) serialNo := diskSerialNumber(paths, dname) wwn := diskWWN(paths, dname) + wwnNoExtension := diskWWNNoExtension(paths, dname) removable := diskIsRemovable(paths, dname) if storageController == STORAGE_CONTROLLER_LOOP && size == 0 { @@ -335,6 +358,7 @@ func disks(ctx *context.Context, paths *linuxpath.Paths) []*Disk { Model: model, SerialNumber: serialNo, WWN: wwn, + WWNNoExtension: wwnNoExtension, } parts := diskPartitions(ctx, paths, dname) @@ -358,34 +382,34 @@ func diskTypes(dname string) ( // The conditionals below which set the controller and drive type are // based on information listed here: // https://en.wikipedia.org/wiki/Device_file - driveType := DRIVE_TYPE_UNKNOWN - storageController := STORAGE_CONTROLLER_UNKNOWN + driveType := DriveTypeUnknown + storageController := StorageControllerUnknown if strings.HasPrefix(dname, "fd") { - driveType = DRIVE_TYPE_FDD + driveType = DriveTypeFDD } else if strings.HasPrefix(dname, "sd") { - driveType = DRIVE_TYPE_HDD - storageController = STORAGE_CONTROLLER_SCSI + driveType = DriveTypeHDD + storageController = StorageControllerSCSI } else if strings.HasPrefix(dname, "hd") { - driveType = DRIVE_TYPE_HDD - storageController = STORAGE_CONTROLLER_IDE + driveType = DriveTypeHDD + storageController = StorageControllerIDE } else if strings.HasPrefix(dname, "vd") { - driveType = DRIVE_TYPE_HDD - storageController = STORAGE_CONTROLLER_VIRTIO + driveType = DriveTypeHDD + storageController = StorageControllerVirtIO } else if strings.HasPrefix(dname, "nvme") { - driveType = DRIVE_TYPE_SSD - storageController = STORAGE_CONTROLLER_NVME + driveType = DriveTypeSSD + storageController = StorageControllerNVMe } else if strings.HasPrefix(dname, "sr") { - driveType = DRIVE_TYPE_ODD - storageController = STORAGE_CONTROLLER_SCSI + driveType = DriveTypeODD + storageController = StorageControllerSCSI } else if strings.HasPrefix(dname, "xvd") { - driveType = DRIVE_TYPE_HDD - storageController = STORAGE_CONTROLLER_SCSI + driveType = DriveTypeHDD + storageController = StorageControllerSCSI } else if strings.HasPrefix(dname, "mmc") { - driveType = DRIVE_TYPE_SSD - storageController = STORAGE_CONTROLLER_MMC + driveType = DriveTypeSSD + storageController = StorageControllerMMC } else if strings.HasPrefix(dname, "loop") { - driveType = DRIVE_TYPE_VIRTUAL - storageController = STORAGE_CONTROLLER_LOOP + driveType = DriveTypeVirtual + storageController = StorageControllerLoop } return driveType, storageController @@ -403,7 +427,7 @@ func diskIsRotational(ctx *context.Context, paths *linuxpath.Paths, devName stri // paths. func partitionSizeBytes(paths *linuxpath.Paths, disk string, part string) uint64 { path := filepath.Join(paths.SysBlock, disk, part, "size") - contents, err := ioutil.ReadFile(path) + contents, err := os.ReadFile(path) if err != nil { return 0 } diff --git a/vendor/github.com/jaypipes/ghw/pkg/block/block_windows.go b/vendor/github.com/jaypipes/ghw/pkg/block/block_windows.go index 574f5612e9..270e19f98d 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/block/block_windows.go +++ b/vendor/github.com/jaypipes/ghw/pkg/block/block_windows.go @@ -17,24 +17,24 @@ import ( type physicalDiskMediaType int const ( - PHYSICAL_DISK_MEDIA_TYPE_UNSPECIFIED physicalDiskMediaType = 0 - PHYSICAL_DISK_MEDIA_TYPE_HDD physicalDiskMediaType = 3 - PHYSICAL_DISK_MEDIA_TYPE_SSD physicalDiskMediaType = 4 - PHYSICAL_DISK_MEDIA_TYPE_SCM physicalDiskMediaType = 5 + physicalDiskMediaTypeUnspecified physicalDiskMediaType = 0 + physicalDiskMediaTypeHDD physicalDiskMediaType = 3 + physicalDiskMediaTypeSSD physicalDiskMediaType = 4 + physicalDiskMediaTypeSCM physicalDiskMediaType = 5 ) func (dt physicalDiskMediaType) ToDriveType() DriveType { switch dt { - case PHYSICAL_DISK_MEDIA_TYPE_UNSPECIFIED: - return DRIVE_TYPE_UNKNOWN - case PHYSICAL_DISK_MEDIA_TYPE_HDD: - return DRIVE_TYPE_HDD - case PHYSICAL_DISK_MEDIA_TYPE_SSD: - return DRIVE_TYPE_SSD - case PHYSICAL_DISK_MEDIA_TYPE_SCM: - return DRIVE_TYPE_UNKNOWN + case physicalDiskMediaTypeUnspecified: + return DriveTypeUnknown + case physicalDiskMediaTypeHDD: + return DriveTypeHDD + case physicalDiskMediaTypeSSD: + return DriveTypeSSD + case physicalDiskMediaTypeSCM: + return DriveTypeUnknown } - return DRIVE_TYPE_UNKNOWN + return DriveTypeUnknown } const wqlDiskDrive = "SELECT Caption, CreationClassName, DefaultBlockSize, Description, DeviceID, Index, InterfaceType, Manufacturer, MediaType, Model, Name, Partitions, SerialNumber, Size, TotalCylinders, TotalHeads, TotalSectors, TotalTracks, TracksPerCylinder FROM Win32_DiskDrive" @@ -155,6 +155,7 @@ func (i *Info) load() error { Model: strings.TrimSpace(*diskdrive.Caption), SerialNumber: strings.TrimSpace(*diskdrive.SerialNumber), WWN: util.UNKNOWN, // TODO: add information + WWNNoExtension: util.UNKNOWN, // TODO: add information Partitions: make([]*Partition, 0), } for _, diskpartition := range win32DiskPartitionDescriptions { @@ -191,11 +192,12 @@ func (i *Info) load() error { } i.Disks = disks - var tpb uint64 + var tsb uint64 for _, d := range i.Disks { - tpb += d.SizeBytes + tsb += d.SizeBytes } - i.TotalPhysicalBytes = tpb + i.TotalSizeBytes = tsb + i.TotalPhysicalBytes = tsb return nil } @@ -245,18 +247,18 @@ func getPhysicalDisks() ([]win32PhysicalDisk, error) { } func toDriveType(physicalDiskMediaType physicalDiskMediaType, mediaType string, caption string) DriveType { - if driveType := physicalDiskMediaType.ToDriveType(); driveType != DRIVE_TYPE_UNKNOWN { + if driveType := physicalDiskMediaType.ToDriveType(); driveType != DriveTypeUnknown { return driveType } mediaType = strings.ToLower(mediaType) caption = strings.ToLower(caption) if strings.Contains(mediaType, "fixed") || strings.Contains(mediaType, "ssd") || strings.Contains(caption, "ssd") { - return DRIVE_TYPE_SSD + return DriveTypeSSD } else if strings.ContainsAny(mediaType, "hdd") { - return DRIVE_TYPE_HDD + return DriveTypeHDD } - return DRIVE_TYPE_UNKNOWN + return DriveTypeUnknown } // TODO: improve @@ -264,11 +266,11 @@ func toStorageController(interfaceType string) StorageController { var storageController StorageController switch interfaceType { case "SCSI": - storageController = STORAGE_CONTROLLER_SCSI + storageController = StorageControllerSCSI case "IDE": - storageController = STORAGE_CONTROLLER_IDE + storageController = StorageControllerIDE default: - storageController = STORAGE_CONTROLLER_UNKNOWN + storageController = StorageControllerUnknown } return storageController } diff --git a/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_darwin.go b/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_darwin.go new file mode 100644 index 0000000000..7e9e8fc7e8 --- /dev/null +++ b/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_darwin.go @@ -0,0 +1,135 @@ +package cpu + +import ( + "fmt" + "github.com/pkg/errors" + "os/exec" + "strconv" + "strings" +) + +var ( + hasARMArchitecture = false // determine if ARM + sysctlOutput = make(map[string]string) // store all the sysctl output +) + +func (i *Info) load() error { + err := populateSysctlOutput() + if err != nil { + return errors.Wrap(err, "unable to populate sysctl map") + } + + i.TotalCores = getTotalCores() + i.TotalThreads = getTotalThreads() + i.Processors = getProcessors() + + return nil +} + +// getProcessors some more info https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_system_capabilities +func getProcessors() []*Processor { + p := make([]*Processor, getProcTopCount()) + for i, _ := range p { + p[i] = new(Processor) + p[i].Vendor = sysctlOutput[fmt.Sprintf("hw.perflevel%s.name", strconv.Itoa(i))] + p[i].Model = getVendor() + p[i].NumCores = getNumberCoresFromPerfLevel(i) + p[i].Capabilities = getCapabilities() + p[i].Cores = make([]*ProcessorCore, getTotalCores()) + } + return p +} + +// getCapabilities valid for ARM, see https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics +func getCapabilities() []string { + var caps []string + + // add ARM capabilities + if hasARMArchitecture { + for cap, isEnabled := range sysctlOutput { + if isEnabled == "1" { + // capabilities with keys with a common prefix + commonPrefix := "hw.optional.arm." + if strings.HasPrefix(cap, commonPrefix) { + caps = append(caps, strings.TrimPrefix(cap, commonPrefix)) + } + // not following prefix convention but are important + if cap == "hw.optional.AdvSIMD_HPFPCvt" { + caps = append(caps, "AdvSIMD_HPFPCvt") + } + if cap == "hw.optional.armv8_crc32" { + caps = append(caps, "armv8_crc32") + } + } + } + + // hw.optional.AdvSIMD and hw.optional.floatingpoint are always enabled (see linked doc) + caps = append(caps, "AdvSIMD") + caps = append(caps, "floatingpoint") + } + + return caps +} + +// populateSysctlOutput to populate a map to quickly retrieve values later +func populateSysctlOutput() error { + // get sysctl output + o, err := exec.Command("sysctl", "-a").CombinedOutput() + if err != nil { + return err + } + + // clean up and store sysctl output + oS := strings.Split(string(o), "\n") + for _, l := range oS { + if l != "" { + s := strings.SplitN(l, ":", 2) + k, v := strings.TrimSpace(s[0]), strings.TrimSpace(s[1]) + sysctlOutput[k] = v + + // see if it's possible to determine if ARM + if k == "hw.optional.arm64" && v == "1" { + hasARMArchitecture = true + } + } + } + + return nil +} + +func getNumberCoresFromPerfLevel(i int) uint32 { + key := fmt.Sprintf("hw.perflevel%s.physicalcpu_max", strconv.Itoa(i)) + nCores := sysctlOutput[key] + return stringToUint32(nCores) +} + +func getVendor() string { + v := sysctlOutput["machdep.cpu.brand_string"] + return v +} + +func getProcTopCount() int { + pC, ok := sysctlOutput["hw.nperflevels"] + if !ok { + // most likely intel so no performance/efficiency core seperation + return 1 + } + i, _ := strconv.Atoi(pC) + return i +} + +// num of physical cores +func getTotalCores() uint32 { + nCores := sysctlOutput["hw.physicalcpu_max"] + return stringToUint32(nCores) +} + +func getTotalThreads() uint32 { + nThreads := sysctlOutput["machdep.cpu.thread_count"] + return stringToUint32(nThreads) +} + +func stringToUint32(s string) uint32 { + o, _ := strconv.ParseUint(s, 10, 0) + return uint32(o) +} diff --git a/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_linux.go b/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_linux.go index 00e701940f..3ec2e8473f 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_linux.go +++ b/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_linux.go @@ -8,10 +8,10 @@ package cpu import ( "bufio" "fmt" - "io/ioutil" "os" "path/filepath" "regexp" + "sort" "strconv" "strings" @@ -22,6 +22,7 @@ import ( var ( regexForCpulCore = regexp.MustCompile("^cpu([0-9]+)$") + onlineFile = "online" ) func (i *Info) load() error { @@ -47,7 +48,7 @@ func processorsGet(ctx *context.Context) []*Processor { // /sys/devices/system/cpu pseudodir contains N number of pseudodirs with // information about the logical processors on the host. These logical // processor pseudodirs are of the pattern /sys/devices/system/cpu/cpu{N} - fnames, err := ioutil.ReadDir(paths.SysDevicesSystemCPU) + fnames, err := os.ReadDir(paths.SysDevicesSystemCPU) if err != nil { ctx.Warn("failed to read /sys/devices/system/cpu: %s", err) return []*Processor{} @@ -64,6 +65,10 @@ func processorsGet(ctx *context.Context) []*Processor { continue } + onlineFilePath := filepath.Join(paths.SysDevicesSystemCPU, fmt.Sprintf("cpu%d", lpID), onlineFile) + if util.SafeIntFromFile(ctx, onlineFilePath) == 0 { + continue + } procID := processorIDFromLogicalProcessorID(ctx, lpID) proc, found := procs[procID] if !found { @@ -113,6 +118,9 @@ func processorsGet(ctx *context.Context) []*Processor { } res := []*Processor{} for _, p := range procs { + for _, c := range p.Cores { + sort.Ints(c.LogicalProcessors) + } res = append(res, p) } return res @@ -172,7 +180,7 @@ func CoresForNode(ctx *context.Context, nodeID int) ([]*ProcessorCore, error) { return c } - files, err := ioutil.ReadDir(path) + files, err := os.ReadDir(path) if err != nil { return nil, err } @@ -198,6 +206,10 @@ func CoresForNode(ctx *context.Context, nodeID int) ([]*ProcessorCore, error) { ) continue } + onlineFilePath := filepath.Join(cpuPath, onlineFile) + if util.SafeIntFromFile(ctx, onlineFilePath) == 0 { + continue + } coreIDPath := filepath.Join(cpuPath, "topology", "core_id") coreID := util.SafeIntFromFile(ctx, coreIDPath) core := findCoreByID(coreID) diff --git a/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_stub.go b/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_stub.go index 5d07ee4327..85156069a1 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_stub.go +++ b/vendor/github.com/jaypipes/ghw/pkg/cpu/cpu_stub.go @@ -1,5 +1,5 @@ -//go:build !linux && !windows -// +build !linux,!windows +//go:build !linux && !windows && !darwin +// +build !linux,!windows,!darwin // Use and distribution licensed under the Apache license version 2. // diff --git a/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu_linux.go b/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu_linux.go index a2791e86d1..8f9c9b8cad 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu_linux.go +++ b/vendor/github.com/jaypipes/ghw/pkg/gpu/gpu_linux.go @@ -6,7 +6,6 @@ package gpu import ( - "io/ioutil" "os" "path/filepath" "strconv" @@ -55,7 +54,7 @@ func (i *Info) load() error { // subsystem (we query the modalias file of the PCI device's sysfs // directory using the `ghw.PCIInfo.GetDevice()` function. paths := linuxpath.New(i.ctx) - links, err := ioutil.ReadDir(paths.SysClassDRM) + links, err := os.ReadDir(paths.SysClassDRM) if err != nil { i.ctx.Warn(_WARN_NO_SYS_CLASS_DRM) return nil diff --git a/vendor/github.com/jaypipes/ghw/pkg/linuxdmi/dmi_linux.go b/vendor/github.com/jaypipes/ghw/pkg/linuxdmi/dmi_linux.go index 09398d36c8..8e6d8302d5 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/linuxdmi/dmi_linux.go +++ b/vendor/github.com/jaypipes/ghw/pkg/linuxdmi/dmi_linux.go @@ -6,7 +6,7 @@ package linuxdmi import ( - "io/ioutil" + "os" "path/filepath" "strings" @@ -19,7 +19,7 @@ func Item(ctx *context.Context, value string) string { paths := linuxpath.New(ctx) path := filepath.Join(paths.SysClassDMI, "id", value) - b, err := ioutil.ReadFile(path) + b, err := os.ReadFile(path) if err != nil { ctx.Warn("Unable to read %s: %s\n", value, err) return util.UNKNOWN diff --git a/vendor/github.com/jaypipes/ghw/pkg/marshal/marshal.go b/vendor/github.com/jaypipes/ghw/pkg/marshal/marshal.go index e8f1bbeac9..e442d6aff3 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/marshal/marshal.go +++ b/vendor/github.com/jaypipes/ghw/pkg/marshal/marshal.go @@ -9,28 +9,36 @@ package marshal import ( "encoding/json" - "github.com/ghodss/yaml" "github.com/jaypipes/ghw/pkg/context" + yaml "gopkg.in/yaml.v3" ) -// safeYAML returns a string after marshalling the supplied parameter into YAML +// SafeYAML returns a string after marshalling the supplied parameter into YAML. func SafeYAML(ctx *context.Context, p interface{}) string { b, err := json.Marshal(p) if err != nil { ctx.Warn("error marshalling JSON: %s", err) return "" } - yb, err := yaml.JSONToYAML(b) - if err != nil { + + var jsonObj interface{} + if err := yaml.Unmarshal(b, &jsonObj); err != nil { ctx.Warn("error converting JSON to YAML: %s", err) return "" } + + yb, err := yaml.Marshal(jsonObj) + if err != nil { + ctx.Warn("error marshalling YAML: %s", err) + return "" + } + return string(yb) } -// safeJSON returns a string after marshalling the supplied parameter into +// SafeJSON returns a string after marshalling the supplied parameter into // JSON. Accepts an optional argument to trigger pretty/indented formatting of -// the JSON string +// the JSON string. func SafeJSON(ctx *context.Context, p interface{}, indent bool) string { var b []byte var err error diff --git a/vendor/github.com/jaypipes/ghw/pkg/memory/memory.go b/vendor/github.com/jaypipes/ghw/pkg/memory/memory.go index bdf1ab1ac4..81e0dc667e 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/memory/memory.go +++ b/vendor/github.com/jaypipes/ghw/pkg/memory/memory.go @@ -17,6 +17,10 @@ import ( "github.com/jaypipes/ghw/pkg/util" ) +// Module describes a single physical memory module for a host system. Pretty +// much all modern systems contain dual in-line memory modules (DIMMs). +// +// See https://en.wikipedia.org/wiki/DIMM type Module struct { Label string `json:"label"` Location string `json:"location"` @@ -25,6 +29,10 @@ type Module struct { Vendor string `json:"vendor"` } +// Area describes a set of physical memory on a host system. Non-NUMA systems +// will almost always have a single memory area containing all memory the +// system can use. NUMA systems will have multiple memory areas, one or more +// for each NUMA node/cell in the system. type Area struct { TotalPhysicalBytes int64 `json:"total_physical_bytes"` TotalUsableBytes int64 `json:"total_usable_bytes"` @@ -33,6 +41,8 @@ type Area struct { Modules []*Module `json:"modules"` } +// String returns a short string with a summary of information for this memory +// area func (a *Area) String() string { tpbs := util.UNKNOWN if a.TotalPhysicalBytes > 0 { @@ -51,11 +61,13 @@ func (a *Area) String() string { return fmt.Sprintf("memory (%s physical, %s usable)", tpbs, tubs) } +// Info contains information about the memory on a host system. type Info struct { ctx *context.Context Area } +// New returns an Info struct that describes the memory on a host system. func New(opts ...*option.Option) (*Info, error) { ctx := context.New(opts...) info := &Info{ctx: ctx} @@ -65,6 +77,7 @@ func New(opts ...*option.Option) (*Info, error) { return info, nil } +// String returns a short string with a summary of memory information func (i *Info) String() string { return i.Area.String() } diff --git a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache.go b/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache.go index 8bc4074def..2d8f88d7ce 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache.go +++ b/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache.go @@ -15,19 +15,35 @@ import ( "github.com/jaypipes/ghw/pkg/unitutil" ) +// CacheType indicates the type of memory stored in a memory cache. type CacheType int const ( - CACHE_TYPE_UNIFIED CacheType = iota - CACHE_TYPE_INSTRUCTION - CACHE_TYPE_DATA + // CacheTypeUnified indicates the memory cache stores both instructions and + // data. + CacheTypeUnified CacheType = iota + // CacheTypeInstruction indicates the memory cache stores only instructions + // (executable bytecode). + CacheTypeInstruction + // CacheTypeData indicates the memory cache stores only data + // (non-executable bytecode). + CacheTypeData +) + +const ( + // DEPRECATED: Please use CacheTypeUnified + CACHE_TYPE_UNIFIED = CacheTypeUnified + // DEPRECATED: Please use CacheTypeUnified + CACHE_TYPE_INSTRUCTION = CacheTypeInstruction + // DEPRECATED: Please use CacheTypeUnified + CACHE_TYPE_DATA = CacheTypeData ) var ( memoryCacheTypeString = map[CacheType]string{ - CACHE_TYPE_UNIFIED: "Unified", - CACHE_TYPE_INSTRUCTION: "Instruction", - CACHE_TYPE_DATA: "Data", + CacheTypeUnified: "Unified", + CacheTypeInstruction: "Instruction", + CacheTypeData: "Data", } // NOTE(fromani): the keys are all lowercase and do not match @@ -36,9 +52,9 @@ var ( // CacheType:MarshalJSON. // We use this table only in UnmarshalJSON, so it should be OK. stringMemoryCacheType = map[string]CacheType{ - "unified": CACHE_TYPE_UNIFIED, - "instruction": CACHE_TYPE_INSTRUCTION, - "data": CACHE_TYPE_DATA, + "unified": CacheTypeUnified, + "instruction": CacheTypeInstruction, + "data": CacheTypeData, } ) @@ -92,21 +108,33 @@ func (a SortByLogicalProcessorId) Len() int { return len(a) } func (a SortByLogicalProcessorId) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a SortByLogicalProcessorId) Less(i, j int) bool { return a[i] < a[j] } +// Cache contains information about a single memory cache on a physical CPU +// package. Caches have a 1-based numeric level, with lower numbers indicating +// the cache is "closer" to the processing cores and reading memory from the +// cache will be faster relative to caches with higher levels. Note that this +// has nothing to do with RAM or memory modules like DIMMs. type Cache struct { - Level uint8 `json:"level"` - Type CacheType `json:"type"` - SizeBytes uint64 `json:"size_bytes"` - // The set of logical processors (hardware threads) that have access to the - // cache + // Level is a 1-based numeric level that indicates the relative closeness + // of this cache to processing cores on the physical package. Lower numbers + // are "closer" to the processing cores and therefore have faster access + // times. + Level uint8 `json:"level"` + // Type indicates what type of memory is stored in the cache. Can be + // instruction (executable bytecodes), data or both. + Type CacheType `json:"type"` + // SizeBytes indicates the size of the cache in bytes. + SizeBytes uint64 `json:"size_bytes"` + // The set of logical processors (hardware threads) that have access to + // this cache. LogicalProcessors []uint32 `json:"logical_processors"` } func (c *Cache) String() string { sizeKb := c.SizeBytes / uint64(unitutil.KB) typeStr := "" - if c.Type == CACHE_TYPE_INSTRUCTION { + if c.Type == CacheTypeInstruction { typeStr = "i" - } else if c.Type == CACHE_TYPE_DATA { + } else if c.Type == CacheTypeData { typeStr = "d" } cacheIDStr := fmt.Sprintf("L%d%s", c.Level, typeStr) diff --git a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache_linux.go b/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache_linux.go index dfb5c1f1ea..12258ea4ed 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache_linux.go +++ b/vendor/github.com/jaypipes/ghw/pkg/memory/memory_cache_linux.go @@ -8,7 +8,6 @@ package memory import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" "sort" @@ -35,7 +34,7 @@ func CachesForNode(ctx *context.Context, nodeID int) ([]*Cache, error) { ) caches := make(map[string]*Cache) - files, err := ioutil.ReadDir(path) + files, err := os.ReadDir(path) if err != nil { return nil, err } @@ -66,7 +65,7 @@ func CachesForNode(ctx *context.Context, nodeID int) ([]*Cache, error) { if _, err = os.Stat(cachePath); errors.Is(err, os.ErrNotExist) { continue } - cacheDirFiles, err := ioutil.ReadDir(cachePath) + cacheDirFiles, err := os.ReadDir(cachePath) if err != nil { return nil, err } @@ -120,7 +119,7 @@ func memoryCacheLevel(ctx *context.Context, paths *linuxpath.Paths, nodeID int, paths.NodeCPUCacheIndex(nodeID, lpID, cacheIndex), "level", ) - levelContents, err := ioutil.ReadFile(levelPath) + levelContents, err := os.ReadFile(levelPath) if err != nil { ctx.Warn("%s", err) return -1 @@ -140,7 +139,7 @@ func memoryCacheSize(ctx *context.Context, paths *linuxpath.Paths, nodeID int, l paths.NodeCPUCacheIndex(nodeID, lpID, cacheIndex), "size", ) - sizeContents, err := ioutil.ReadFile(sizePath) + sizeContents, err := os.ReadFile(sizePath) if err != nil { ctx.Warn("%s", err) return -1 @@ -159,18 +158,18 @@ func memoryCacheType(ctx *context.Context, paths *linuxpath.Paths, nodeID int, l paths.NodeCPUCacheIndex(nodeID, lpID, cacheIndex), "type", ) - cacheTypeContents, err := ioutil.ReadFile(typePath) + cacheTypeContents, err := os.ReadFile(typePath) if err != nil { ctx.Warn("%s", err) - return CACHE_TYPE_UNIFIED + return CacheTypeUnified } switch string(cacheTypeContents[:len(cacheTypeContents)-1]) { case "Data": - return CACHE_TYPE_DATA + return CacheTypeData case "Instruction": - return CACHE_TYPE_INSTRUCTION + return CacheTypeInstruction default: - return CACHE_TYPE_UNIFIED + return CacheTypeUnified } } @@ -179,7 +178,7 @@ func memoryCacheSharedCPUMap(ctx *context.Context, paths *linuxpath.Paths, nodeI paths.NodeCPUCacheIndex(nodeID, lpID, cacheIndex), "shared_cpu_map", ) - sharedCpuMap, err := ioutil.ReadFile(scpuPath) + sharedCpuMap, err := os.ReadFile(scpuPath) if err != nil { ctx.Warn("%s", err) return "" diff --git a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_linux.go b/vendor/github.com/jaypipes/ghw/pkg/memory/memory_linux.go index 21d10f2fcf..d5a54101af 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/memory/memory_linux.go +++ b/vendor/github.com/jaypipes/ghw/pkg/memory/memory_linux.go @@ -10,7 +10,6 @@ import ( "compress/gzip" "fmt" "io" - "io/ioutil" "os" "path/filepath" "regexp" @@ -24,7 +23,7 @@ import ( ) const ( - _WARN_CANNOT_DETERMINE_PHYSICAL_MEMORY = ` + warnCannotDeterminePhysicalMemory = ` Could not determine total physical bytes of memory. This may be due to the host being a virtual machine or container with no /var/log/syslog file or /sys/devices/system/memory directory, or @@ -37,7 +36,7 @@ the total usable amount of memory var ( // System log lines will look similar to the following: // ... kernel: [0.000000] Memory: 24633272K/25155024K ... - _REGEX_SYSLOG_MEMLINE = regexp.MustCompile(`Memory:\s+\d+K\/(\d+)K`) + regexSyslogMemline = regexp.MustCompile(`Memory:\s+\d+K\/(\d+)K`) // regexMemoryBlockDirname matches a subdirectory in either // /sys/devices/system/memory or /sys/devices/system/node/nodeX that // represents information on a specific memory cell/block @@ -54,7 +53,7 @@ func (i *Info) load() error { tpb := memTotalPhysicalBytes(paths) i.TotalPhysicalBytes = tpb if tpb < 1 { - i.ctx.Warn(_WARN_CANNOT_DETERMINE_PHYSICAL_MEMORY) + i.ctx.Warn(warnCannotDeterminePhysicalMemory) i.TotalPhysicalBytes = tub } i.SupportedPageSizes, _ = memorySupportedPageSizes(paths.SysKernelMMHugepages) @@ -111,7 +110,7 @@ func memoryBlockSizeBytes(dir string) (uint64, error) { // get the memory block size in byte in hexadecimal notation blockSize := filepath.Join(dir, "block_size_bytes") - d, err := ioutil.ReadFile(blockSize) + d, err := os.ReadFile(blockSize) if err != nil { return 0, err } @@ -149,7 +148,7 @@ func memTotalPhysicalBytes(paths *linuxpath.Paths) (total int64) { // size in bytes func memoryTotalPhysicalBytesFromPath(dir string, blockSizeBytes uint64) (int64, error) { var total int64 - files, err := ioutil.ReadDir(dir) + files, err := os.ReadDir(dir) if err != nil { return -1, err } @@ -165,7 +164,7 @@ func memoryTotalPhysicalBytesFromPath(dir string, blockSizeBytes uint64) (int64, if !regexMemoryBlockDirname.MatchString(fname) { continue } - s, err := ioutil.ReadFile(filepath.Join(dir, fname, "state")) + s, err := os.ReadFile(filepath.Join(dir, fname, "state")) if err != nil { return -1, err } @@ -186,7 +185,7 @@ func memTotalPhysicalBytesFromSyslog(paths *linuxpath.Paths) int64 { // so instead we examine the system logs for startup information containing // total physical memory and cache the results of this. findPhysicalKb := func(line string) int64 { - matches := _REGEX_SYSLOG_MEMLINE.FindStringSubmatch(line) + matches := regexSyslogMemline.FindStringSubmatch(line) if len(matches) == 2 { i, err := strconv.Atoi(matches[1]) if err != nil { @@ -202,7 +201,7 @@ func memTotalPhysicalBytesFromSyslog(paths *linuxpath.Paths) int64 { // search each, stopping when we match a system log record line that // contains physical memory information. logDir := paths.VarLog - logFiles, err := ioutil.ReadDir(logDir) + logFiles, err := os.ReadDir(logDir) if err != nil { return -1 } @@ -304,7 +303,7 @@ func memorySupportedPageSizes(hpDir string) ([]uint64, error) { // 'hugepages-{pagesize}kb' out := make([]uint64, 0) - files, err := ioutil.ReadDir(hpDir) + files, err := os.ReadDir(hpDir) if err != nil { return out, err } diff --git a/vendor/github.com/jaypipes/ghw/pkg/net/net.go b/vendor/github.com/jaypipes/ghw/pkg/net/net.go index 82d3226a11..e26dab702e 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/net/net.go +++ b/vendor/github.com/jaypipes/ghw/pkg/net/net.go @@ -14,28 +14,63 @@ import ( "github.com/jaypipes/ghw/pkg/option" ) +// NICCapability is a feature/capability of a Network Interface Controller +// (NIC) type NICCapability struct { - Name string `json:"name"` - IsEnabled bool `json:"is_enabled"` - CanEnable bool `json:"can_enable"` + // Name is the string name for the capability, e.g. + // "tcp-segmentation-offload" + Name string `json:"name"` + // IsEnabled is true if the capability is currently enabled on the NIC, + // false otherwise. + IsEnabled bool `json:"is_enabled"` + // CanEnable is true if the capability can be enabled on the NIC, false + // otherwise. + CanEnable bool `json:"can_enable"` } +// NIC contains information about a single Network Interface Controller (NIC). type NIC struct { - Name string `json:"name"` - MacAddress string `json:"mac_address"` - IsVirtual bool `json:"is_virtual"` - Capabilities []*NICCapability `json:"capabilities"` - PCIAddress *string `json:"pci_address,omitempty"` - Speed string `json:"speed"` - Duplex string `json:"duplex"` - SupportedLinkModes []string `json:"supported_link_modes,omitempty"` - SupportedPorts []string `json:"supported_ports,omitempty"` - SupportedFECModes []string `json:"supported_fec_modes,omitempty"` - AdvertisedLinkModes []string `json:"advertised_link_modes,omitempty"` - AdvertisedFECModes []string `json:"advertised_fec_modes,omitempty"` + // Name is the string identifier the system gave this NIC. + Name string `json:"name"` + // MACAddress is the Media Access Control (MAC) address of this NIC. + MACAddress string `json:"mac_address"` + // DEPRECATED: Please use MACAddress instead. + MacAddress string `json:"-"` + // IsVirtual is true if the NIC is entirely virtual/emulated, false + // otherwise. + IsVirtual bool `json:"is_virtual"` + // Capabilities is a slice of pointers to `NICCapability` structs + // describing a feature/capability of this NIC. + Capabilities []*NICCapability `json:"capabilities"` + // PCIAddress is a pointer to the PCI address for this NIC, or nil if there + // is no PCI address for this NIC. + PCIAddress *string `json:"pci_address,omitempty"` + // Speed is a string describing the link speed of this NIC, e.g. "1000Mb/s" + Speed string `json:"speed"` + // Duplex is a string indicating the current duplex setting of this NIC, + // e.g. "Full" + Duplex string `json:"duplex"` + // SupportedLinkModes is a slice of strings containing the supported link + // modes of this NIC, e.g. "10baseT/Half", "1000baseT/Full", etc. + SupportedLinkModes []string `json:"supported_link_modes,omitempty"` + // SupportedPorts is a slice of strings containing the supported physical + // ports on this NIC, e.g. "Twisted Pair" + SupportedPorts []string `json:"supported_ports,omitempty"` + // SupportedFECModes is a slice of strings containing the supported Forward + // Error Correction (FEC) modes for this NIC. + SupportedFECModes []string `json:"supported_fec_modes,omitempty"` + // AdvertiseLinkModes is a slice of strings containing the advertised + // (during auto-negotiation) link modes of this NIC, e.g. "10baseT/Half", + // "1000baseT/Full", etc. + AdvertisedLinkModes []string `json:"advertised_link_modes,omitempty"` + // AvertisedFECModes is a slice of strings containing the advertised + // (during auto-negotiation) Forward Error Correction (FEC) modes for this + // NIC. + AdvertisedFECModes []string `json:"advertised_fec_modes,omitempty"` // TODO(fromani): add other hw addresses (USB) when we support them } +// String returns a short string with information about the NIC capability. func (nc *NICCapability) String() string { return fmt.Sprintf( "{Name:%s IsEnabled:%t CanEnable:%t}", @@ -45,6 +80,7 @@ func (nc *NICCapability) String() string { ) } +// String returns a short string with information about the NIC. func (n *NIC) String() string { isVirtualStr := "" if n.IsVirtual { @@ -57,8 +93,11 @@ func (n *NIC) String() string { ) } +// Info describes all network interface controllers (NICs) in the host system. type Info struct { - ctx *context.Context + ctx *context.Context + // NICs is a slice of pointers to `NIC` structs describing the network + // interface controllers (NICs) on the host system. NICs []*NIC `json:"nics"` } @@ -73,6 +112,8 @@ func New(opts ...*option.Option) (*Info, error) { return info, nil } +// String returns a short string with information about the networking on the +// host system. func (i *Info) String() string { return fmt.Sprintf( "net (%d NICs)", diff --git a/vendor/github.com/jaypipes/ghw/pkg/net/net_linux.go b/vendor/github.com/jaypipes/ghw/pkg/net/net_linux.go index cbdea30408..d7d7e8caf3 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/net/net_linux.go +++ b/vendor/github.com/jaypipes/ghw/pkg/net/net_linux.go @@ -9,7 +9,6 @@ import ( "bufio" "bytes" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -21,7 +20,7 @@ import ( ) const ( - _WARN_ETHTOOL_NOT_INSTALLED = `ethtool not installed. Cannot grab NIC capabilities` + warnEthtoolNotInstalled = `ethtool not installed. Cannot grab NIC capabilities` ) func (i *Info) load() error { @@ -33,7 +32,7 @@ func nics(ctx *context.Context) []*NIC { nics := make([]*NIC, 0) paths := linuxpath.New(ctx) - files, err := ioutil.ReadDir(paths.SysClassNet) + files, err := os.ReadDir(paths.SysClassNet) if err != nil { return nics } @@ -41,7 +40,7 @@ func nics(ctx *context.Context) []*NIC { etAvailable := ctx.EnableTools if etAvailable { if etInstalled := ethtoolInstalled(); !etInstalled { - ctx.Warn(_WARN_ETHTOOL_NOT_INSTALLED) + ctx.Warn(warnEthtoolNotInstalled) etAvailable = false } } @@ -67,6 +66,7 @@ func nics(ctx *context.Context) []*NIC { mac := netDeviceMacAddress(paths, filename) nic.MacAddress = mac + nic.MACAddress = mac if etAvailable { nic.netDeviceParseEthtool(ctx, filename) } else { @@ -88,7 +88,7 @@ func netDeviceMacAddress(paths *linuxpath.Paths, dev string) string { // that have addr_assign_type != 0, return None since the MAC address is // random. aatPath := filepath.Join(paths.SysClassNet, dev, "addr_assign_type") - contents, err := ioutil.ReadFile(aatPath) + contents, err := os.ReadFile(aatPath) if err != nil { return "" } @@ -96,7 +96,7 @@ func netDeviceMacAddress(paths *linuxpath.Paths, dev string) string { return "" } addrPath := filepath.Join(paths.SysClassNet, dev, "address") - contents, err = ioutil.ReadFile(addrPath) + contents, err = os.ReadFile(addrPath) if err != nil { return "" } @@ -256,7 +256,7 @@ func (nic *NIC) setNicAttrSysFs(paths *linuxpath.Paths, dev string) { } func readFile(path string) string { - contents, err := ioutil.ReadFile(path) + contents, err := os.ReadFile(path) if err != nil { return "" } diff --git a/vendor/github.com/jaypipes/ghw/pkg/net/net_windows.go b/vendor/github.com/jaypipes/ghw/pkg/net/net_windows.go index 0b46aa566e..7efc0946ce 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/net/net_windows.go +++ b/vendor/github.com/jaypipes/ghw/pkg/net/net_windows.go @@ -45,10 +45,10 @@ func nics(win32NetDescriptions []win32NetworkAdapter) []*NIC { nic := &NIC{ Name: netDeviceName(nicDescription), MacAddress: *nicDescription.MACAddress, + MACAddress: *nicDescription.MACAddress, IsVirtual: netIsVirtual(nicDescription), Capabilities: []*NICCapability{}, } - // Appenging NIC to NICs nics = append(nics, nic) } diff --git a/vendor/github.com/jaypipes/ghw/pkg/option/option.go b/vendor/github.com/jaypipes/ghw/pkg/option/option.go index 6cd231de3d..7ce14016d7 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/option/option.go +++ b/vendor/github.com/jaypipes/ghw/pkg/option/option.go @@ -8,7 +8,6 @@ package option import ( "io" - "io/ioutil" "log" "os" ) @@ -35,7 +34,7 @@ type Alerter interface { } var ( - NullAlerter = log.New(ioutil.Discard, "", 0) + NullAlerter = log.New(io.Discard, "", 0) ) // EnvOrDefaultAlerter returns the default instance ghw will use to emit @@ -45,7 +44,7 @@ var ( func EnvOrDefaultAlerter() Alerter { var dest io.Writer if _, exists := os.LookupEnv(envKeyDisableWarnings); exists { - dest = ioutil.Discard + dest = io.Discard } else { // default dest = os.Stderr diff --git a/vendor/github.com/jaypipes/ghw/pkg/pci/address/address.go b/vendor/github.com/jaypipes/ghw/pkg/pci/address/address.go index 6a8a4e4575..660238c21f 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/pci/address/address.go +++ b/vendor/github.com/jaypipes/ghw/pkg/pci/address/address.go @@ -13,7 +13,7 @@ import ( var ( regexAddress *regexp.Regexp = regexp.MustCompile( - `^(([0-9a-f]{0,4}):)?([0-9a-f]{2}):([0-9a-f]{2})\.([0-9a-f]{1})$`, + `^((1?[0-9a-f]{0,4}):)?([0-9a-f]{2}):([0-9a-f]{2})\.([0-9a-f]{1})$`, ) ) @@ -30,12 +30,11 @@ func (addr *Address) String() string { return addr.Domain + ":" + addr.Bus + ":" + addr.Device + "." + addr.Function } -// FromString returns an Address struct from an ddress string in either -// $BUS:$DEVICE.$FUNCTION (BDF) format or it can be a full PCI address that -// includes the 4-digit $DOMAIN information as well: -// $DOMAIN:$BUS:$DEVICE.$FUNCTION. +// FromString returns [Address] from an address string in either +// $BUS:$DEVICE.$FUNCTION (BDF) format or a full PCI address that +// includes the domain: $DOMAIN:$BUS:$DEVICE.$FUNCTION. // -// Returns "" if the address string wasn't a valid PCI address. +// If the address string isn't a valid PCI address, then nil is returned. func FromString(address string) *Address { addrLowered := strings.ToLower(address) matches := regexAddress.FindStringSubmatch(addrLowered) diff --git a/vendor/github.com/jaypipes/ghw/pkg/pci/pci.go b/vendor/github.com/jaypipes/ghw/pkg/pci/pci.go index 86cc7b2522..49adde620b 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/pci/pci.go +++ b/vendor/github.com/jaypipes/ghw/pkg/pci/pci.go @@ -15,17 +15,10 @@ import ( "github.com/jaypipes/ghw/pkg/context" "github.com/jaypipes/ghw/pkg/marshal" "github.com/jaypipes/ghw/pkg/option" - pciaddr "github.com/jaypipes/ghw/pkg/pci/address" "github.com/jaypipes/ghw/pkg/topology" "github.com/jaypipes/ghw/pkg/util" ) -// backward compatibility, to be removed in 1.0.0 -type Address pciaddr.Address - -// backward compatibility, to be removed in 1.0.0 -var AddressFromString = pciaddr.FromString - type Device struct { // The PCI address of the device Address string `json:"address"` @@ -123,22 +116,11 @@ func (d *Device) String() string { } type Info struct { + db *pcidb.PCIDB arch topology.Architecture ctx *context.Context // All PCI devices on the host system Devices []*Device - // hash of class ID -> class information - // DEPRECATED. Will be removed in v1.0. Please use - // github.com/jaypipes/pcidb to explore PCIDB information - Classes map[string]*pcidb.Class `json:"-"` - // hash of vendor ID -> vendor information - // DEPRECATED. Will be removed in v1.0. Please use - // github.com/jaypipes/pcidb to explore PCIDB information - Vendors map[string]*pcidb.Vendor `json:"-"` - // hash of vendor ID + product/device ID -> product information - // DEPRECATED. Will be removed in v1.0. Please use - // github.com/jaypipes/pcidb to explore PCIDB information - Products map[string]*pcidb.Product `json:"-"` } func (i *Info) String() string { diff --git a/vendor/github.com/jaypipes/ghw/pkg/pci/pci_linux.go b/vendor/github.com/jaypipes/ghw/pkg/pci/pci_linux.go index 087da33d26..538e77f325 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/pci/pci_linux.go +++ b/vendor/github.com/jaypipes/ghw/pkg/pci/pci_linux.go @@ -6,7 +6,6 @@ package pci import ( - "io/ioutil" "os" "path/filepath" "strings" @@ -44,10 +43,8 @@ func (i *Info) load() error { if err != nil { return err } - i.Classes = db.Classes - i.Vendors = db.Vendors - i.Products = db.Products - i.Devices = i.ListDevices() + i.db = db + i.Devices = i.getDevices() return nil } @@ -71,7 +68,7 @@ func getDeviceRevision(ctx *context.Context, pciAddr *pciaddr.Address) string { if _, err := os.Stat(revisionPath); err != nil { return "" } - revision, err := ioutil.ReadFile(revisionPath) + revision, err := os.ReadFile(revisionPath) if err != nil { return "" } @@ -125,7 +122,7 @@ func parseModaliasFile(fp string) *deviceModaliasInfo { if _, err := os.Stat(fp); err != nil { return nil } - data, err := ioutil.ReadFile(fp) + data, err := os.ReadFile(fp) if err != nil { return nil } @@ -179,7 +176,7 @@ func parseModaliasData(data string) *deviceModaliasInfo { // pcidb.Vendor struct populated with "unknown" vendor Name attribute and // empty Products attribute. func findPCIVendor(info *Info, vendorID string) *pcidb.Vendor { - vendor := info.Vendors[vendorID] + vendor := info.db.Vendors[vendorID] if vendor == nil { return &pcidb.Vendor{ ID: vendorID, @@ -199,7 +196,7 @@ func findPCIProduct( vendorID string, productID string, ) *pcidb.Product { - product := info.Products[vendorID+productID] + product := info.db.Products[vendorID+productID] if product == nil { return &pcidb.Product{ ID: productID, @@ -221,8 +218,8 @@ func findPCISubsystem( subvendorID string, subproductID string, ) *pcidb.Product { - product := info.Products[vendorID+productID] - subvendor := info.Vendors[subvendorID] + product := info.db.Products[vendorID+productID] + subvendor := info.db.Vendors[subvendorID] if subvendor != nil && product != nil { for _, p := range product.Subsystems { if p.ID == subproductID { @@ -242,7 +239,7 @@ func findPCISubsystem( // pcidb.Class struct populated with "unknown" class Name attribute and // empty Subclasses attribute. func findPCIClass(info *Info, classID string) *pcidb.Class { - class := info.Classes[classID] + class := info.db.Classes[classID] if class == nil { return &pcidb.Class{ ID: classID, @@ -262,7 +259,7 @@ func findPCISubclass( classID string, subclassID string, ) *pcidb.Subclass { - class := info.Classes[classID] + class := info.db.Classes[classID] if class != nil { for _, sc := range class.Subclasses { if sc.ID == subclassID { @@ -346,7 +343,10 @@ func (info *Info) ParseDevice(address, modalias string) *Device { return info.getDeviceFromModaliasInfo(address, modaliasInfo) } -func (info *Info) getDeviceFromModaliasInfo(address string, modaliasInfo *deviceModaliasInfo) *Device { +func (info *Info) getDeviceFromModaliasInfo( + address string, + modaliasInfo *deviceModaliasInfo, +) *Device { vendor := findPCIVendor(info, modaliasInfo.vendorID) product := findPCIProduct( info, @@ -384,18 +384,16 @@ func (info *Info) getDeviceFromModaliasInfo(address string, modaliasInfo *device } } -// ListDevices returns a list of pointers to Device structs present on the +// getDevices returns a list of pointers to Device structs present on the // host system -// DEPRECATED. Will be removed in v1.0. Please use -// github.com/jaypipes/pcidb to explore PCIDB information -func (info *Info) ListDevices() []*Device { +func (info *Info) getDevices() []*Device { paths := linuxpath.New(info.ctx) devs := make([]*Device, 0) // We scan the /sys/bus/pci/devices directory which contains a collection // of symlinks. The names of the symlinks are all the known PCI addresses // for the host. For each address, we grab a *Device matching the // address and append to the returned array. - links, err := ioutil.ReadDir(paths.SysBusPciDevices) + links, err := os.ReadDir(paths.SysBusPciDevices) if err != nil { info.ctx.Warn("failed to read /sys/bus/pci/devices") return nil diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree.go b/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree.go index 519a874d9d..020e7e673f 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree.go +++ b/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree.go @@ -8,7 +8,6 @@ package snapshot import ( "errors" - "io/ioutil" "os" "path/filepath" "strings" @@ -182,7 +181,7 @@ func copyLink(path, targetPath string) error { } func copyPseudoFile(path, targetPath string) error { - buf, err := ioutil.ReadFile(path) + buf, err := os.ReadFile(path) if err != nil { return err } diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_block_linux.go b/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_block_linux.go index 18e2161a4e..f692d41379 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_block_linux.go +++ b/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_block_linux.go @@ -8,7 +8,6 @@ package snapshot import ( "errors" - "io/ioutil" "os" "path/filepath" "strings" @@ -18,7 +17,7 @@ func createBlockDevices(buildDir string) error { // Grab all the block device pseudo-directories from /sys/block symlinks // (excluding loopback devices) and inject them into our build filesystem // with all but the circular symlink'd subsystem directories - devLinks, err := ioutil.ReadDir("/sys/block") + devLinks, err := os.ReadDir("/sys/block") if err != nil { return err } @@ -78,7 +77,7 @@ func createBlockDeviceDir(buildDeviceDir string, srcDeviceDir string) error { // Populate the supplied directory (in our build filesystem) with all the // appropriate information pseudofile contents for the block device. devName := filepath.Base(srcDeviceDir) - devFiles, err := ioutil.ReadDir(srcDeviceDir) + devFiles, err := os.ReadDir(srcDeviceDir) if err != nil { return err } @@ -119,7 +118,7 @@ func createBlockDeviceDir(buildDeviceDir string, srcDeviceDir string) error { // Regular files in the block device directory are both regular and // pseudofiles containing information such as the size (in sectors) // and whether the device is read-only - buf, err := ioutil.ReadFile(fp) + buf, err := os.ReadFile(fp) if err != nil { if errors.Is(err, os.ErrPermission) { // example: /sys/devices/virtual/block/zram0/compact is 0400 @@ -156,7 +155,7 @@ func createBlockDeviceDir(buildDeviceDir string, srcDeviceDir string) error { return err } fp := filepath.Join(srcQueueDir, "rotational") - buf, err := ioutil.ReadFile(fp) + buf, err := os.ReadFile(fp) if err != nil { return err } @@ -177,7 +176,7 @@ func createBlockDeviceDir(buildDeviceDir string, srcDeviceDir string) error { func createPartitionDir(buildPartitionDir string, srcPartitionDir string) error { // Populate the supplied directory (in our build filesystem) with all the // appropriate information pseudofile contents for the partition. - partFiles, err := ioutil.ReadDir(srcPartitionDir) + partFiles, err := os.ReadDir(srcPartitionDir) if err != nil { return err } @@ -201,7 +200,7 @@ func createPartitionDir(buildPartitionDir string, srcPartitionDir string) error // Regular files in the block device directory are both regular and // pseudofiles containing information such as the size (in sectors) // and whether the device is read-only - buf, err := ioutil.ReadFile(fp) + buf, err := os.ReadFile(fp) if err != nil { return err } diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_linux.go b/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_linux.go index 0ccd69350d..68fdecebd7 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_linux.go +++ b/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_linux.go @@ -7,7 +7,6 @@ package snapshot import ( - "io/ioutil" "os" "path/filepath" ) @@ -67,7 +66,7 @@ func cloneContentByClass(devClass string, subEntries []string, filterName filter // warning: don't use the context package here, this means not even the linuxpath package. // TODO(fromani) remove the path duplication sysClass := filepath.Join("sys", "class", devClass) - entries, err := ioutil.ReadDir(sysClass) + entries, err := os.ReadDir(sysClass) if err != nil { // we should not import context, hence we can't Warn() return fileSpecs diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_pci_linux.go b/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_pci_linux.go index dbc3fc83f5..e7aa7d265d 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_pci_linux.go +++ b/vendor/github.com/jaypipes/ghw/pkg/snapshot/clonetree_pci_linux.go @@ -8,7 +8,6 @@ package snapshot import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -70,7 +69,7 @@ func scanPCIDeviceRoot(root string) (fileSpecs []string, pciRoots []string) { "revision", "vendor", } - entries, err := ioutil.ReadDir(root) + entries, err := os.ReadDir(root) if err != nil { return []string{}, []string{} } @@ -124,7 +123,7 @@ func findPCIEntryFromPath(root, entryName string) (string, error) { } func isPCIBridge(entryPath string) bool { - subNodes, err := ioutil.ReadDir(entryPath) + subNodes, err := os.ReadDir(entryPath) if err != nil { // this is so unlikely we don't even return error. But we trace just in case. trace("error scanning device entry path %q: %v", entryPath, err) diff --git a/vendor/github.com/jaypipes/ghw/pkg/snapshot/unpack.go b/vendor/github.com/jaypipes/ghw/pkg/snapshot/unpack.go index 3df395e277..f05f8f79eb 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/snapshot/unpack.go +++ b/vendor/github.com/jaypipes/ghw/pkg/snapshot/unpack.go @@ -10,7 +10,6 @@ import ( "archive/tar" "compress/gzip" "io" - "io/ioutil" "os" "path/filepath" @@ -39,7 +38,7 @@ func Cleanup(targetRoot string) error { // Unpack expands the given snapshot in a temporary directory managed by `ghw`. Returns the path of that directory. func Unpack(snapshotName string) (string, error) { - targetRoot, err := ioutil.TempDir("", TargetRoot) + targetRoot, err := os.MkdirTemp("", TargetRoot) if err != nil { return "", err } @@ -121,7 +120,7 @@ func Untar(root string, r io.Reader) error { } func isEmptyDir(name string) bool { - entries, err := ioutil.ReadDir(name) + entries, err := os.ReadDir(name) if err != nil { return false } diff --git a/vendor/github.com/jaypipes/ghw/pkg/topology/topology_linux.go b/vendor/github.com/jaypipes/ghw/pkg/topology/topology_linux.go index 6844dd9687..9d8434cb7d 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/topology/topology_linux.go +++ b/vendor/github.com/jaypipes/ghw/pkg/topology/topology_linux.go @@ -7,7 +7,7 @@ package topology import ( "fmt" - "io/ioutil" + "os" "path/filepath" "strconv" "strings" @@ -32,7 +32,7 @@ func topologyNodes(ctx *context.Context) []*Node { paths := linuxpath.New(ctx) nodes := make([]*Node, 0) - files, err := ioutil.ReadDir(paths.SysDevicesSystemNode) + files, err := os.ReadDir(paths.SysDevicesSystemNode) if err != nil { ctx.Warn("failed to determine nodes: %s\n", err) return nodes @@ -89,7 +89,7 @@ func distancesForNode(ctx *context.Context, nodeID int) ([]int, error) { "distance", ) - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return nil, err } diff --git a/vendor/github.com/jaypipes/ghw/pkg/util/util.go b/vendor/github.com/jaypipes/ghw/pkg/util/util.go index 5d57bda23b..816aeb1b3d 100644 --- a/vendor/github.com/jaypipes/ghw/pkg/util/util.go +++ b/vendor/github.com/jaypipes/ghw/pkg/util/util.go @@ -8,7 +8,6 @@ package util import ( "fmt" - "io/ioutil" "os" "strconv" "strings" @@ -37,7 +36,7 @@ func SafeClose(c closer) { // message is printed to STDERR and -1 is returned. func SafeIntFromFile(ctx *context.Context, path string) int { msg := "failed to read int from file: %s\n" - buf, err := ioutil.ReadFile(path) + buf, err := os.ReadFile(path) if err != nil { ctx.Warn(msg, err) return -1 diff --git a/vendor/github.com/jaypipes/pcidb/README.md b/vendor/github.com/jaypipes/pcidb/README.md index ddfcde6bf8..27485dca41 100644 --- a/vendor/github.com/jaypipes/pcidb/README.md +++ b/vendor/github.com/jaypipes/pcidb/README.md @@ -1,6 +1,6 @@ # `pcidb` - the Golang PCI DB library -[![Build Status](https://github.com/jaypipes/pcidb/actions/workflows/go.yml/badge.svg?branch=main)](https://github.com/jaypipes/pcidb/actions) +[![Build Status](https://github.com/jaypipes/pcidb/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/jaypipes/pcidb/actions) [![Go Report Card](https://goreportcard.com/badge/github.com/jaypipes/pcidb)](https://goreportcard.com/report/github.com/jaypipes/pcidb) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md) diff --git a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go index 8d35f2d8ae..8a4f49a4c5 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go @@ -1658,7 +1658,10 @@ func addAndResetCounts(hot, cold *histogramCounts) { type nativeExemplars struct { sync.Mutex - ttl time.Duration + // Time-to-live for exemplars, it is set to -1 if exemplars are disabled, that is NativeHistogramMaxExemplars is below 0. + // The ttl is used on insertion to remove an exemplar that is older than ttl, if present. + ttl time.Duration + exemplars []*dto.Exemplar } @@ -1673,6 +1676,7 @@ func makeNativeExemplars(ttl time.Duration, maxCount int) nativeExemplars { if maxCount < 0 { maxCount = 0 + ttl = -1 } return nativeExemplars{ @@ -1682,20 +1686,18 @@ func makeNativeExemplars(ttl time.Duration, maxCount int) nativeExemplars { } func (n *nativeExemplars) addExemplar(e *dto.Exemplar) { - if cap(n.exemplars) == 0 { + if n.ttl == -1 { return } n.Lock() defer n.Unlock() - // The index where to insert the new exemplar. - var nIdx int = -1 - // When the number of exemplars has not yet exceeded or // is equal to cap(n.exemplars), then // insert the new exemplar directly. if len(n.exemplars) < cap(n.exemplars) { + var nIdx int for nIdx = 0; nIdx < len(n.exemplars); nIdx++ { if *e.Value < *n.exemplars[nIdx].Value { break @@ -1705,17 +1707,46 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) { return } + if len(n.exemplars) == 1 { + // When the number of exemplars is 1, then + // replace the existing exemplar with the new exemplar. + n.exemplars[0] = e + return + } + // From this point on, the number of exemplars is greater than 1. + // When the number of exemplars exceeds the limit, remove one exemplar. var ( - rIdx int // The index where to remove the old exemplar. - - ot = time.Now() // Oldest timestamp seen. - otIdx = -1 // Index of the exemplar with the oldest timestamp. - - md = -1.0 // Logarithm of the delta of the closest pair of exemplars. - mdIdx = -1 // Index of the older exemplar within the closest pair. - cLog float64 // Logarithm of the current exemplar. - pLog float64 // Logarithm of the previous exemplar. + ot = time.Time{} // Oldest timestamp seen. Initial value doesn't matter as we replace it due to otIdx == -1 in the loop. + otIdx = -1 // Index of the exemplar with the oldest timestamp. + + md = -1.0 // Logarithm of the delta of the closest pair of exemplars. + + // The insertion point of the new exemplar in the exemplars slice after insertion. + // This is calculated purely based on the order of the exemplars by value. + // nIdx == len(n.exemplars) means the new exemplar is to be inserted after the end. + nIdx = -1 + + // rIdx is ultimately the index for the exemplar that we are replacing with the new exemplar. + // The aim is to keep a good spread of exemplars by value and not let them bunch up too much. + // It is calculated in 3 steps: + // 1. First we set rIdx to the index of the older exemplar within the closest pair by value. + // That is the following will be true (on log scale): + // either the exemplar pair on index (rIdx-1, rIdx) or (rIdx, rIdx+1) will have + // the closest values to each other from all pairs. + // For example, suppose the values are distributed like this: + // |-----------x-------------x----------------x----x-----| + // ^--rIdx as this is older. + // Or like this: + // |-----------x-------------x----------------x----x-----| + // ^--rIdx as this is older. + // 2. If there is an exemplar that expired, then we simple reset rIdx to that index. + // 3. We check if by inserting the new exemplar we would create a closer pair at + // (nIdx-1, nIdx) or (nIdx, nIdx+1) and set rIdx to nIdx-1 or nIdx accordingly to + // keep the spread of exemplars by value; otherwise we keep rIdx as it is. + rIdx = -1 + cLog float64 // Logarithm of the current exemplar. + pLog float64 // Logarithm of the previous exemplar. ) for i, exemplar := range n.exemplars { @@ -1726,7 +1757,7 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) { } // Find the index at which to insert new the exemplar. - if *e.Value <= *exemplar.Value && nIdx == -1 { + if nIdx == -1 && *e.Value <= *exemplar.Value { nIdx = i } @@ -1738,11 +1769,13 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) { } diff := math.Abs(cLog - pLog) if md == -1 || diff < md { + // The closest exemplar pair is at index: i-1, i. + // Choose the exemplar with the older timestamp for replacement. md = diff if n.exemplars[i].Timestamp.AsTime().Before(n.exemplars[i-1].Timestamp.AsTime()) { - mdIdx = i + rIdx = i } else { - mdIdx = i - 1 + rIdx = i - 1 } } @@ -1753,8 +1786,12 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) { if nIdx == -1 { nIdx = len(n.exemplars) } + // Here, we have the following relationships: + // n.exemplars[nIdx-1].Value < e.Value (if nIdx > 0) + // e.Value <= n.exemplars[nIdx].Value (if nIdx < len(n.exemplars)) if otIdx != -1 && e.Timestamp.AsTime().Sub(ot) > n.ttl { + // If the oldest exemplar has expired, then replace it with the new exemplar. rIdx = otIdx } else { // In the previous for loop, when calculating the closest pair of exemplars, @@ -1764,23 +1801,26 @@ func (n *nativeExemplars) addExemplar(e *dto.Exemplar) { if nIdx > 0 { diff := math.Abs(elog - math.Log(n.exemplars[nIdx-1].GetValue())) if diff < md { + // The value we are about to insert is closer to the previous exemplar at the insertion point than what we calculated before in rIdx. + // v--rIdx + // |-----------x-n-----------x----------------x----x-----| + // nIdx-1--^ ^--new exemplar value + // Do not make the spread worse, replace nIdx-1 and not rIdx. md = diff - mdIdx = nIdx - if n.exemplars[nIdx-1].Timestamp.AsTime().Before(e.Timestamp.AsTime()) { - mdIdx = nIdx - 1 - } + rIdx = nIdx - 1 } } if nIdx < len(n.exemplars) { diff := math.Abs(math.Log(n.exemplars[nIdx].GetValue()) - elog) if diff < md { - mdIdx = nIdx - if n.exemplars[nIdx].Timestamp.AsTime().Before(e.Timestamp.AsTime()) { - mdIdx = nIdx - } + // The value we are about to insert is closer to the next exemplar at the insertion point than what we calculated before in rIdx. + // v--rIdx + // |-----------x-----------n-x----------------x----x-----| + // new exemplar value--^ ^--nIdx + // Do not make the spread worse, replace nIdx-1 and not rIdx. + rIdx = nIdx } } - rIdx = mdIdx } // Adjust the slice according to rIdx and nIdx. diff --git a/vendor/golang.org/x/sys/cpu/cpu.go b/vendor/golang.org/x/sys/cpu/cpu.go index ec07aab057..02609d5b21 100644 --- a/vendor/golang.org/x/sys/cpu/cpu.go +++ b/vendor/golang.org/x/sys/cpu/cpu.go @@ -201,6 +201,25 @@ var S390X struct { _ CacheLinePad } +// RISCV64 contains the supported CPU features and performance characteristics for riscv64 +// platforms. The booleans in RISCV64, with the exception of HasFastMisaligned, indicate +// the presence of RISC-V extensions. +// +// It is safe to assume that all the RV64G extensions are supported and so they are omitted from +// this structure. As riscv64 Go programs require at least RV64G, the code that populates +// this structure cannot run successfully if some of the RV64G extensions are missing. +// The struct is padded to avoid false sharing. +var RISCV64 struct { + _ CacheLinePad + HasFastMisaligned bool // Fast misaligned accesses + HasC bool // Compressed instruction-set extension + HasV bool // Vector extension compatible with RVV 1.0 + HasZba bool // Address generation instructions extension + HasZbb bool // Basic bit-manipulation extension + HasZbs bool // Single-bit instructions extension + _ CacheLinePad +} + func init() { archInit() initOptions() diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go b/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go index cd63e73355..7d902b6847 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go +++ b/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build linux && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !s390x +//go:build linux && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !s390x && !riscv64 package cpu diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go b/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go new file mode 100644 index 0000000000..cb4a0c5728 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go @@ -0,0 +1,137 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cpu + +import ( + "syscall" + "unsafe" +) + +// RISC-V extension discovery code for Linux. The approach here is to first try the riscv_hwprobe +// syscall falling back to HWCAP to check for the C extension if riscv_hwprobe is not available. +// +// A note on detection of the Vector extension using HWCAP. +// +// Support for the Vector extension version 1.0 was added to the Linux kernel in release 6.5. +// Support for the riscv_hwprobe syscall was added in 6.4. It follows that if the riscv_hwprobe +// syscall is not available then neither is the Vector extension (which needs kernel support). +// The riscv_hwprobe syscall should then be all we need to detect the Vector extension. +// However, some RISC-V board manufacturers ship boards with an older kernel on top of which +// they have back-ported various versions of the Vector extension patches but not the riscv_hwprobe +// patches. These kernels advertise support for the Vector extension using HWCAP. Falling +// back to HWCAP to detect the Vector extension, if riscv_hwprobe is not available, or simply not +// bothering with riscv_hwprobe at all and just using HWCAP may then seem like an attractive option. +// +// Unfortunately, simply checking the 'V' bit in AT_HWCAP will not work as this bit is used by +// RISC-V board and cloud instance providers to mean different things. The Lichee Pi 4A board +// and the Scaleway RV1 cloud instances use the 'V' bit to advertise their support for the unratified +// 0.7.1 version of the Vector Specification. The Banana Pi BPI-F3 and the CanMV-K230 board use +// it to advertise support for 1.0 of the Vector extension. Versions 0.7.1 and 1.0 of the Vector +// extension are binary incompatible. HWCAP can then not be used in isolation to populate the +// HasV field as this field indicates that the underlying CPU is compatible with RVV 1.0. +// +// There is a way at runtime to distinguish between versions 0.7.1 and 1.0 of the Vector +// specification by issuing a RVV 1.0 vsetvli instruction and checking the vill bit of the vtype +// register. This check would allow us to safely detect version 1.0 of the Vector extension +// with HWCAP, if riscv_hwprobe were not available. However, the check cannot +// be added until the assembler supports the Vector instructions. +// +// Note the riscv_hwprobe syscall does not suffer from these ambiguities by design as all of the +// extensions it advertises support for are explicitly versioned. It's also worth noting that +// the riscv_hwprobe syscall is the only way to detect multi-letter RISC-V extensions, e.g., Zba. +// These cannot be detected using HWCAP and so riscv_hwprobe must be used to detect the majority +// of RISC-V extensions. +// +// Please see https://docs.kernel.org/arch/riscv/hwprobe.html for more information. + +// golang.org/x/sys/cpu is not allowed to depend on golang.org/x/sys/unix so we must +// reproduce the constants, types and functions needed to make the riscv_hwprobe syscall +// here. + +const ( + // Copied from golang.org/x/sys/unix/ztypes_linux_riscv64.go. + riscv_HWPROBE_KEY_IMA_EXT_0 = 0x4 + riscv_HWPROBE_IMA_C = 0x2 + riscv_HWPROBE_IMA_V = 0x4 + riscv_HWPROBE_EXT_ZBA = 0x8 + riscv_HWPROBE_EXT_ZBB = 0x10 + riscv_HWPROBE_EXT_ZBS = 0x20 + riscv_HWPROBE_KEY_CPUPERF_0 = 0x5 + riscv_HWPROBE_MISALIGNED_FAST = 0x3 + riscv_HWPROBE_MISALIGNED_MASK = 0x7 +) + +const ( + // sys_RISCV_HWPROBE is copied from golang.org/x/sys/unix/zsysnum_linux_riscv64.go. + sys_RISCV_HWPROBE = 258 +) + +// riscvHWProbePairs is copied from golang.org/x/sys/unix/ztypes_linux_riscv64.go. +type riscvHWProbePairs struct { + key int64 + value uint64 +} + +const ( + // CPU features + hwcap_RISCV_ISA_C = 1 << ('C' - 'A') +) + +func doinit() { + // A slice of key/value pair structures is passed to the RISCVHWProbe syscall. The key + // field should be initialised with one of the key constants defined above, e.g., + // RISCV_HWPROBE_KEY_IMA_EXT_0. The syscall will set the value field to the appropriate value. + // If the kernel does not recognise a key it will set the key field to -1 and the value field to 0. + + pairs := []riscvHWProbePairs{ + {riscv_HWPROBE_KEY_IMA_EXT_0, 0}, + {riscv_HWPROBE_KEY_CPUPERF_0, 0}, + } + + // This call only indicates that extensions are supported if they are implemented on all cores. + if riscvHWProbe(pairs, 0) { + if pairs[0].key != -1 { + v := uint(pairs[0].value) + RISCV64.HasC = isSet(v, riscv_HWPROBE_IMA_C) + RISCV64.HasV = isSet(v, riscv_HWPROBE_IMA_V) + RISCV64.HasZba = isSet(v, riscv_HWPROBE_EXT_ZBA) + RISCV64.HasZbb = isSet(v, riscv_HWPROBE_EXT_ZBB) + RISCV64.HasZbs = isSet(v, riscv_HWPROBE_EXT_ZBS) + } + if pairs[1].key != -1 { + v := pairs[1].value & riscv_HWPROBE_MISALIGNED_MASK + RISCV64.HasFastMisaligned = v == riscv_HWPROBE_MISALIGNED_FAST + } + } + + // Let's double check with HWCAP if the C extension does not appear to be supported. + // This may happen if we're running on a kernel older than 6.4. + + if !RISCV64.HasC { + RISCV64.HasC = isSet(hwCap, hwcap_RISCV_ISA_C) + } +} + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} + +// riscvHWProbe is a simplified version of the generated wrapper function found in +// golang.org/x/sys/unix/zsyscall_linux_riscv64.go. We simplify it by removing the +// cpuCount and cpus parameters which we do not need. We always want to pass 0 for +// these parameters here so the kernel only reports the extensions that are present +// on all cores. +func riscvHWProbe(pairs []riscvHWProbePairs, flags uint) bool { + var _zero uintptr + var p0 unsafe.Pointer + if len(pairs) > 0 { + p0 = unsafe.Pointer(&pairs[0]) + } else { + p0 = unsafe.Pointer(&_zero) + } + + _, _, e1 := syscall.Syscall6(sys_RISCV_HWPROBE, uintptr(p0), uintptr(len(pairs)), uintptr(0), uintptr(0), uintptr(flags), 0) + return e1 == 0 +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_riscv64.go b/vendor/golang.org/x/sys/cpu/cpu_riscv64.go index 7f0c79c004..aca3199c91 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_riscv64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_riscv64.go @@ -8,4 +8,13 @@ package cpu const cacheLineSize = 64 -func initOptions() {} +func initOptions() { + options = []option{ + {Name: "fastmisaligned", Feature: &RISCV64.HasFastMisaligned}, + {Name: "c", Feature: &RISCV64.HasC}, + {Name: "v", Feature: &RISCV64.HasV}, + {Name: "zba", Feature: &RISCV64.HasZba}, + {Name: "zbb", Feature: &RISCV64.HasZbb}, + {Name: "zbs", Feature: &RISCV64.HasZbs}, + } +} diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index d07dd09eb5..e14b766a32 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -552,6 +552,7 @@ ccflags="$@" $2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ && $2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ || $2 ~ /^SOCK_|SK_DIAG_|SKNLGRP_$/ || + $2 ~ /^(CONNECT|SAE)_/ || $2 ~ /^FIORDCHK$/ || $2 ~ /^SIOC/ || $2 ~ /^TIOC/ || diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 2d15200adb..099867deed 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -566,6 +566,43 @@ func PthreadFchdir(fd int) (err error) { return pthread_fchdir_np(fd) } +// Connectx calls connectx(2) to initiate a connection on a socket. +// +// srcIf, srcAddr, and dstAddr are filled into a [SaEndpoints] struct and passed as the endpoints argument. +// +// - srcIf is the optional source interface index. 0 means unspecified. +// - srcAddr is the optional source address. nil means unspecified. +// - dstAddr is the destination address. +// +// On success, Connectx returns the number of bytes enqueued for transmission. +func Connectx(fd int, srcIf uint32, srcAddr, dstAddr Sockaddr, associd SaeAssocID, flags uint32, iov []Iovec, connid *SaeConnID) (n uintptr, err error) { + endpoints := SaEndpoints{ + Srcif: srcIf, + } + + if srcAddr != nil { + addrp, addrlen, err := srcAddr.sockaddr() + if err != nil { + return 0, err + } + endpoints.Srcaddr = (*RawSockaddr)(addrp) + endpoints.Srcaddrlen = uint32(addrlen) + } + + if dstAddr != nil { + addrp, addrlen, err := dstAddr.sockaddr() + if err != nil { + return 0, err + } + endpoints.Dstaddr = (*RawSockaddr)(addrp) + endpoints.Dstaddrlen = uint32(addrlen) + } + + err = connectx(fd, &endpoints, associd, flags, iov, &n, connid) + return +} + +//sys connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) //sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_hurd.go b/vendor/golang.org/x/sys/unix/syscall_hurd.go index ba46651f8e..a6a2d2fc2b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_hurd.go +++ b/vendor/golang.org/x/sys/unix/syscall_hurd.go @@ -11,6 +11,7 @@ package unix int ioctl(int, unsigned long int, uintptr_t); */ import "C" +import "unsafe" func ioctl(fd int, req uint, arg uintptr) (err error) { r0, er := C.ioctl(C.int(fd), C.ulong(req), C.uintptr_t(arg)) diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go index 4308ac1772..d73c4652e6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go @@ -237,6 +237,9 @@ const ( CLOCK_UPTIME_RAW_APPROX = 0x9 CLONE_NOFOLLOW = 0x1 CLONE_NOOWNERCOPY = 0x2 + CONNECT_DATA_AUTHENTICATED = 0x4 + CONNECT_DATA_IDEMPOTENT = 0x2 + CONNECT_RESUME_ON_READ_WRITE = 0x1 CR0 = 0x0 CR1 = 0x1000 CR2 = 0x2000 @@ -1265,6 +1268,10 @@ const ( RTV_SSTHRESH = 0x20 RUSAGE_CHILDREN = -0x1 RUSAGE_SELF = 0x0 + SAE_ASSOCID_ALL = 0xffffffff + SAE_ASSOCID_ANY = 0x0 + SAE_CONNID_ALL = 0xffffffff + SAE_CONNID_ANY = 0x0 SCM_CREDS = 0x3 SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x2 diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go index c8068a7a16..4a55a40058 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go @@ -237,6 +237,9 @@ const ( CLOCK_UPTIME_RAW_APPROX = 0x9 CLONE_NOFOLLOW = 0x1 CLONE_NOOWNERCOPY = 0x2 + CONNECT_DATA_AUTHENTICATED = 0x4 + CONNECT_DATA_IDEMPOTENT = 0x2 + CONNECT_RESUME_ON_READ_WRITE = 0x1 CR0 = 0x0 CR1 = 0x1000 CR2 = 0x2000 @@ -1265,6 +1268,10 @@ const ( RTV_SSTHRESH = 0x20 RUSAGE_CHILDREN = -0x1 RUSAGE_SELF = 0x0 + SAE_ASSOCID_ALL = 0xffffffff + SAE_ASSOCID_ANY = 0x0 + SAE_CONNID_ALL = 0xffffffff + SAE_CONNID_ANY = 0x0 SCM_CREDS = 0x3 SCM_RIGHTS = 0x1 SCM_TIMESTAMP = 0x2 diff --git a/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go index da08b2ab3d..1ec2b1407b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_zos_s390x.go @@ -581,6 +581,8 @@ const ( AT_EMPTY_PATH = 0x1000 AT_REMOVEDIR = 0x200 RENAME_NOREPLACE = 1 << 0 + ST_RDONLY = 1 + ST_NOSUID = 2 ) const ( diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index b622533ef2..24b346e1a3 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -841,6 +841,26 @@ var libc_pthread_fchdir_np_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) { + var _p0 unsafe.Pointer + if len(iov) > 0 { + _p0 = unsafe.Pointer(&iov[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall9(libc_connectx_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(endpoints)), uintptr(associd), uintptr(flags), uintptr(_p0), uintptr(len(iov)), uintptr(unsafe.Pointer(n)), uintptr(unsafe.Pointer(connid)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_connectx_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_connectx connectx "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { _, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s index cfe6646baf..ebd213100b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s @@ -248,6 +248,11 @@ TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8 DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB) +TEXT libc_connectx_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_connectx(SB) +GLOBL ·libc_connectx_trampoline_addr(SB), RODATA, $8 +DATA ·libc_connectx_trampoline_addr(SB)/8, $libc_connectx_trampoline<>(SB) + TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendfile(SB) GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index 13f624f69f..824b9c2d5e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -841,6 +841,26 @@ var libc_pthread_fchdir_np_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func connectx(fd int, endpoints *SaEndpoints, associd SaeAssocID, flags uint32, iov []Iovec, n *uintptr, connid *SaeConnID) (err error) { + var _p0 unsafe.Pointer + if len(iov) > 0 { + _p0 = unsafe.Pointer(&iov[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall9(libc_connectx_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(endpoints)), uintptr(associd), uintptr(flags), uintptr(_p0), uintptr(len(iov)), uintptr(unsafe.Pointer(n)), uintptr(unsafe.Pointer(connid)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_connectx_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_connectx connectx "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { _, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s index fe222b75df..4f178a2293 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s @@ -248,6 +248,11 @@ TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8 DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB) +TEXT libc_connectx_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_connectx(SB) +GLOBL ·libc_connectx_trampoline_addr(SB), RODATA, $8 +DATA ·libc_connectx_trampoline_addr(SB)/8, $libc_connectx_trampoline<>(SB) + TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendfile(SB) GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index 091d107f3a..d003c3d437 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -306,6 +306,19 @@ type XVSockPgen struct { type _Socklen uint32 +type SaeAssocID uint32 + +type SaeConnID uint32 + +type SaEndpoints struct { + Srcif uint32 + Srcaddr *RawSockaddr + Srcaddrlen uint32 + Dstaddr *RawSockaddr + Dstaddrlen uint32 + _ [4]byte +} + type Xucred struct { Version uint32 Uid uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go index 28ff4ef74d..0d45a941aa 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go @@ -306,6 +306,19 @@ type XVSockPgen struct { type _Socklen uint32 +type SaeAssocID uint32 + +type SaeConnID uint32 + +type SaEndpoints struct { + Srcif uint32 + Srcaddr *RawSockaddr + Srcaddrlen uint32 + Dstaddr *RawSockaddr + Dstaddrlen uint32 + _ [4]byte +} + type Xucred struct { Version uint32 Uid uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go index 6cbd094a3a..51e13eb055 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go @@ -625,6 +625,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go index 7c03b6ee77..d002d8ef3c 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go @@ -630,6 +630,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go index 422107ee8b..3f863d898d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go @@ -616,6 +616,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go index 505a12acfd..61c7293106 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go @@ -610,6 +610,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go index cc986c7900..b5d17414f0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go @@ -612,6 +612,7 @@ const ( POLLRDNORM = 0x40 POLLWRBAND = 0x100 POLLWRNORM = 0x4 + POLLRDHUP = 0x4000 ) type CapRights struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 7f1961b907..9f2550dc31 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -2486,7 +2486,7 @@ type XDPMmapOffsets struct { type XDPUmemReg struct { Addr uint64 Len uint64 - Chunk_size uint32 + Size uint32 Headroom uint32 Flags uint32 Tx_metadata_len uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index 15adc04142..ad05b51a60 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -727,6 +727,37 @@ const ( RISCV_HWPROBE_EXT_ZBA = 0x8 RISCV_HWPROBE_EXT_ZBB = 0x10 RISCV_HWPROBE_EXT_ZBS = 0x20 + RISCV_HWPROBE_EXT_ZICBOZ = 0x40 + RISCV_HWPROBE_EXT_ZBC = 0x80 + RISCV_HWPROBE_EXT_ZBKB = 0x100 + RISCV_HWPROBE_EXT_ZBKC = 0x200 + RISCV_HWPROBE_EXT_ZBKX = 0x400 + RISCV_HWPROBE_EXT_ZKND = 0x800 + RISCV_HWPROBE_EXT_ZKNE = 0x1000 + RISCV_HWPROBE_EXT_ZKNH = 0x2000 + RISCV_HWPROBE_EXT_ZKSED = 0x4000 + RISCV_HWPROBE_EXT_ZKSH = 0x8000 + RISCV_HWPROBE_EXT_ZKT = 0x10000 + RISCV_HWPROBE_EXT_ZVBB = 0x20000 + RISCV_HWPROBE_EXT_ZVBC = 0x40000 + RISCV_HWPROBE_EXT_ZVKB = 0x80000 + RISCV_HWPROBE_EXT_ZVKG = 0x100000 + RISCV_HWPROBE_EXT_ZVKNED = 0x200000 + RISCV_HWPROBE_EXT_ZVKNHA = 0x400000 + RISCV_HWPROBE_EXT_ZVKNHB = 0x800000 + RISCV_HWPROBE_EXT_ZVKSED = 0x1000000 + RISCV_HWPROBE_EXT_ZVKSH = 0x2000000 + RISCV_HWPROBE_EXT_ZVKT = 0x4000000 + RISCV_HWPROBE_EXT_ZFH = 0x8000000 + RISCV_HWPROBE_EXT_ZFHMIN = 0x10000000 + RISCV_HWPROBE_EXT_ZIHINTNTL = 0x20000000 + RISCV_HWPROBE_EXT_ZVFH = 0x40000000 + RISCV_HWPROBE_EXT_ZVFHMIN = 0x80000000 + RISCV_HWPROBE_EXT_ZFA = 0x100000000 + RISCV_HWPROBE_EXT_ZTSO = 0x200000000 + RISCV_HWPROBE_EXT_ZACAS = 0x400000000 + RISCV_HWPROBE_EXT_ZICOND = 0x800000000 + RISCV_HWPROBE_EXT_ZIHINTPAUSE = 0x1000000000 RISCV_HWPROBE_KEY_CPUPERF_0 = 0x5 RISCV_HWPROBE_MISALIGNED_UNKNOWN = 0x0 RISCV_HWPROBE_MISALIGNED_EMULATED = 0x1 @@ -734,4 +765,6 @@ const ( RISCV_HWPROBE_MISALIGNED_FAST = 0x3 RISCV_HWPROBE_MISALIGNED_UNSUPPORTED = 0x4 RISCV_HWPROBE_MISALIGNED_MASK = 0x7 + RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE = 0x6 + RISCV_HWPROBE_WHICH_CPUS = 0x1 ) diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 1fa34fd17c..5cee9a3143 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -313,6 +313,10 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode //sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo //sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition +//sys GetConsoleCP() (cp uint32, err error) = kernel32.GetConsoleCP +//sys GetConsoleOutputCP() (cp uint32, err error) = kernel32.GetConsoleOutputCP +//sys SetConsoleCP(cp uint32) (err error) = kernel32.SetConsoleCP +//sys SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP //sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW //sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW //sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 3f03b3d57c..7b97a154c9 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -1060,6 +1060,7 @@ const ( SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6 SIO_KEEPALIVE_VALS = IOC_IN | IOC_VENDOR | 4 SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12 + SIO_UDP_NETRESET = IOC_IN | IOC_VENDOR | 15 // cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460 diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 9bb979a3e4..4c2e1bdc01 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -247,7 +247,9 @@ var ( procGetCommandLineW = modkernel32.NewProc("GetCommandLineW") procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") procGetComputerNameW = modkernel32.NewProc("GetComputerNameW") + procGetConsoleCP = modkernel32.NewProc("GetConsoleCP") procGetConsoleMode = modkernel32.NewProc("GetConsoleMode") + procGetConsoleOutputCP = modkernel32.NewProc("GetConsoleOutputCP") procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo") procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW") procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId") @@ -347,8 +349,10 @@ var ( procSetCommMask = modkernel32.NewProc("SetCommMask") procSetCommState = modkernel32.NewProc("SetCommState") procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts") + procSetConsoleCP = modkernel32.NewProc("SetConsoleCP") procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition") procSetConsoleMode = modkernel32.NewProc("SetConsoleMode") + procSetConsoleOutputCP = modkernel32.NewProc("SetConsoleOutputCP") procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW") procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories") procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW") @@ -2162,6 +2166,15 @@ func GetComputerName(buf *uint16, n *uint32) (err error) { return } +func GetConsoleCP() (cp uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0) + cp = uint32(r0) + if cp == 0 { + err = errnoErr(e1) + } + return +} + func GetConsoleMode(console Handle, mode *uint32) (err error) { r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0) if r1 == 0 { @@ -2170,6 +2183,15 @@ func GetConsoleMode(console Handle, mode *uint32) (err error) { return } +func GetConsoleOutputCP() (cp uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetConsoleOutputCP.Addr(), 0, 0, 0, 0) + cp = uint32(r0) + if cp == 0 { + err = errnoErr(e1) + } + return +} + func GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) { r1, _, e1 := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(info)), 0) if r1 == 0 { @@ -3038,6 +3060,14 @@ func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { return } +func SetConsoleCP(cp uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetConsoleCP.Addr(), 1, uintptr(cp), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func setConsoleCursorPosition(console Handle, position uint32) (err error) { r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0) if r1 == 0 { @@ -3054,6 +3084,14 @@ func SetConsoleMode(console Handle, mode uint32) (err error) { return } +func SetConsoleOutputCP(cp uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetConsoleOutputCP.Addr(), 1, uintptr(cp), 0, 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func SetCurrentDirectory(path *uint16) (err error) { r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) if r1 == 0 { diff --git a/vendor/modules.txt b/vendor/modules.txt index 52b0992458..1120e7363b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -55,9 +55,6 @@ github.com/digitalocean/go-libvirt/socket/dialers ## explicit; go 1.13 github.com/emicklei/go-restful/v3 github.com/emicklei/go-restful/v3/log -# github.com/ghodss/yaml v1.0.0 -## explicit -github.com/ghodss/yaml # github.com/go-logr/logr v1.4.2 ## explicit; go 1.18 github.com/go-logr/logr @@ -127,8 +124,8 @@ github.com/grafana/regexp/syntax # github.com/imdario/mergo v0.3.16 ## explicit; go 1.13 github.com/imdario/mergo -# github.com/jaypipes/ghw v0.12.0 -## explicit; go 1.18 +# github.com/jaypipes/ghw v0.13.0 +## explicit; go 1.21 github.com/jaypipes/ghw github.com/jaypipes/ghw/pkg/baseboard github.com/jaypipes/ghw/pkg/bios @@ -150,8 +147,8 @@ github.com/jaypipes/ghw/pkg/snapshot github.com/jaypipes/ghw/pkg/topology github.com/jaypipes/ghw/pkg/unitutil github.com/jaypipes/ghw/pkg/util -# github.com/jaypipes/pcidb v1.0.0 -## explicit; go 1.17 +# github.com/jaypipes/pcidb v1.0.1 +## explicit; go 1.21 github.com/jaypipes/pcidb # github.com/joho/godotenv v1.5.1 ## explicit; go 1.12 @@ -243,7 +240,7 @@ github.com/pkg/errors # github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 ## explicit github.com/pmezard/go-difflib/difflib -# github.com/prometheus/client_golang v1.20.2 +# github.com/prometheus/client_golang v1.20.3 ## explicit; go 1.20 github.com/prometheus/client_golang/api github.com/prometheus/client_golang/api/prometheus/v1 @@ -327,7 +324,7 @@ golang.org/x/net/proxy ## explicit; go 1.18 golang.org/x/oauth2 golang.org/x/oauth2/internal -# golang.org/x/sys v0.24.0 +# golang.org/x/sys v0.25.0 ## explicit; go 1.18 golang.org/x/sys/cpu golang.org/x/sys/plan9 @@ -413,7 +410,7 @@ gopkg.in/yaml.v3 # howett.net/plist v1.0.0 ## explicit; go 1.12 howett.net/plist -# k8s.io/api v0.29.8 +# k8s.io/api v0.29.9 ## explicit; go 1.21 k8s.io/api/admissionregistration/v1 k8s.io/api/admissionregistration/v1alpha1 @@ -467,7 +464,7 @@ k8s.io/api/scheduling/v1beta1 k8s.io/api/storage/v1 k8s.io/api/storage/v1alpha1 k8s.io/api/storage/v1beta1 -# k8s.io/apimachinery v0.29.8 +# k8s.io/apimachinery v0.29.9 ## explicit; go 1.21 k8s.io/apimachinery/pkg/api/equality k8s.io/apimachinery/pkg/api/errors @@ -518,7 +515,7 @@ k8s.io/apimachinery/pkg/version k8s.io/apimachinery/pkg/watch k8s.io/apimachinery/third_party/forked/golang/netutil k8s.io/apimachinery/third_party/forked/golang/reflect -# k8s.io/client-go v0.29.8 +# k8s.io/client-go v0.29.9 ## explicit; go 1.21 k8s.io/client-go/applyconfigurations/admissionregistration/v1 k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1