├── .changelog ├── 172.txt ├── 175.txt ├── 180.txt ├── 183.txt ├── 184.txt ├── 185.txt ├── 186.txt ├── 188.txt ├── 195.txt ├── 199.txt ├── 200.txt ├── 201.txt ├── 214.txt ├── 215.txt ├── 217.txt ├── 220.txt ├── 223.txt ├── 226.txt ├── 231.txt ├── 234.txt ├── 246.txt ├── 248.txt ├── 252.txt ├── 255.txt ├── 258.txt └── 259.txt ├── .ci ├── release │ ├── changelog.gotmpl │ └── release-note.gotmpl └── scripts │ ├── check-changelog.sh │ ├── check-cross-compile.sh │ ├── test.bat │ └── test.sh ├── .editorconfig ├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── changelog.yml │ ├── go.yml │ └── release.yml ├── .gitignore ├── .golangci.yml ├── CONTRIBUTING.md ├── LICENSE.txt ├── Makefile ├── NOTICE.txt ├── README.md ├── go.mod ├── go.sum ├── internal └── registry │ └── registry.go ├── providers ├── aix │ ├── boottime_aix_ppc64.go │ ├── boottime_aix_ppc64_test.go │ ├── defs_aix.go │ ├── doc.go │ ├── host_aix_ppc64.go │ ├── kernel_aix_ppc64.go │ ├── machineid_aix_ppc64.go │ ├── os_aix_ppc64.go │ ├── process_aix_ppc64.go │ ├── testdata │ │ └── utmp │ └── ztypes_aix_ppc64.go ├── darwin │ ├── arch_darwin.go │ ├── arch_darwin_test.go │ ├── boottime_darwin.go │ ├── boottime_darwin_test.go │ ├── defs_darwin.go │ ├── doc.go │ ├── host_darwin.go │ ├── host_darwin_test.go │ ├── kernel_darwin.go │ ├── load_average_darwin.go │ ├── load_average_darwin_test.go │ ├── machineid_darwin.go │ ├── machineid_nocgo_darwin.go │ ├── memory_darwin.go │ ├── memory_darwin_test.go │ ├── os_darwin.go │ ├── os_darwin_test.go │ ├── process_cgo_darwin.go │ ├── process_darwin.go │ ├── process_darwin_test.go │ ├── process_nocgo_darwin.go │ ├── syscall_cgo_darwin.go │ ├── syscall_darwin.go │ ├── syscall_nocgo_darwin.go │ └── ztypes_darwin.go ├── linux │ ├── arch_linux.go │ ├── arch_linux_test.go │ ├── boottime_linux.go │ ├── capabilities_linux.go │ ├── container.go │ ├── container_test.go │ ├── doc.go │ ├── host_fqdn_integration_docker_linux_test.go │ ├── host_fqdn_integration_linux_test.go │ ├── host_linux.go │ ├── host_linux_test.go │ ├── kernel_linux.go │ ├── machineid.go │ ├── machineid_test.go │ ├── memory_linux.go │ ├── os.go │ ├── os_test.go │ ├── process_linux.go │ ├── process_linux_test.go │ ├── procnet.go │ ├── procnet_test.go │ ├── seccomp_linux.go │ ├── testdata │ │ ├── almalinux10 │ │ │ ├── etc │ │ │ │ ├── almalinux-release │ │ │ │ ├── os-release │ │ │ │ ├── redhat-release │ │ │ │ └── system-release │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ ├── almalinux9 │ │ │ ├── etc │ │ │ │ ├── almalinux-release │ │ │ │ ├── os-release │ │ │ │ ├── redhat-release │ │ │ │ └── system-release │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ ├── alpine3.17 │ │ │ └── etc │ │ │ │ ├── alpine-release │ │ │ │ └── os-release │ │ ├── amazon2017.03 │ │ │ └── etc │ │ │ │ ├── os-release │ │ │ │ └── system-release │ │ ├── archlinux │ │ │ ├── etc │ │ │ │ ├── arch-release │ │ │ │ └── os-release │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ ├── centos6 │ │ │ └── etc │ │ │ │ ├── centos-release │ │ │ │ ├── redhat-release │ │ │ │ └── system-release │ │ ├── centos7.8 │ │ │ ├── etc │ │ │ │ ├── centos-release │ │ │ │ ├── os-release │ │ │ │ ├── redhat-release │ │ │ │ └── system-release │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ ├── centos7 │ │ │ └── etc │ │ │ │ ├── centos-release │ │ │ │ ├── os-release │ │ │ │ ├── redhat-release │ │ │ │ └── system-release │ │ ├── debian6 │ │ │ └── etc │ │ │ │ └── debian_version │ │ ├── debian9 │ │ │ ├── etc │ │ │ │ ├── debian_version │ │ │ │ └── os-release │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ ├── dir_release │ │ │ └── etc │ │ │ │ ├── aaa-release │ │ │ │ └── .dir │ │ │ │ ├── centos-release │ │ │ │ ├── os-release │ │ │ │ ├── redhat-release │ │ │ │ └── system-release │ │ ├── fedora30 │ │ │ ├── etc │ │ │ │ ├── fedora-release │ │ │ │ ├── machine-id │ │ │ │ ├── os-release │ │ │ │ ├── redhat-release │ │ │ │ └── system-release │ │ │ ├── proc │ │ │ │ ├── net │ │ │ │ │ ├── netstat │ │ │ │ │ └── snmp │ │ │ │ └── stat │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ ├── fedora-release │ │ │ │ ├── os-release │ │ │ │ ├── redhat-release │ │ │ │ └── system-release │ │ ├── fedora40 │ │ │ └── proc │ │ │ │ └── 33925 │ │ │ │ └── stat │ │ ├── linuxmint20 │ │ │ ├── etc │ │ │ │ ├── lsb-release │ │ │ │ └── os-release │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ ├── manjaro23 │ │ │ ├── etc │ │ │ │ ├── arch-release │ │ │ │ ├── lsb-release │ │ │ │ └── os-release │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ ├── openeuler20.03 │ │ │ └── etc │ │ │ │ ├── openEuler-release │ │ │ │ ├── os-release │ │ │ │ └── system-release │ │ ├── opensuse-leap15.4 │ │ │ ├── etc │ │ │ │ └── os-release │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ ├── opensuse-tumbleweed │ │ │ ├── etc │ │ │ │ └── os-release │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ ├── oraclelinux7 │ │ │ └── etc │ │ │ │ ├── oracle-release │ │ │ │ ├── os-release │ │ │ │ ├── redhat-release │ │ │ │ └── system-release │ │ ├── raspbian9 │ │ │ ├── etc │ │ │ │ ├── debian_version │ │ │ │ └── os-release │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ ├── redhat10 │ │ │ ├── etc │ │ │ │ ├── os-release │ │ │ │ ├── redhat-release │ │ │ │ └── system-release │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ ├── redhat7 │ │ │ └── etc │ │ │ │ ├── os-release │ │ │ │ ├── redhat-release │ │ │ │ └── system-release │ │ ├── redhat9 │ │ │ ├── etc │ │ │ │ ├── os-release │ │ │ │ ├── redhat-release │ │ │ │ └── system-release │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ ├── rockylinux9 │ │ │ ├── etc │ │ │ │ ├── os-release │ │ │ │ ├── redhat-release │ │ │ │ ├── rocky-release │ │ │ │ └── system-release │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ ├── sled15sp5 │ │ │ └── etc │ │ │ │ └── os-release │ │ ├── sles15sp5 │ │ │ └── etc │ │ │ │ └── os-release │ │ ├── ubuntu1204 │ │ │ └── etc │ │ │ │ ├── lsb-release │ │ │ │ └── os-release │ │ ├── ubuntu1404 │ │ │ └── etc │ │ │ │ ├── debian_version │ │ │ │ ├── lsb-release │ │ │ │ └── os-release │ │ ├── ubuntu1710 │ │ │ ├── etc │ │ │ │ ├── debian_version │ │ │ │ ├── lsb-release │ │ │ │ └── os-release │ │ │ ├── proc │ │ │ │ ├── loadavg │ │ │ │ ├── meminfo │ │ │ │ ├── stat │ │ │ │ └── vmstat │ │ │ └── usr │ │ │ │ └── lib │ │ │ │ └── os-release │ │ └── ubuntu2204 │ │ │ ├── etc │ │ │ ├── lsb-release │ │ │ └── os-release │ │ │ └── usr │ │ │ └── lib │ │ │ └── os-release │ ├── util.go │ ├── util_test.go │ ├── vmstat.go │ └── vmstat_test.go ├── shared │ ├── fqdn.go │ ├── fqdn_test.go │ └── network.go └── windows │ ├── arch_windows.go │ ├── arch_windows_test.go │ ├── boottime_windows.go │ ├── boottime_windows_test.go │ ├── device_windows.go │ ├── device_windows_test.go │ ├── doc.go │ ├── helpers_windows.go │ ├── host_windows.go │ ├── host_windows_test.go │ ├── kernel_windows.go │ ├── machineid_windows.go │ ├── os_windows.go │ ├── os_windows_test.go │ ├── process_windows.go │ └── process_windows_test.go ├── system.go ├── system_test.go └── types ├── errors.go ├── go.go ├── host.go └── process.go /.changelog/172.txt: -------------------------------------------------------------------------------- 1 | ```release-note:bug 2 | darwin: Prevent possible runtime panic while reading process arguments. 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/175.txt: -------------------------------------------------------------------------------- 1 | ```release-note:bug 2 | windows: On versions earlier than 10/2016, the `os.major` version was getting overwritten with 3 | what would have been the minor version, and the `os.minor` version was not being set. 4 | ``` 5 | -------------------------------------------------------------------------------- /.changelog/180.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | Lowercase the returned OS.Hostname and FQDN values as per Elastic 3 | Common Schema (ECS) guidelines for the `host.name` field. 4 | ``` 5 | -------------------------------------------------------------------------------- /.changelog/183.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | linux: Added an `os.Family` mapping for Arch Linux based distributions. 3 | ``` 4 | 5 | ```release-note:bug 6 | linux: Fix OS metadata collection for Manjaro Linux. 7 | ``` 8 | -------------------------------------------------------------------------------- /.changelog/184.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | linux: Update the Linux capability name mapping to add names for the 3 | `perfmon`, `bpf`, and `checkpoint_restore` capabilities. 4 | ``` 5 | -------------------------------------------------------------------------------- /.changelog/185.txt: -------------------------------------------------------------------------------- 1 | ```release-note:bug 2 | aix: Added missing method FQDN for types.Host implementation. 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/186.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | linux: optimize linux key value parsing (ie: /proc files) 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/188.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | aix: Added mappings for AIX host memory information 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/195.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | darwin: Remove duplicate `-lproc` linker flag to avoid a warning on macOS Sonoma. 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/199.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | Allow FQDN lookup functions to take a context. 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/200.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | Adds NativeArchitecture to HostInfo to allow applications to detect whether they are running in emulation. 3 | ``` -------------------------------------------------------------------------------- /.changelog/201.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | HostInfo.NativeArchitecture is not available on Windows system prior Windows 10 version 1709. 3 | ``` -------------------------------------------------------------------------------- /.changelog/214.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | build: Require Go 1.21 for the module. 3 | ``` 4 | 5 | ```release-note:enhancement 6 | docs: Add policy of supporting the two most recent Go releases. 7 | ``` 8 | -------------------------------------------------------------------------------- /.changelog/215.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | Refactor the Linux FQDN test cases to remove the dependency on github.com/docker/docker. 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/217.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | Replace usages of github.com/joeshaw/multierror with the stdlib errors.Join(). This may affect the rendering of some error messages. 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/220.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | Replace usages of the deprecated io/ioutil package. 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/223.txt: -------------------------------------------------------------------------------- 1 | ```release-note:bug 2 | linux: Remove newline from HostInfo.NativeArchitecture value. 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/226.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | The sysinfo APIs (e.g. `Host()`, `Process()`) now accept an optional argument to force reading from an alternative filesystem root. This can be useful inside of containers to read data from the Linux host. 3 | ``` -------------------------------------------------------------------------------- /.changelog/231.txt: -------------------------------------------------------------------------------- 1 | ```release-note:breaking-change 2 | `Host.FQDNWithContext()` and the deprecated `Host.FQDN()` now return the FQDN as is; it isn't lowercased anymore. This also affects `types.HostInfo#Hostname` which, when it's the FQDN, won't be lowercased. 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/234.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | linux: Add alpine family to OSInfo 3 | ``` -------------------------------------------------------------------------------- /.changelog/246.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | Fetch all IP addresses in a single stdlib call 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/248.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | linux: Support SLES/SLED OS version extraction. 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/252.txt: -------------------------------------------------------------------------------- 1 | ```release-note:bug 2 | linux: Improve parsing Linux kernel version for determining native host architecture, x86_64 was not recognized 3 | ``` -------------------------------------------------------------------------------- /.changelog/255.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | Bump go-windows to 1.0.2 3 | ``` -------------------------------------------------------------------------------- /.changelog/258.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | linux: Add test case to validate OS metadata can be collected from Red Hat Enterprise Linux 10. 3 | ``` 4 | -------------------------------------------------------------------------------- /.changelog/259.txt: -------------------------------------------------------------------------------- 1 | ```release-note:enhancement 2 | linux: Add test case to validate OS metadata can be collected from AlmaLinux 10. 3 | ``` 4 | -------------------------------------------------------------------------------- /.ci/release/changelog.gotmpl: -------------------------------------------------------------------------------- 1 | {{- if .NotesByType.note -}} 2 | NOTES: 3 | {{range .NotesByType.note -}} 4 | * {{ template "note" .}} 5 | {{ end -}} 6 | {{- end -}} 7 | 8 | {{- if .NotesByType.deprecation -}} 9 | DEPRECATIONS: 10 | {{range .NotesByType.deprecation -}} 11 | * {{ template "note" .}} 12 | {{ end -}} 13 | {{- end -}} 14 | 15 | {{- if index .NotesByType "breaking-change" -}} 16 | BREAKING CHANGES: 17 | {{range index .NotesByType "breaking-change" -}} 18 | * {{ template "note" .}} 19 | {{ end -}} 20 | {{- end -}} 21 | 22 | {{- $features := combineTypes .NotesByType.feature (index .NotesByType "new-resource" ) (index .NotesByType "new-datasource") (index .NotesByType "new-data-source") -}} 23 | {{- if $features }} 24 | FEATURES: 25 | {{range $features | sort -}} 26 | * {{ template "note" . }} 27 | {{ end -}} 28 | {{- end -}} 29 | 30 | {{- $improvements := combineTypes .NotesByType.improvement .NotesByType.enhancement -}} 31 | {{- if $improvements }} 32 | IMPROVEMENTS: 33 | {{range $improvements | sort -}} 34 | * {{ template "note" . }} 35 | {{ end -}} 36 | {{- end -}} 37 | 38 | {{- if .NotesByType.bug }} 39 | BUG FIXES: 40 | {{range .NotesByType.bug -}} 41 | * {{ template "note" . }} 42 | {{ end -}} 43 | {{- end -}} 44 | -------------------------------------------------------------------------------- /.ci/release/release-note.gotmpl: -------------------------------------------------------------------------------- 1 | {{- define "note" -}} 2 | {{if eq "new-resource" .Type}}**New Resource:** {{else if eq "new-datasource" .Type}}**New Data Source:** {{ end }}{{.Body}} ([GH-{{- .Issue -}}]) 3 | {{- end -}} 4 | -------------------------------------------------------------------------------- /.ci/scripts/check-changelog.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -uo pipefail 3 | 4 | if [[ -z "${PR_NUMBER}" ]]; then 5 | echo "PR_NUMBER must be set." 6 | exit 1 7 | fi 8 | 9 | if [[ -z "${BASE_REF}" ]]; then 10 | echo "BASE_REF must be set." 11 | exit 1 12 | fi 13 | 14 | docs_url="https://github.com/GoogleCloudPlatform/magic-modules/blob/2834761fec3acbf35cacbffe100530f82eada650/.ci/RELEASE_NOTES_GUIDE.md#expected-format" 15 | 16 | # Version of https://github.com/hashicorp/go-changelog. 17 | go_changelog_version=ba40b3a 18 | go_changelog_check="go run github.com/hashicorp/go-changelog/cmd/changelog-check@${go_changelog_version}" 19 | 20 | expected_changelog_file=.changelog/${PR_NUMBER}.txt 21 | 22 | # Verify file is present. 23 | if [ ! -e "${expected_changelog_file}" ]; then 24 | echo "Changelog file missing at ${expected_changelog_file}. 25 | 26 | Please add a changelog entry following the format described [here](${docs_url}). 27 | 28 | If this change does not require a changelog entry then label the pull request 29 | with skip-changelog. 30 | " >> $GITHUB_STEP_SUMMARY 31 | exit 1 32 | fi 33 | 34 | # Check the format. 35 | if ! ${go_changelog_check} "${expected_changelog_file}"; then 36 | echo "Changelog format is invalid. See build log." >> $GITHUB_STEP_SUMMARY 37 | exit 1 38 | fi 39 | 40 | echo "Changelog is valid." >> $GITHUB_STEP_SUMMARY 41 | -------------------------------------------------------------------------------- /.ci/scripts/check-cross-compile.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -xeuo pipefail 3 | 4 | export CGO_ENABLED=0 5 | 6 | # Test that there are no compilation issues when not using CGO. This does 7 | # not imply that all of these targets are supported without CGO. It's only 8 | # a sanity check for build tag issues. 9 | GOOS=aix GOARCH=ppc64 go build ./... 10 | GOOS=darwin GOARCH=amd64 go build ./... 11 | GOOS=darwin GOARCH=arm64 go build ./... 12 | GOOS=linux GOARCH=386 go build ./... 13 | GOOS=linux GOARCH=amd64 go build ./... 14 | GOOS=linux GOARCH=arm go build ./... 15 | GOOS=linux GOARCH=arm64 go build ./... 16 | GOOS=linux GOARCH=mips go build ./... 17 | GOOS=linux GOARCH=mips64 go build ./... 18 | GOOS=linux GOARCH=mips64le go build ./... 19 | GOOS=linux GOARCH=mipsle go build ./... 20 | GOOS=linux GOARCH=ppc64 go build ./... 21 | GOOS=linux GOARCH=ppc64le go build ./... 22 | GOOS=linux GOARCH=riscv64 go build ./... 23 | GOOS=linux GOARCH=s390x go build ./... 24 | GOOS=windows GOARCH=amd64 go build ./... 25 | GOOS=windows GOARCH=arm go build ./... 26 | GOOS=windows GOARCH=arm64 go build ./... 27 | -------------------------------------------------------------------------------- /.ci/scripts/test.bat: -------------------------------------------------------------------------------- 1 | go install gotest.tools/gotestsum@latest 2 | 3 | mkdir -p build 4 | SET OUT_FILE=build\output-report.out 5 | gotestsum --format testname --junitfile build\junit-%GO_VERSION%.xml -- ./... 6 | -------------------------------------------------------------------------------- /.ci/scripts/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euxo pipefail 3 | 4 | go install gotest.tools/gotestsum@latest 5 | 6 | # Run the tests 7 | export OUT_FILE="build/test-report.out" 8 | mkdir -p build 9 | gotestsum --format testname --junitfile "build/junit-${GO_VERSION}.xml" -- -tags integration ./... 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # See: http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.json] 11 | indent_size = 2 12 | indent_style = space 13 | 14 | [*.py] 15 | indent_style = space 16 | indent_size = 4 17 | 18 | [*.yml] 19 | indent_style = space 20 | indent_size = 2 21 | 22 | [Makefile] 23 | indent_style = tab 24 | 25 | [Vagrantfile] 26 | indent_size = 2 27 | indent_style = space 28 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Treat all files in the Go repo as binary, with no git magic updating 2 | # line endings. Windows users contributing to Go will need to use a 3 | # modern version of git and editors capable of LF line endings. 4 | 5 | * -text 6 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Maintain dependencies for GitHub Actions (/.github/workflows) 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | day: "sunday" 9 | time: "22:00" 10 | reviewers: 11 | - "elastic/observablt-ci" 12 | labels: 13 | - dependencies 14 | - skip-changelog 15 | groups: 16 | github-actions: 17 | patterns: 18 | - "*" 19 | -------------------------------------------------------------------------------- /.github/workflows/changelog.yml: -------------------------------------------------------------------------------- 1 | name: changelog 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize, labeled, unlabeled] 6 | branches: 7 | - main 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | check: 14 | if: "!contains(github.event.pull_request.labels.*.name, 'skip-changelog')" 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | - name: changelog 20 | env: 21 | PR_NUMBER: ${{ github.event.pull_request.number }} 22 | BASE_REF: ${{ github.event.pull_request.base.ref }} 23 | run: .ci/scripts/check-changelog.sh 24 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: go 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | 9 | permissions: 10 | contents: read 11 | 12 | env: 13 | # Use the local toolchain. Never download. 14 | GOTOOLCHAIN: local 15 | 16 | jobs: 17 | check: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v4 21 | 22 | - uses: actions/setup-go@v5 23 | with: 24 | go-version: 1.23.x 25 | 26 | - name: go.mod tidy 27 | run: go mod tidy && git diff --exit-code 28 | 29 | - name: license header 30 | run: go run github.com/elastic/go-licenser@v0.4.1 -d 31 | 32 | - name: cross-compile 33 | run: .ci/scripts/check-cross-compile.sh 34 | 35 | test: 36 | needs: check 37 | strategy: 38 | matrix: 39 | go: 40 | - 1.23.x 41 | - 1.22.x 42 | os: 43 | - macos-13 44 | - macos-14 45 | - macos-15 46 | - windows-2019 47 | - windows-2022 48 | - ubuntu-22.04 49 | - ubuntu-24.04 50 | cgo: 51 | - cgo 52 | - nocgo 53 | exclude: 54 | # Exclude cgo testing for platforms that don't use CGO. 55 | - {cgo: cgo, os: windows-2019} 56 | - {cgo: cgo, os: windows-2022} 57 | - {cgo: cgo, os: ubuntu-22.04} 58 | - {cgo: cgo, os: ubuntu-24.04} 59 | # Limit the OS variants tested with the earliest supported Go version (save resources). 60 | - {go: 1.22.x, os: macos-13} 61 | - {go: 1.22.x, os: macos-14} 62 | - {go: 1.22.x, os: windows-2019} 63 | - {go: 1.22.x, os: ubuntu-22.04} 64 | runs-on: ${{ matrix.os }} 65 | steps: 66 | - uses: actions/checkout@v4 67 | 68 | - uses: actions/setup-go@v5 69 | id: setup_go 70 | with: 71 | go-version: ${{ matrix.go }} 72 | 73 | - name: Set GO_VERSION 74 | run: echo "GO_VERSION=${{ steps.setup_go.outputs.go-version }}" >> $GITHUB_ENV 75 | 76 | - name: Set CGO_ENABLED=1 77 | if: matrix.cgo == 'cgo' 78 | run: echo "CGO_ENABLED=1" >> $GITHUB_ENV 79 | 80 | - name: Set CGO_ENABLED=0 81 | if: matrix.cgo == 'nocgo' 82 | run: echo "CGO_ENABLED=0" >> $GITHUB_ENV 83 | 84 | - name: golangci-lint 85 | uses: golangci/golangci-lint-action@v6 86 | if: github.event_name == 'pull_request' 87 | with: 88 | version: latest 89 | only-new-issues: true 90 | args: --timeout=5m 91 | # Don't cache or restore ~/go/pkg. It conflicts with caching from setup-go@v4. 92 | skip-pkg-cache: true 93 | 94 | - name: Test 95 | if: runner.os != 'Windows' 96 | run: .ci/scripts/test.sh 97 | 98 | - name: Test 99 | if: runner.os == 'Windows' 100 | run: .ci/scripts/test.bat 101 | 102 | test-freebsd: 103 | runs-on: ubuntu-latest 104 | env: 105 | # Only GITHUB_* are passed into the VM. 106 | GITHUB_GOLANG_VERSION: 1.23.0 107 | name: test (1.23.0, freebsd-14.0, cgo) 108 | steps: 109 | - uses: actions/checkout@v4 110 | 111 | - name: Test 112 | # TODO: Skip until freebsd provider is merged. Then this 'if' should be removed. 113 | if: ${{ hashFiles('providers/freebsd/') != '' }} 114 | id: test 115 | uses: vmactions/freebsd-vm@8873d98fd1413b5977cb2f7348fe329775159892 #v1.1.9 116 | with: 117 | usesh: true 118 | prepare: | 119 | freebsd-version 120 | pwd 121 | ls -lah 122 | whoami 123 | 124 | pkg install -y curl 125 | curl -sL -o /usr/bin/gvm https://github.com/andrewkroh/gvm/releases/download/v0.5.2/gvm-freebsd-amd64 126 | chmod +x /usr/bin/gvm 127 | eval "$(gvm ${GITHUB_GOLANG_VERSION})" 128 | go version 129 | 130 | run: | 131 | eval "$(gvm ${GITHUB_GOLANG_VERSION})" 132 | go test -v ./... 133 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | version: 7 | description: Tag name (e.g. v1.2.3) for this version (does not need to exist). 8 | required: true 9 | type: string 10 | last_release: 11 | description: Last release tag. 12 | required: true 13 | type: string 14 | 15 | permissions: 16 | contents: read 17 | 18 | jobs: 19 | draft: 20 | permissions: 21 | contents: write 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | with: 26 | fetch-depth: 0 # Need full history. 27 | 28 | - name: release notes 29 | run: >- 30 | go run github.com/hashicorp/go-changelog/cmd/changelog-build@ba40b3a 31 | -changelog-template .ci/release/changelog.gotmpl 32 | -note-template .ci/release/release-note.gotmpl 33 | -entries-dir ./.changelog 34 | -last-release "${{ inputs.last_release }}" 35 | -this-release HEAD | tee /tmp/release-notes.txt 36 | 37 | - name: draft GH release 38 | env: 39 | GH_TOKEN: ${{ github.token }} 40 | run: >- 41 | gh release create "${{ inputs.version }}" 42 | --draft 43 | --notes-file /tmp/release-notes.txt 44 | --title "${{ inputs.version }}" 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | *.swp 3 | *.o 4 | .idea 5 | .vagrant 6 | _obj 7 | 8 | *TEST.out 9 | 10 | build/ 11 | **/testdata/fuzz 12 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | run: 4 | issues-exit-code: 1 5 | modules-download-mode: readonly 6 | 7 | linters: 8 | disable-all: true 9 | fast: false 10 | enable: 11 | - goimports 12 | - revive 13 | 14 | linters-settings: 15 | goimports: 16 | local-prefixes: github.com/elastic/go-sysinfo 17 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Pull requests are welcomed. You must 4 | 5 | - Sign the Elastic [Contributor License Agreement](https://www.elastic.co/contributor-agreement). 6 | - Include a [changelog][changelog_docs] entry at `.changelog/{pr-number}.txt` with your pull request. 7 | - Include tests that demonstrate the change is working. 8 | 9 | [changelog_docs]: https://github.com/GoogleCloudPlatform/magic-modules/blob/2834761fec3acbf35cacbffe100530f82eada650/.ci/RELEASE_NOTES_GUIDE.md#expected-format 10 | 11 | ## Releasing 12 | 13 | To create a new release use the release workflow in GitHub actions. This will create a new draft 14 | release in GitHub releases with a changelog. After the job completes, review the draft and if 15 | everything is correct, publish the release. When the release is published GitHub will create the 16 | git tag. 17 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .phony: update 2 | update: fmt lic imports 3 | 4 | .PHONY: lic 5 | lic: 6 | go run github.com/elastic/go-licenser@latest 7 | 8 | .PHONY: fmt 9 | fmt: 10 | go run mvdan.cc/gofumpt@latest -w -l ./ 11 | 12 | .PHONY: imports 13 | imports: 14 | go run golang.org/x/tools/cmd/goimports@latest -l -local github.com/elastic/go-sysinfo ./ 15 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Elastic go-sysinfo 2 | Copyright 2017-2024 Elasticsearch B.V. 3 | 4 | This product includes software developed at 5 | Elasticsearch, B.V. (https://www.elastic.co/). 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-sysinfo 2 | 3 | [![go](https://github.com/elastic/go-sysinfo/actions/workflows/go.yml/badge.svg)](https://github.com/elastic/go-sysinfo/actions/workflows/go.yml) 4 | [![Go Documentation](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][godocs] 5 | 6 | [godocs]: http://godoc.org/github.com/elastic/go-sysinfo 7 | 8 | go-sysinfo is a library for collecting system information. This includes 9 | information about the host machine and processes running on the host. 10 | 11 | The available features vary based on what has been implemented by the "provider" 12 | for the operating system. At runtime you check to see if additional interfaces 13 | are implemented by the returned `Host` or `Process`. For example: 14 | 15 | ```go 16 | process, err := sysinfo.Self() 17 | if err != nil { 18 | return err 19 | } 20 | 21 | if handleCounter, ok := process.(types.OpenHandleCounter); ok { 22 | count, err := handleCounter.OpenHandleCount() 23 | if err != nil { 24 | return err 25 | } 26 | log.Printf("%d open handles", count) 27 | } 28 | ``` 29 | 30 | These tables show what methods are implemented as well as the extra interfaces 31 | that are implemented. 32 | 33 | | `Host` Features | Darwin | Linux | Windows | AIX | 34 | |------------------|--------|-------|---------|-----| 35 | | `Info()` | x | x | x | x | 36 | | `Memory()` | x | x | x | x | 37 | | `CPUTimer` | x | x | x | x | 38 | | `LoadAverage` | x | x | | | 39 | | `VMStat` | | x | | | 40 | | `NetworkCounters`| | x | | | 41 | 42 | | `Process` Features | Darwin | Linux | Windows | AIX | 43 | |------------------------|--------|-------|---------|-----| 44 | | `Info()` | x | x | x | x | 45 | | `Memory()` | x | x | x | x | 46 | | `User()` | x | x | x | x | 47 | | `Parent()` | x | x | x | x | 48 | | `CPUTimer` | x | x | x | x | 49 | | `Environment` | x | x | | x | 50 | | `OpenHandleEnumerator` | | x | | | 51 | | `OpenHandleCounter` | | x | | | 52 | | `Seccomp` | | x | | | 53 | | `Capabilities` | | x | | | 54 | | `NetworkCounters` | | x | | | 55 | 56 | ### GOOS / GOARCH Pairs 57 | 58 | This table lists the OS and architectures for which a "provider" is implemented. 59 | 60 | | GOOS / GOARCH | Requires CGO | Tested | 61 | |----------------|--------------|--------| 62 | | aix/ppc64 | x | | 63 | | darwin/amd64 | optional * | x | 64 | | darwin/arm64 | optional * | x | 65 | | linux/386 | | | 66 | | linux/amd64 | | x | 67 | | linux/arm | | | 68 | | linux/arm64 | | | 69 | | linux/mips | | | 70 | | linux/mips64 | | | 71 | | linux/mips64le | | | 72 | | linux/mipsle | | | 73 | | linux/ppc64 | | | 74 | | linux/ppc64le | | | 75 | | linux/riscv64 | | | 76 | | linux/s390x | | | 77 | | windows/amd64 | | x | 78 | | windows/arm64 | | | 79 | | windows/arm | | | 80 | 81 | * On darwin (macOS) host information like machineid and process information like memory, cpu, user and starttime require cgo. 82 | 83 | ### Supported Go versions 84 | 85 | go-sysinfo supports the [two most recent Go releases][ci_go_versions]. 86 | 87 | [ci_go_versions]: https://github.com/elastic/go-sysinfo/blob/main/.github/workflows/go.yml#L40-L41 88 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/elastic/go-sysinfo 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/elastic/go-windows v1.0.2 7 | github.com/prometheus/procfs v0.15.1 8 | github.com/stretchr/testify v1.9.0 9 | golang.org/x/sys v0.25.0 10 | howett.net/plist v0.0.0-20181124034731-591f970eefbb 11 | ) 12 | 13 | require ( 14 | github.com/davecgh/go-spew v1.1.1 // indirect 15 | github.com/pmezard/go-difflib v1.0.0 // indirect 16 | gopkg.in/yaml.v3 v3.0.1 // indirect 17 | ) 18 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/elastic/go-windows v1.0.2 h1:yoLLsAsV5cfg9FLhZ9EXZ2n2sQFKeDYrHenkcivY4vI= 4 | github.com/elastic/go-windows v1.0.2/go.mod h1:bGcDpBzXgYSqM0Gx3DM4+UxFj300SZLixie9u9ixLM8= 5 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 6 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 7 | github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 8 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 9 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 10 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 11 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 12 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 13 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 14 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 15 | github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= 16 | github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= 17 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 18 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 19 | golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= 20 | golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 21 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 22 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 23 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 24 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 25 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 26 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 27 | howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= 28 | howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= 29 | -------------------------------------------------------------------------------- /internal/registry/registry.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package registry 19 | 20 | import ( 21 | "fmt" 22 | 23 | "github.com/elastic/go-sysinfo/types" 24 | ) 25 | 26 | type ( 27 | HostOptsCreator = func(ProviderOptions) HostProvider 28 | ProcessOptsCreator = func(ProviderOptions) ProcessProvider 29 | ) 30 | 31 | // HostProvider defines interfaces that provide host-specific metrics 32 | type HostProvider interface { 33 | Host() (types.Host, error) 34 | } 35 | 36 | // ProcessProvider defines interfaces that provide process-specific metrics 37 | type ProcessProvider interface { 38 | Processes() ([]types.Process, error) 39 | Process(pid int) (types.Process, error) 40 | Self() (types.Process, error) 41 | } 42 | 43 | type ProviderOptions struct { 44 | Hostfs string 45 | } 46 | 47 | var ( 48 | hostProvider HostProvider 49 | processProvider ProcessProvider 50 | processProviderWithOpts ProcessOptsCreator 51 | hostProviderWithOpts HostOptsCreator 52 | ) 53 | 54 | // Register a metrics provider. `provider` should implement one or more of `ProcessProvider` or `HostProvider` 55 | func Register(provider interface{}) { 56 | if h, ok := provider.(ProcessOptsCreator); ok { 57 | if processProviderWithOpts != nil { 58 | panic(fmt.Sprintf("ProcessOptsCreator already registered: %T", processProviderWithOpts)) 59 | } 60 | processProviderWithOpts = h 61 | } 62 | 63 | if h, ok := provider.(HostOptsCreator); ok { 64 | if hostProviderWithOpts != nil { 65 | panic(fmt.Sprintf("HostOptsCreator already registered: %T", hostProviderWithOpts)) 66 | } 67 | hostProviderWithOpts = h 68 | } 69 | 70 | if h, ok := provider.(HostProvider); ok { 71 | if hostProvider != nil { 72 | panic(fmt.Sprintf("HostProvider already registered: %v", hostProvider)) 73 | } 74 | hostProvider = h 75 | } 76 | 77 | if p, ok := provider.(ProcessProvider); ok { 78 | if processProvider != nil { 79 | panic(fmt.Sprintf("ProcessProvider already registered: %v", processProvider)) 80 | } 81 | processProvider = p 82 | } 83 | } 84 | 85 | // GetHostProvider returns the HostProvider registered for the system. May return nil. 86 | func GetHostProvider(opts ProviderOptions) HostProvider { 87 | if hostProviderWithOpts != nil { 88 | return hostProviderWithOpts(opts) 89 | } 90 | return hostProvider 91 | } 92 | 93 | // GetProcessProvider returns the ProcessProvider registered on the system. May return nil. 94 | func GetProcessProvider(opts ProviderOptions) ProcessProvider { 95 | if processProviderWithOpts != nil { 96 | return processProviderWithOpts(opts) 97 | } 98 | return processProvider 99 | } 100 | -------------------------------------------------------------------------------- /providers/aix/boottime_aix_ppc64.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build aix && ppc64 19 | 20 | package aix 21 | 22 | import ( 23 | "encoding/binary" 24 | "fmt" 25 | "os" 26 | "time" 27 | ) 28 | 29 | // utmp can't be used by "encoding/binary" if generated by cgo, 30 | // some pads will be missing. 31 | type utmp struct { 32 | User [256]uint8 33 | Id [14]uint8 34 | Line [64]uint8 35 | XPad1 int16 36 | Pid int32 37 | Type int16 38 | XPad2 int16 39 | Time int64 40 | Termination int16 41 | Exit int16 42 | Host [256]uint8 43 | Xdblwordpad int32 44 | XreservedA [2]int32 45 | XreservedV [6]int32 46 | } 47 | 48 | const ( 49 | typeBootTime = 2 50 | ) 51 | 52 | // BootTime returns the time at which the machine was started, truncated to the nearest second 53 | func BootTime() (time.Time, error) { 54 | return bootTime("/etc/utmp") 55 | } 56 | 57 | func bootTime(filename string) (time.Time, error) { 58 | // Get boot time from /etc/utmp 59 | file, err := os.Open(filename) 60 | if err != nil { 61 | return time.Time{}, fmt.Errorf("failed to get host uptime: cannot open /etc/utmp: %w", err) 62 | } 63 | 64 | defer file.Close() 65 | 66 | for { 67 | var utmp utmp 68 | if err := binary.Read(file, binary.BigEndian, &utmp); err != nil { 69 | break 70 | } 71 | 72 | if utmp.Type == typeBootTime { 73 | return time.Unix(utmp.Time, 0), nil 74 | } 75 | } 76 | 77 | return time.Time{}, fmt.Errorf("failed to get host uptime: no utmp record: %w", err) 78 | } 79 | -------------------------------------------------------------------------------- /providers/aix/boottime_aix_ppc64_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build aix && ppc64 19 | 20 | package aix 21 | 22 | import ( 23 | "testing" 24 | 25 | "github.com/stretchr/testify/assert" 26 | ) 27 | 28 | func TestBootTime(t *testing.T) { 29 | bt, err := bootTime("testdata/utmp") 30 | if err != nil { 31 | t.Fatal(err) 32 | } 33 | 34 | assert.EqualValues(t, bt.Unix(), 1585726535) 35 | } 36 | -------------------------------------------------------------------------------- /providers/aix/defs_aix.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build ignore 19 | 20 | package aix 21 | 22 | /* 23 | #include 24 | #include 25 | #include 26 | */ 27 | import "C" 28 | 29 | type prcred C.prcred_t 30 | 31 | type ( 32 | pstatus C.pstatus_t 33 | prTimestruc64 C.pr_timestruc64_t 34 | prSigset C.pr_sigset_t 35 | fltset C.fltset_t 36 | lwpstatus C.lwpstatus_t 37 | prSiginfo64 C.pr_siginfo64_t 38 | prStack64 C.pr_stack64_t 39 | prSigaction64 C.struct_pr_sigaction64 40 | prgregset C.prgregset_t 41 | prfpregset C.prfpregset_t 42 | pfamily C.pfamily_t 43 | ) 44 | -------------------------------------------------------------------------------- /providers/aix/doc.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | // Package aix implements the HostProvider and ProcessProvider interfaces 19 | // for providing information about IBM AIX on ppc64. 20 | package aix 21 | -------------------------------------------------------------------------------- /providers/aix/kernel_aix_ppc64.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build aix && ppc64 && cgo 19 | 20 | package aix 21 | 22 | /* 23 | #include 24 | */ 25 | import "C" 26 | 27 | import ( 28 | "fmt" 29 | "strconv" 30 | ) 31 | 32 | var oslevel string 33 | 34 | func getKernelVersion() (int, int, error) { 35 | name := C.struct_utsname{} 36 | if _, err := C.uname(&name); err != nil { 37 | return 0, 0, fmt.Errorf("kernel version: uname: %w", err) 38 | } 39 | 40 | version, err := strconv.Atoi(C.GoString(&name.version[0])) 41 | if err != nil { 42 | return 0, 0, fmt.Errorf("parsing kernel version: %w", err) 43 | } 44 | 45 | release, err := strconv.Atoi(C.GoString(&name.release[0])) 46 | if err != nil { 47 | return 0, 0, fmt.Errorf("parsing kernel release: %w", err) 48 | } 49 | return version, release, nil 50 | } 51 | 52 | // KernelVersion returns the version of AIX kernel 53 | func KernelVersion() (string, error) { 54 | major, minor, err := getKernelVersion() 55 | if err != nil { 56 | return "", err 57 | } 58 | return strconv.Itoa(major) + "." + strconv.Itoa(minor), nil 59 | } 60 | -------------------------------------------------------------------------------- /providers/aix/machineid_aix_ppc64.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build aix && ppc64 && cgo 19 | 20 | package aix 21 | 22 | /* 23 | #include 24 | */ 25 | import "C" 26 | 27 | import "fmt" 28 | 29 | // MachineID returns the id of the machine 30 | func MachineID() (string, error) { 31 | name := C.struct_utsname{} 32 | if _, err := C.uname(&name); err != nil { 33 | return "", fmt.Errorf("machine id: %w", err) 34 | } 35 | return C.GoString(&name.machine[0]), nil 36 | } 37 | -------------------------------------------------------------------------------- /providers/aix/os_aix_ppc64.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build aix && ppc64 && cgo 19 | 20 | package aix 21 | 22 | import ( 23 | "fmt" 24 | "os" 25 | "strconv" 26 | "strings" 27 | 28 | "github.com/elastic/go-sysinfo/types" 29 | ) 30 | 31 | // OperatingSystem returns information of the host operating system 32 | func OperatingSystem() (*types.OSInfo, error) { 33 | return getOSInfo() 34 | } 35 | 36 | func getOSInfo() (*types.OSInfo, error) { 37 | major, minor, err := getKernelVersion() 38 | if err != nil { 39 | return nil, err 40 | } 41 | 42 | // Retrieve build version from "/proc/version". 43 | procVersion, err := os.ReadFile("/proc/version") 44 | if err != nil { 45 | return nil, fmt.Errorf("failed to get OS info: cannot open /proc/version: %w", err) 46 | } 47 | build := strings.SplitN(string(procVersion), "\n", 4)[2] 48 | 49 | return &types.OSInfo{ 50 | Type: "unix", 51 | Family: "aix", 52 | Platform: "aix", 53 | Name: "aix", 54 | Version: strconv.Itoa(major) + "." + strconv.Itoa(minor), 55 | Major: major, 56 | Minor: minor, 57 | Patch: 0, // No patch version 58 | Build: build, 59 | }, nil 60 | } 61 | -------------------------------------------------------------------------------- /providers/aix/testdata/utmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/go-sysinfo/4f2a4c67e96568b6f10a07ba716a19f05d72e13a/providers/aix/testdata/utmp -------------------------------------------------------------------------------- /providers/aix/ztypes_aix_ppc64.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | // Code generated by cmd/cgo -godefs; DO NOT EDIT. 19 | // cgo -godefs defs_aix.go 20 | 21 | //go:build aix && ppc64 22 | 23 | package aix 24 | 25 | type prcred struct { 26 | Euid uint64 27 | Ruid uint64 28 | Suid uint64 29 | Egid uint64 30 | Rgid uint64 31 | Sgid uint64 32 | X_pad [8]uint64 33 | X_pad1 uint32 34 | Ngroups uint32 35 | Groups [1]uint64 36 | } 37 | 38 | type pstatus struct { 39 | Flag uint32 40 | Flag2 uint32 41 | Flags uint32 42 | Nlwp uint32 43 | Stat uint8 44 | Dmodel uint8 45 | X_pad1 [6]uint8 46 | Sigpend prSigset 47 | Brkbase uint64 48 | Brksize uint64 49 | Stkbase uint64 50 | Stksize uint64 51 | Pid uint64 52 | Ppid uint64 53 | Pgid uint64 54 | Sid uint64 55 | Utime prTimestruc64 56 | Stime prTimestruc64 57 | Cutime prTimestruc64 58 | Cstime prTimestruc64 59 | Sigtrace prSigset 60 | Flttrace fltset 61 | Sysentry_offset uint32 62 | Sysexit_offset uint32 63 | X_pad [8]uint64 64 | Lwp lwpstatus 65 | } 66 | 67 | type prTimestruc64 struct { 68 | Sec int64 69 | Nsec int32 70 | X__pad uint32 71 | } 72 | 73 | type prSigset struct { 74 | Set [4]uint64 75 | } 76 | 77 | type fltset struct { 78 | Set [4]uint64 79 | } 80 | 81 | type lwpstatus struct { 82 | Lwpid uint64 83 | Flags uint32 84 | X_pad1 [1]uint8 85 | State uint8 86 | Cursig uint16 87 | Why uint16 88 | What uint16 89 | Policy uint32 90 | Clname [8]uint8 91 | Lwppend prSigset 92 | Lwphold prSigset 93 | Info prSiginfo64 94 | Altstack prStack64 95 | Action prSigaction64 96 | X_pad2 uint32 97 | Syscall uint16 98 | Nsysarg uint16 99 | Sysarg [8]uint64 100 | Errno int32 101 | Ptid uint32 102 | X_pad [9]uint64 103 | Reg prgregset 104 | Fpreg prfpregset 105 | Family pfamily 106 | } 107 | 108 | type prSiginfo64 struct { 109 | Signo int32 110 | Errno int32 111 | Code int32 112 | Imm int32 113 | Status int32 114 | X__pad1 uint32 115 | Uid uint64 116 | Pid uint64 117 | Addr uint64 118 | Band int64 119 | Value [8]byte 120 | X__pad [4]uint32 121 | } 122 | 123 | type prStack64 struct { 124 | Sp uint64 125 | Size uint64 126 | Flags int32 127 | X__pad [5]int32 128 | } 129 | 130 | type prSigaction64 struct { 131 | Union [8]byte 132 | Mask prSigset 133 | Flags int32 134 | X__pad [5]int32 135 | } 136 | 137 | type prgregset struct { 138 | X__iar uint64 139 | X__msr uint64 140 | X__cr uint64 141 | X__lr uint64 142 | X__ctr uint64 143 | X__xer uint64 144 | X__fpscr uint64 145 | X__fpscrx uint64 146 | X__gpr [32]uint64 147 | X__pad1 [8]uint64 148 | } 149 | 150 | type prfpregset struct { 151 | X__fpr [32]float64 152 | } 153 | 154 | type pfamily struct { 155 | Extoff uint64 156 | Extsize uint64 157 | Pad [14]uint64 158 | } 159 | -------------------------------------------------------------------------------- /providers/darwin/arch_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build amd64 || arm64 19 | 20 | package darwin 21 | 22 | import ( 23 | "fmt" 24 | "os" 25 | 26 | "golang.org/x/sys/unix" 27 | ) 28 | 29 | const ( 30 | hardwareMIB = "hw.machine" 31 | procTranslated = "sysctl.proc_translated" 32 | archIntel = "x86_64" 33 | archApple = "arm64" 34 | ) 35 | 36 | func Architecture() (string, error) { 37 | arch, err := unix.Sysctl(hardwareMIB) 38 | if err != nil { 39 | return "", fmt.Errorf("failed to get architecture: %w", err) 40 | } 41 | 42 | return arch, nil 43 | } 44 | 45 | func NativeArchitecture() (string, error) { 46 | processArch, err := Architecture() 47 | if err != nil { 48 | return "", err 49 | } 50 | 51 | // https://developer.apple.com/documentation/apple-silicon/about-the-rosetta-translation-environment 52 | 53 | translated, err := unix.SysctlUint32(procTranslated) 54 | if err != nil { 55 | // macos without Rosetta installed doesn't have sysctl.proc_translated 56 | if os.IsNotExist(err) { 57 | return processArch, nil 58 | } 59 | return "", fmt.Errorf("failed to read sysctl.proc_translated: %w", err) 60 | } 61 | 62 | var nativeArch string 63 | 64 | switch translated { 65 | case 0: 66 | nativeArch = processArch 67 | case 1: 68 | // Rosetta 2 is supported only on Apple silicon 69 | nativeArch = archApple 70 | } 71 | 72 | return nativeArch, nil 73 | } 74 | -------------------------------------------------------------------------------- /providers/darwin/arch_darwin_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package darwin 19 | 20 | import ( 21 | "testing" 22 | 23 | "github.com/stretchr/testify/assert" 24 | ) 25 | 26 | func TestArchitecture(t *testing.T) { 27 | a, err := Architecture() 28 | assert.NoError(t, err) 29 | assert.NotEmpty(t, a) 30 | } 31 | 32 | func TestNativeArchitecture(t *testing.T) { 33 | a, err := NativeArchitecture() 34 | assert.NoError(t, err) 35 | assert.NotEmpty(t, a) 36 | } 37 | -------------------------------------------------------------------------------- /providers/darwin/boottime_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build amd64 || arm64 19 | 20 | package darwin 21 | 22 | import ( 23 | "fmt" 24 | "time" 25 | 26 | "golang.org/x/sys/unix" 27 | ) 28 | 29 | const kernBoottimeMIB = "kern.boottime" 30 | 31 | func BootTime() (time.Time, error) { 32 | tv, err := unix.SysctlTimeval(kernBoottimeMIB) 33 | if err != nil { 34 | return time.Time{}, fmt.Errorf("failed to get host uptime: %w", err) 35 | } 36 | 37 | bootTime := time.Unix(int64(tv.Sec), int64(tv.Usec)*int64(time.Microsecond)) 38 | return bootTime, nil 39 | } 40 | -------------------------------------------------------------------------------- /providers/darwin/boottime_darwin_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package darwin 19 | 20 | import ( 21 | "testing" 22 | "time" 23 | 24 | "github.com/stretchr/testify/assert" 25 | ) 26 | 27 | func TestBootTime(t *testing.T) { 28 | bt, err := BootTime() 29 | assert.NoError(t, err) 30 | 31 | t.Logf(bt.Format(time.RFC1123)) 32 | } 33 | -------------------------------------------------------------------------------- /providers/darwin/defs_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build ignore 19 | 20 | package darwin 21 | 22 | /* 23 | #include 24 | #include 25 | */ 26 | import "C" 27 | 28 | type processState uint32 29 | 30 | const ( 31 | stateSIDL processState = iota + 1 32 | stateRun 33 | stateSleep 34 | stateStop 35 | stateZombie 36 | ) 37 | 38 | const argMax = C.ARG_MAX 39 | 40 | type bsdInfo C.struct_proc_bsdinfo 41 | 42 | type procTaskInfo C.struct_proc_taskinfo 43 | 44 | type procTaskAllInfo C.struct_proc_taskallinfo 45 | 46 | type vinfoStat C.struct_vinfo_stat 47 | 48 | type fsid C.struct_fsid 49 | 50 | type vnodeInfo C.struct_vnode_info 51 | 52 | type vnodeInfoPath C.struct_vnode_info_path 53 | 54 | type procVnodePathInfo C.struct_proc_vnodepathinfo 55 | 56 | type vmStatisticsData C.vm_statistics_data_t 57 | 58 | type vmStatistics64Data C.vm_statistics64_data_t 59 | 60 | type vmSize C.vm_size_t 61 | 62 | const ( 63 | cpuStateUser = C.CPU_STATE_USER 64 | cpuStateSystem = C.CPU_STATE_SYSTEM 65 | cpuStateIdle = C.CPU_STATE_IDLE 66 | cpuStateNice = C.CPU_STATE_NICE 67 | ) 68 | 69 | type hostCPULoadInfo C.host_cpu_load_info_data_t 70 | -------------------------------------------------------------------------------- /providers/darwin/doc.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | // Package darwin implements the HostProvider and ProcessProvider interfaces 19 | // for providing information about MacOS. 20 | package darwin 21 | -------------------------------------------------------------------------------- /providers/darwin/host_darwin_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build amd64 || arm64 19 | 20 | package darwin 21 | 22 | import ( 23 | "encoding/json" 24 | "testing" 25 | 26 | "github.com/elastic/go-sysinfo/internal/registry" 27 | ) 28 | 29 | var _ registry.HostProvider = darwinSystem{} 30 | 31 | func TestHost(t *testing.T) { 32 | host, err := darwinSystem{}.Host() 33 | if err != nil { 34 | t.Logf("could not get all host info: %v\n", err) 35 | } 36 | 37 | info := host.Info() 38 | data, _ := json.MarshalIndent(info, "", " ") 39 | t.Logf(string(data)) 40 | } 41 | -------------------------------------------------------------------------------- /providers/darwin/kernel_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build !386 19 | 20 | package darwin 21 | 22 | import ( 23 | "fmt" 24 | "syscall" 25 | ) 26 | 27 | const kernelReleaseMIB = "kern.osrelease" 28 | 29 | func KernelVersion() (string, error) { 30 | version, err := syscall.Sysctl(kernelReleaseMIB) 31 | if err != nil { 32 | return "", fmt.Errorf("failed to get kernel version: %w", err) 33 | } 34 | 35 | return version, nil 36 | } 37 | -------------------------------------------------------------------------------- /providers/darwin/load_average_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build amd64 || arm64 19 | 20 | package darwin 21 | 22 | import ( 23 | "unsafe" 24 | 25 | "golang.org/x/sys/unix" 26 | ) 27 | 28 | const loadAverage = "vm.loadavg" 29 | 30 | type loadAvg struct { 31 | load [3]uint32 32 | scale int 33 | } 34 | 35 | func getLoadAverage() (*loadAvg, error) { 36 | data, err := unix.SysctlRaw(loadAverage) 37 | if err != nil { 38 | return nil, err 39 | } 40 | 41 | load := *(*loadAvg)(unsafe.Pointer((&data[0]))) 42 | 43 | return &load, nil 44 | } 45 | -------------------------------------------------------------------------------- /providers/darwin/load_average_darwin_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package darwin 19 | 20 | import ( 21 | "testing" 22 | 23 | "github.com/stretchr/testify/assert" 24 | ) 25 | 26 | func TestGetLoadAverage(t *testing.T) { 27 | a, err := getLoadAverage() 28 | assert.NoError(t, err) 29 | assert.NotEmpty(t, a) 30 | } 31 | -------------------------------------------------------------------------------- /providers/darwin/machineid_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build (amd64 && cgo) || (arm64 && cgo) 19 | 20 | package darwin 21 | 22 | // #include 23 | // #include 24 | import "C" 25 | 26 | import ( 27 | "fmt" 28 | "unsafe" 29 | ) 30 | 31 | // MachineID returns the Hardware UUID also accessible via 32 | // About this Mac -> System Report and as the field 33 | // IOPlatformUUID in the output of "ioreg -d2 -c IOPlatformExpertDevice". 34 | func MachineID() (string, error) { 35 | return getHostUUID() 36 | } 37 | 38 | func getHostUUID() (string, error) { 39 | var uuidC C.uuid_t 40 | var id [unsafe.Sizeof(uuidC)]C.uchar 41 | wait := C.struct_timespec{5, 0} // 5 seconds 42 | 43 | ret, err := C.gethostuuid(&id[0], &wait) 44 | if ret != 0 { 45 | if err != nil { 46 | return "", fmt.Errorf("gethostuuid failed with %v: %w", ret, err) 47 | } 48 | 49 | return "", fmt.Errorf("gethostuuid failed with %v", ret) 50 | } 51 | 52 | var uuidStringC C.uuid_string_t 53 | var uuid [unsafe.Sizeof(uuidStringC)]C.char 54 | _, err = C.uuid_unparse_upper(&id[0], &uuid[0]) 55 | if err != nil { 56 | return "", fmt.Errorf("uuid_unparse_upper failed: %w", err) 57 | } 58 | 59 | return C.GoString(&uuid[0]), nil 60 | } 61 | -------------------------------------------------------------------------------- /providers/darwin/machineid_nocgo_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build (amd64 && !cgo) || (arm64 && !cgo) 19 | 20 | package darwin 21 | 22 | import ( 23 | "fmt" 24 | 25 | "github.com/elastic/go-sysinfo/types" 26 | ) 27 | 28 | func MachineID() (string, error) { 29 | return "", fmt.Errorf("machineid requires cgo: %w", types.ErrNotImplemented) 30 | } 31 | -------------------------------------------------------------------------------- /providers/darwin/memory_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build amd64 || arm64 19 | 20 | package darwin 21 | 22 | import ( 23 | "fmt" 24 | 25 | "golang.org/x/sys/unix" 26 | ) 27 | 28 | const hwMemsizeMIB = "hw.memsize" 29 | 30 | func MemTotal() (uint64, error) { 31 | size, err := unix.SysctlUint64(hwMemsizeMIB) 32 | if err != nil { 33 | return 0, fmt.Errorf("failed to get mem total: %w", err) 34 | } 35 | 36 | return size, nil 37 | } 38 | -------------------------------------------------------------------------------- /providers/darwin/memory_darwin_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package darwin 19 | 20 | import ( 21 | "testing" 22 | 23 | "github.com/stretchr/testify/assert" 24 | ) 25 | 26 | func TestMemory(t *testing.T) { 27 | m, err := MemTotal() 28 | assert.NoError(t, err) 29 | assert.NotZero(t, m) 30 | } 31 | -------------------------------------------------------------------------------- /providers/darwin/os_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package darwin 19 | 20 | import ( 21 | "fmt" 22 | "os" 23 | "strconv" 24 | "strings" 25 | 26 | "howett.net/plist" 27 | 28 | "github.com/elastic/go-sysinfo/types" 29 | ) 30 | 31 | const ( 32 | systemVersionPlist = "/System/Library/CoreServices/SystemVersion.plist" 33 | 34 | plistProductName = "ProductName" 35 | plistProductVersion = "ProductVersion" 36 | plistProductBuildVersion = "ProductBuildVersion" 37 | ) 38 | 39 | func OperatingSystem() (*types.OSInfo, error) { 40 | data, err := os.ReadFile(systemVersionPlist) 41 | if err != nil { 42 | return nil, fmt.Errorf("failed to read plist file: %w", err) 43 | } 44 | 45 | return getOSInfo(data) 46 | } 47 | 48 | func getOSInfo(data []byte) (*types.OSInfo, error) { 49 | attrs := map[string]string{} 50 | if _, err := plist.Unmarshal(data, &attrs); err != nil { 51 | return nil, fmt.Errorf("failed to unmarshal plist data: %w", err) 52 | } 53 | 54 | productName, found := attrs[plistProductName] 55 | if !found { 56 | return nil, fmt.Errorf("plist key %v not found", plistProductName) 57 | } 58 | 59 | version, found := attrs[plistProductVersion] 60 | if !found { 61 | return nil, fmt.Errorf("plist key %v not found", plistProductVersion) 62 | } 63 | 64 | build, found := attrs[plistProductBuildVersion] 65 | if !found { 66 | return nil, fmt.Errorf("plist key %v not found", plistProductBuildVersion) 67 | } 68 | 69 | var major, minor, patch int 70 | for i, v := range strings.SplitN(version, ".", 3) { 71 | switch i { 72 | case 0: 73 | major, _ = strconv.Atoi(v) 74 | case 1: 75 | minor, _ = strconv.Atoi(v) 76 | case 2: 77 | patch, _ = strconv.Atoi(v) 78 | default: 79 | break 80 | } 81 | } 82 | 83 | return &types.OSInfo{ 84 | Type: "macos", 85 | Family: "darwin", 86 | Platform: "darwin", 87 | Name: productName, 88 | Version: version, 89 | Major: major, 90 | Minor: minor, 91 | Patch: patch, 92 | Build: build, 93 | }, nil 94 | } 95 | -------------------------------------------------------------------------------- /providers/darwin/os_darwin_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package darwin 19 | 20 | import ( 21 | "testing" 22 | 23 | "github.com/stretchr/testify/assert" 24 | ) 25 | 26 | const SystemVersionPlist = ` 27 | 28 | 29 | 30 | ProductBuildVersion 31 | 16G1114 32 | ProductCopyright 33 | 1983-2017 Apple Inc. 34 | ProductName 35 | Mac OS X 36 | ProductUserVisibleVersion 37 | 10.12.6 38 | ProductVersion 39 | 10.12.6 40 | 41 | 42 | ` 43 | 44 | func TestOperatingSystem(t *testing.T) { 45 | osInfo, err := getOSInfo([]byte(SystemVersionPlist)) 46 | if err != nil { 47 | t.Fatal(err) 48 | } 49 | 50 | assert.Equal(t, "macos", osInfo.Type) 51 | assert.Equal(t, "darwin", osInfo.Family) 52 | assert.Equal(t, "darwin", osInfo.Platform) 53 | assert.Equal(t, "Mac OS X", osInfo.Name) 54 | assert.Equal(t, "10.12.6", osInfo.Version) 55 | assert.Equal(t, 10, osInfo.Major) 56 | assert.Equal(t, 12, osInfo.Minor) 57 | assert.Equal(t, 6, osInfo.Patch) 58 | assert.Equal(t, "16G1114", osInfo.Build) 59 | } 60 | -------------------------------------------------------------------------------- /providers/darwin/process_cgo_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build (amd64 && cgo) || (arm64 && cgo) 19 | 20 | package darwin 21 | 22 | // #include 23 | // #include 24 | import "C" 25 | 26 | import ( 27 | "errors" 28 | "unsafe" 29 | ) 30 | 31 | //go:generate sh -c "go tool cgo -godefs defs_darwin.go > ztypes_darwin.go" 32 | 33 | func getProcTaskAllInfo(pid int, info *procTaskAllInfo) error { 34 | size := C.int(unsafe.Sizeof(*info)) 35 | ptr := unsafe.Pointer(info) 36 | 37 | n, err := C.proc_pidinfo(C.int(pid), C.PROC_PIDTASKALLINFO, 0, ptr, size) 38 | if err != nil { 39 | return err 40 | } else if n != size { 41 | return errors.New("failed to read process info with proc_pidinfo") 42 | } 43 | 44 | return nil 45 | } 46 | 47 | func getProcVnodePathInfo(pid int, info *procVnodePathInfo) error { 48 | size := C.int(unsafe.Sizeof(*info)) 49 | ptr := unsafe.Pointer(info) 50 | 51 | n := C.proc_pidinfo(C.int(pid), C.PROC_PIDVNODEPATHINFO, 0, ptr, size) 52 | if n != size { 53 | return errors.New("failed to read vnode info with proc_pidinfo") 54 | } 55 | 56 | return nil 57 | } 58 | -------------------------------------------------------------------------------- /providers/darwin/process_nocgo_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build (amd64 && !cgo) || (arm64 && !cgo) 19 | 20 | package darwin 21 | 22 | import "github.com/elastic/go-sysinfo/types" 23 | 24 | func getProcTaskAllInfo(pid int, info *procTaskAllInfo) error { 25 | return types.ErrNotImplemented 26 | } 27 | 28 | func getProcVnodePathInfo(pid int, info *procVnodePathInfo) error { 29 | return types.ErrNotImplemented 30 | } 31 | -------------------------------------------------------------------------------- /providers/darwin/syscall_cgo_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build (amd64 && cgo) || (arm64 && cgo) 19 | 20 | package darwin 21 | 22 | /* 23 | #cgo LDFLAGS:-lproc 24 | #include 25 | #include 26 | #include 27 | #include 28 | */ 29 | import "C" 30 | 31 | import ( 32 | "fmt" 33 | "unsafe" 34 | ) 35 | 36 | func getHostCPULoadInfo() (*cpuUsage, error) { 37 | var count C.mach_msg_type_number_t = C.HOST_CPU_LOAD_INFO_COUNT 38 | var cpu cpuUsage 39 | status := C.host_statistics(C.host_t(C.mach_host_self()), 40 | C.HOST_CPU_LOAD_INFO, 41 | C.host_info_t(unsafe.Pointer(&cpu)), 42 | &count) 43 | 44 | if status != C.KERN_SUCCESS { 45 | return nil, fmt.Errorf("host_statistics returned status %d", status) 46 | } 47 | 48 | return &cpu, nil 49 | } 50 | 51 | // getClockTicks returns the number of click ticks in one jiffie. 52 | func getClockTicks() int { 53 | return int(C.sysconf(C._SC_CLK_TCK)) 54 | } 55 | 56 | func getHostVMInfo64() (*vmStatistics64Data, error) { 57 | var count C.mach_msg_type_number_t = C.HOST_VM_INFO64_COUNT 58 | 59 | var vmStat vmStatistics64Data 60 | status := C.host_statistics64( 61 | C.host_t(C.mach_host_self()), 62 | C.HOST_VM_INFO64, 63 | C.host_info_t(unsafe.Pointer(&vmStat)), 64 | &count) 65 | 66 | if status != C.KERN_SUCCESS { 67 | return nil, fmt.Errorf("host_statistics64 returned status %d", status) 68 | } 69 | 70 | return &vmStat, nil 71 | } 72 | -------------------------------------------------------------------------------- /providers/darwin/syscall_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build amd64 || arm64 19 | 20 | package darwin 21 | 22 | import ( 23 | "bytes" 24 | "encoding/binary" 25 | "fmt" 26 | 27 | "golang.org/x/sys/unix" 28 | ) 29 | 30 | type cpuUsage struct { 31 | User uint32 32 | System uint32 33 | Idle uint32 34 | Nice uint32 35 | } 36 | 37 | func getPageSize() (uint64, error) { 38 | i, err := unix.SysctlUint32("vm.pagesize") 39 | if err != nil { 40 | return 0, fmt.Errorf("vm.pagesize returned %w", err) 41 | } 42 | 43 | return uint64(i), nil 44 | } 45 | 46 | // From sysctl.h - xsw_usage. 47 | type swapUsage struct { 48 | Total uint64 49 | Available uint64 50 | Used uint64 51 | PageSize uint64 52 | } 53 | 54 | const vmSwapUsageMIB = "vm.swapusage" 55 | 56 | func getSwapUsage() (*swapUsage, error) { 57 | var swap swapUsage 58 | data, err := unix.SysctlRaw(vmSwapUsageMIB) 59 | if err != nil { 60 | return nil, err 61 | } 62 | 63 | if err := binary.Read(bytes.NewReader(data), binary.LittleEndian, &swap); err != nil { 64 | return nil, err 65 | } 66 | 67 | return &swap, nil 68 | } 69 | -------------------------------------------------------------------------------- /providers/darwin/syscall_nocgo_darwin.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build (amd64 && !cgo) || (arm64 && !cgo) 19 | 20 | package darwin 21 | 22 | import ( 23 | "fmt" 24 | 25 | "github.com/elastic/go-sysinfo/types" 26 | ) 27 | 28 | func getHostCPULoadInfo() (*cpuUsage, error) { 29 | return nil, fmt.Errorf("host cpu load requires cgo: %w", types.ErrNotImplemented) 30 | } 31 | 32 | // getClockTicks returns the number of click ticks in one jiffie. 33 | func getClockTicks() int { 34 | return 0 35 | } 36 | 37 | func getHostVMInfo64() (*vmStatistics64Data, error) { 38 | return nil, fmt.Errorf("host vm info requires cgo: %w", types.ErrNotImplemented) 39 | } 40 | -------------------------------------------------------------------------------- /providers/linux/arch_linux.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "fmt" 22 | "os" 23 | "strings" 24 | "syscall" 25 | ) 26 | 27 | const ( 28 | procSysKernelArch = "/proc/sys/kernel/arch" 29 | procVersion = "/proc/version" 30 | arch8664 = "x86_64" 31 | archAmd64 = "amd64" 32 | archArm64 = "arm64" 33 | archAarch64 = "aarch64" 34 | ) 35 | 36 | func Architecture() (string, error) { 37 | var uname syscall.Utsname 38 | if err := syscall.Uname(&uname); err != nil { 39 | return "", fmt.Errorf("architecture: %w", err) 40 | } 41 | 42 | data := make([]byte, 0, len(uname.Machine)) 43 | for _, v := range uname.Machine { 44 | if v == 0 { 45 | break 46 | } 47 | data = append(data, byte(v)) 48 | } 49 | 50 | return string(data), nil 51 | } 52 | 53 | func NativeArchitecture() (string, error) { 54 | // /proc/sys/kernel/arch was introduced in Kernel 6.1 55 | // https://www.kernel.org/doc/html/v6.1/admin-guide/sysctl/kernel.html#arch 56 | // It's the same as uname -m, except that for a process running in emulation 57 | // machine returned from syscall reflects the emulated machine, whilst /proc 58 | // filesystem is read as file so its value is not emulated 59 | data, err := os.ReadFile(procSysKernelArch) 60 | if err != nil { 61 | if os.IsNotExist(err) { 62 | // fallback to checking version string for older kernels 63 | version, err := os.ReadFile(procVersion) 64 | if err != nil && !os.IsNotExist(err) { 65 | return "", fmt.Errorf("failed to read kernel version: %w", err) 66 | } 67 | 68 | versionStr := string(version) 69 | if strings.Contains(versionStr, archAmd64) || strings.Contains(versionStr, arch8664) { 70 | return archAmd64, nil 71 | } else if strings.Contains(versionStr, archArm64) || strings.Contains(versionStr, archAarch64) { 72 | // for parity with Architecture() and /proc/sys/kernel/arch 73 | // as aarch64 and arm64 are used interchangeably 74 | return archAarch64, nil 75 | } 76 | return "", nil 77 | } 78 | 79 | return "", fmt.Errorf("failed to read kernel arch: %w", err) 80 | } 81 | 82 | nativeArch := string(data) 83 | nativeArch = strings.TrimRight(nativeArch, "\n") 84 | 85 | return nativeArch, nil 86 | } 87 | -------------------------------------------------------------------------------- /providers/linux/arch_linux_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "regexp" 22 | "testing" 23 | 24 | "github.com/stretchr/testify/assert" 25 | ) 26 | 27 | var reNewline = regexp.MustCompile("^.*\n+$") 28 | 29 | func TestArchitecture(t *testing.T) { 30 | a, err := Architecture() 31 | assert.NoError(t, err) 32 | assert.NotEmpty(t, a) 33 | assert.NotRegexp(t, reNewline, a, "should not end in newlines") 34 | } 35 | 36 | func TestNativeArchitecture(t *testing.T) { 37 | a, err := NativeArchitecture() 38 | assert.NoError(t, err) 39 | assert.NotEmpty(t, a) 40 | assert.NotRegexp(t, reNewline, a, "should not end in newlines") 41 | } 42 | -------------------------------------------------------------------------------- /providers/linux/boottime_linux.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "sync" 22 | "time" 23 | 24 | "github.com/prometheus/procfs" 25 | ) 26 | 27 | var ( 28 | bootTimeValue time.Time // Cached boot time. 29 | bootTimeLock sync.Mutex // Lock that guards access to bootTime. 30 | ) 31 | 32 | func bootTime(fs procfs.FS) (time.Time, error) { 33 | bootTimeLock.Lock() 34 | defer bootTimeLock.Unlock() 35 | 36 | if !bootTimeValue.IsZero() { 37 | return bootTimeValue, nil 38 | } 39 | 40 | stat, err := fs.Stat() 41 | if err != nil { 42 | return time.Time{}, err 43 | } 44 | 45 | bootTimeValue = time.Unix(int64(stat.BootTime), 0) 46 | return bootTimeValue, nil 47 | } 48 | -------------------------------------------------------------------------------- /providers/linux/capabilities_linux.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "strconv" 22 | 23 | "github.com/elastic/go-sysinfo/types" 24 | ) 25 | 26 | // capabilityNames is mapping of capability constant values to names. 27 | // 28 | // Generated with: 29 | // 30 | // curl -s https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/capability.h | \ 31 | // grep -P '^#define CAP_\w+\s+\d+' | \ 32 | // perl -pe 's/#define CAP_(\w+)\s+(\d+)/\2: "\L\1",/g' 33 | var capabilityNames = map[int]string{ 34 | 0: "chown", 35 | 1: "dac_override", 36 | 2: "dac_read_search", 37 | 3: "fowner", 38 | 4: "fsetid", 39 | 5: "kill", 40 | 6: "setgid", 41 | 7: "setuid", 42 | 8: "setpcap", 43 | 9: "linux_immutable", 44 | 10: "net_bind_service", 45 | 11: "net_broadcast", 46 | 12: "net_admin", 47 | 13: "net_raw", 48 | 14: "ipc_lock", 49 | 15: "ipc_owner", 50 | 16: "sys_module", 51 | 17: "sys_rawio", 52 | 18: "sys_chroot", 53 | 19: "sys_ptrace", 54 | 20: "sys_pacct", 55 | 21: "sys_admin", 56 | 22: "sys_boot", 57 | 23: "sys_nice", 58 | 24: "sys_resource", 59 | 25: "sys_time", 60 | 26: "sys_tty_config", 61 | 27: "mknod", 62 | 28: "lease", 63 | 29: "audit_write", 64 | 30: "audit_control", 65 | 31: "setfcap", 66 | 32: "mac_override", 67 | 33: "mac_admin", 68 | 34: "syslog", 69 | 35: "wake_alarm", 70 | 36: "block_suspend", 71 | 37: "audit_read", 72 | 38: "perfmon", 73 | 39: "bpf", 74 | 40: "checkpoint_restore", 75 | } 76 | 77 | func capabilityName(num int) string { 78 | name, found := capabilityNames[num] 79 | if found { 80 | return name 81 | } 82 | 83 | return strconv.Itoa(num) 84 | } 85 | 86 | func readCapabilities(content []byte) (*types.CapabilityInfo, error) { 87 | var cap types.CapabilityInfo 88 | 89 | err := parseKeyValue(content, ':', func(key, value []byte) error { 90 | var err error 91 | switch string(key) { 92 | case "CapInh": 93 | cap.Inheritable, err = decodeBitMap(string(value), capabilityName) 94 | if err != nil { 95 | return err 96 | } 97 | case "CapPrm": 98 | cap.Permitted, err = decodeBitMap(string(value), capabilityName) 99 | if err != nil { 100 | return err 101 | } 102 | case "CapEff": 103 | cap.Effective, err = decodeBitMap(string(value), capabilityName) 104 | if err != nil { 105 | return err 106 | } 107 | case "CapBnd": 108 | cap.Bounding, err = decodeBitMap(string(value), capabilityName) 109 | if err != nil { 110 | return err 111 | } 112 | case "CapAmb": 113 | cap.Ambient, err = decodeBitMap(string(value), capabilityName) 114 | if err != nil { 115 | return err 116 | } 117 | } 118 | return nil 119 | }) 120 | 121 | return &cap, err 122 | } 123 | -------------------------------------------------------------------------------- /providers/linux/container.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "bufio" 22 | "bytes" 23 | "fmt" 24 | "os" 25 | ) 26 | 27 | const procOneCgroup = "/proc/1/cgroup" 28 | 29 | // IsContainerized returns true if this process is containerized. 30 | func IsContainerized() (bool, error) { 31 | data, err := os.ReadFile(procOneCgroup) 32 | if err != nil { 33 | if os.IsNotExist(err) { 34 | return false, nil 35 | } 36 | 37 | return false, fmt.Errorf("failed to read process cgroups: %w", err) 38 | } 39 | 40 | return isContainerizedCgroup(data) 41 | } 42 | 43 | func isContainerizedCgroup(data []byte) (bool, error) { 44 | s := bufio.NewScanner(bytes.NewReader(data)) 45 | for n := 0; s.Scan(); n++ { 46 | line := s.Bytes() 47 | 48 | // Following a suggestion on Stack Overflow on how to detect 49 | // being inside a container: https://stackoverflow.com/a/20012536/235203 50 | if bytes.Contains(line, []byte("docker")) || bytes.Contains(line, []byte(".slice")) || bytes.Contains(line, []byte("lxc")) || bytes.Contains(line, []byte("kubepods")) { 51 | return true, nil 52 | } 53 | } 54 | 55 | return false, s.Err() 56 | } 57 | -------------------------------------------------------------------------------- /providers/linux/doc.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | // Package linux implements the HostProvider and ProcessProvider interfaces 19 | // for providing information about Linux. 20 | package linux 21 | -------------------------------------------------------------------------------- /providers/linux/host_fqdn_integration_docker_linux_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build integration && docker 19 | 20 | package linux 21 | 22 | import ( 23 | "context" 24 | "fmt" 25 | "testing" 26 | "time" 27 | 28 | "github.com/stretchr/testify/require" 29 | ) 30 | 31 | func TestHost_FQDN_set(t *testing.T) { 32 | host, err := newLinuxSystem("").Host() 33 | if err != nil { 34 | t.Fatal(fmt.Errorf("could not get host information: %w", err)) 35 | } 36 | 37 | ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 38 | defer cancel() 39 | 40 | gotFQDN, err := host.FQDNWithContext(ctx) 41 | require.NoError(t, err) 42 | if gotFQDN != wantFQDN { 43 | t.Errorf("got FQDN %q, want: %q", gotFQDN, wantFQDN) 44 | } 45 | } 46 | 47 | func TestHost_FQDN_not_set(t *testing.T) { 48 | host, err := newLinuxSystem("").Host() 49 | if err != nil { 50 | t.Fatal(fmt.Errorf("could not get host information: %w", err)) 51 | } 52 | 53 | ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 54 | defer cancel() 55 | 56 | gotFQDN, err := host.FQDNWithContext(ctx) 57 | require.NoError(t, err) 58 | hostname := host.Info().Hostname 59 | if gotFQDN != hostname { 60 | t.Errorf("name and FQDN should be the same but hostname: %s, FQDN %s", hostname, gotFQDN) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /providers/linux/host_fqdn_integration_linux_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build integration 19 | 20 | package linux 21 | 22 | import ( 23 | "bytes" 24 | "go/build" 25 | "path/filepath" 26 | "runtime" 27 | "strings" 28 | "testing" 29 | 30 | "golang.org/x/sys/execabs" 31 | ) 32 | 33 | const ( 34 | wantHostname = "hostname" 35 | wantDomain = "some.domain" 36 | wantFQDN = wantHostname + "." + wantDomain 37 | ) 38 | 39 | func TestHost_FQDN(t *testing.T) { 40 | if _, err := execabs.LookPath("docker"); err != nil { 41 | t.Skipf("Skipping because docker was not found: %v", err) 42 | } 43 | 44 | tcs := []struct { 45 | name string 46 | Hostname string 47 | Domainname string 48 | Cmd []string 49 | }{ 50 | { 51 | name: "TestHost_FQDN_set_hostname+domainname", 52 | Hostname: wantHostname, 53 | Domainname: wantDomain, 54 | Cmd: []string{ 55 | "go", "test", "-v", 56 | "-tags", "integration,docker", 57 | "-run", "^TestHost_FQDN_set$", 58 | "./providers/linux", 59 | }, 60 | }, 61 | { 62 | name: "TestHost_FQDN_set_hostname_only", 63 | Hostname: wantFQDN, 64 | Cmd: []string{ 65 | "go", "test", "-v", 66 | "-tags", "integration,docker", 67 | "-run", "^TestHost_FQDN_set$", 68 | "./providers/linux", 69 | }, 70 | }, 71 | { 72 | name: "TestHost_FQDN_not_set", 73 | Cmd: []string{ 74 | "go", "test", "-v", "-count", "1", 75 | "-tags", "integration,docker", 76 | "-run", "^TestHost_FQDN_not_set$", 77 | "./providers/linux", 78 | }, 79 | }, 80 | } 81 | 82 | for _, tc := range tcs { 83 | t.Run(tc.name, func(t *testing.T) { 84 | dockerRun(t, tc.Hostname, tc.Domainname, tc.Cmd) 85 | }) 86 | } 87 | } 88 | 89 | // dockerRun executes the given command inside the golang Docker container. 90 | // It will set the container's hostname and domain according to the given 91 | // values. 92 | // 93 | // The container's stdout and stderr are passed through. The test will fail 94 | // if docker run returns a non-zero exit code. 95 | func dockerRun(t *testing.T, hostname, domain string, command []string) { 96 | t.Helper() 97 | 98 | // Determine the repository root. 99 | _, filename, _, _ := runtime.Caller(0) 100 | repoRoot, err := filepath.Abs(filepath.Join(filepath.Dir(filename), "../..")) 101 | if err != nil { 102 | t.Fatal(err) 103 | } 104 | 105 | // Use the same version of Go inside the container. 106 | goVersion := strings.TrimPrefix(runtime.Version(), "go") 107 | 108 | args := []string{ 109 | "run", 110 | "--rm", 111 | "-v", build.Default.GOPATH + ":/go", // Mount GOPATH for caching. 112 | "-v", repoRoot + ":/go-sysinfo", 113 | "-w=/go-sysinfo", 114 | } 115 | if hostname != "" { 116 | args = append(args, "--hostname="+hostname) 117 | } 118 | if domain != "" { 119 | args = append(args, "--domainname="+domain) 120 | } 121 | args = append(args, "golang:"+goVersion) 122 | args = append(args, command...) 123 | 124 | buf := new(bytes.Buffer) 125 | cmd := execabs.Command("docker", args...) 126 | cmd.Stdout = buf 127 | cmd.Stderr = buf 128 | 129 | t.Logf("Running docker container using %q", args) 130 | defer t.Log("Exiting container") 131 | 132 | err = cmd.Run() 133 | t.Logf("Container output:\n%s", buf.String()) 134 | if err != nil { 135 | t.Fatal(err) 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /providers/linux/host_linux_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "encoding/json" 22 | "testing" 23 | 24 | "github.com/stretchr/testify/assert" 25 | 26 | "github.com/elastic/go-sysinfo/internal/registry" 27 | "github.com/elastic/go-sysinfo/types" 28 | ) 29 | 30 | var _ registry.HostProvider = linuxSystem{} 31 | 32 | func TestHost(t *testing.T) { 33 | host, err := newLinuxSystem("").Host() 34 | if err != nil { 35 | t.Logf("could not get all host info: %v\n", err) 36 | } 37 | 38 | info := host.Info() 39 | data, _ := json.MarshalIndent(info, "", " ") 40 | t.Logf(string(data)) 41 | } 42 | 43 | func TestHostMemoryInfo(t *testing.T) { 44 | host, err := newLinuxSystem("testdata/ubuntu1710").Host() 45 | if err != nil { 46 | t.Fatal(err) 47 | } 48 | m, err := host.Memory() 49 | if err != nil { 50 | t.Fatal(err) 51 | } 52 | 53 | assert.EqualValues(t, 4139057152, m.Total) 54 | assert.NotContains(t, m.Metrics, "MemTotal") 55 | assert.Contains(t, m.Metrics, "Slab") 56 | } 57 | 58 | func TestHostVMStat(t *testing.T) { 59 | host, err := newLinuxSystem("testdata/ubuntu1710").Host() 60 | if err != nil { 61 | t.Fatal(err) 62 | } 63 | s, err := host.(types.VMStat).VMStat() 64 | if err != nil { 65 | t.Fatal(err) 66 | } 67 | 68 | data, err := json.MarshalIndent(s, "", " ") 69 | if err != nil { 70 | t.Fatal(err) 71 | } 72 | t.Log(string(data)) 73 | } 74 | 75 | func TestHostLoadAverage(t *testing.T) { 76 | host, err := newLinuxSystem("testdata/ubuntu1710").Host() 77 | if err != nil { 78 | t.Fatal(err) 79 | } 80 | s, err := host.(types.LoadAverage).LoadAverage() 81 | if err != nil { 82 | t.Fatal(err) 83 | } 84 | 85 | data, err := json.Marshal(s) 86 | if err != nil { 87 | t.Fatal(err) 88 | } 89 | t.Log(string(data)) 90 | } 91 | 92 | func TestHostNetworkCounters(t *testing.T) { 93 | host, err := newLinuxSystem("testdata/fedora30").Host() 94 | if err != nil { 95 | t.Fatal(err) 96 | } 97 | 98 | s, err := host.(types.NetworkCounters).NetworkCounters() 99 | if err != nil { 100 | t.Fatal(err) 101 | } 102 | 103 | assert.NotEmpty(t, s.Netstat.IPExt) 104 | assert.NotEmpty(t, s.Netstat.TCPExt) 105 | assert.NotEmpty(t, s.SNMP.IP) 106 | 107 | data, err := json.MarshalIndent(s, "", " ") 108 | if err != nil { 109 | t.Fatal(err) 110 | } 111 | t.Log(string(data)) 112 | } 113 | -------------------------------------------------------------------------------- /providers/linux/kernel_linux.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "fmt" 22 | "syscall" 23 | ) 24 | 25 | func KernelVersion() (string, error) { 26 | var uname syscall.Utsname 27 | if err := syscall.Uname(&uname); err != nil { 28 | return "", fmt.Errorf("kernel version: %w", err) 29 | } 30 | 31 | data := make([]byte, 0, len(uname.Release)) 32 | for _, v := range uname.Release { 33 | if v == 0 { 34 | break 35 | } 36 | data = append(data, byte(v)) 37 | } 38 | 39 | return string(data), nil 40 | } 41 | -------------------------------------------------------------------------------- /providers/linux/machineid.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "bytes" 22 | "fmt" 23 | "os" 24 | "path/filepath" 25 | 26 | "github.com/elastic/go-sysinfo/types" 27 | ) 28 | 29 | // Possible (current and historic) locations of the machine-id file. 30 | // These will be searched in order. 31 | var machineIDFiles = []string{"/etc/machine-id", "/var/lib/dbus/machine-id", "/var/db/dbus/machine-id"} 32 | 33 | func machineID(hostfs string) (string, error) { 34 | var contents []byte 35 | var err error 36 | 37 | for _, file := range machineIDFiles { 38 | contents, err = os.ReadFile(filepath.Join(hostfs, file)) 39 | if err != nil { 40 | if os.IsNotExist(err) { 41 | // Try next location 42 | continue 43 | } 44 | 45 | // Return with error on any other error 46 | return "", fmt.Errorf("failed to read %v: %w", file, err) 47 | } 48 | 49 | // Found it 50 | break 51 | } 52 | 53 | if os.IsNotExist(err) { 54 | // None of the locations existed 55 | return "", types.ErrNotImplemented 56 | } 57 | 58 | contents = bytes.TrimSpace(contents) 59 | return string(contents), nil 60 | } 61 | 62 | func MachineIDHostfs(hostfs string) (string, error) { 63 | return machineID(hostfs) 64 | } 65 | 66 | func MachineID() (string, error) { 67 | return machineID("") 68 | } 69 | -------------------------------------------------------------------------------- /providers/linux/machineid_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "testing" 22 | 23 | "github.com/stretchr/testify/require" 24 | ) 25 | 26 | func TestMachineIDLookup(t *testing.T) { 27 | path := "testdata/fedora30" 28 | known := "144d62edb0f142458f320852f495b72c" 29 | id, err := MachineIDHostfs(path) 30 | require.NoError(t, err) 31 | require.Equal(t, known, id) 32 | } 33 | -------------------------------------------------------------------------------- /providers/linux/memory_linux.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "fmt" 22 | 23 | "github.com/elastic/go-sysinfo/types" 24 | ) 25 | 26 | func parseMemInfo(content []byte) (*types.HostMemoryInfo, error) { 27 | memInfo := &types.HostMemoryInfo{ 28 | Metrics: map[string]uint64{}, 29 | } 30 | 31 | hasAvailable := false 32 | err := parseKeyValue(content, ':', func(key, value []byte) error { 33 | num, err := parseBytesOrNumber(value) 34 | if err != nil { 35 | return fmt.Errorf("failed to parse %v value of %v: %w", string(key), string(value), err) 36 | } 37 | 38 | k := string(key) 39 | switch k { 40 | case "MemTotal": 41 | memInfo.Total = num 42 | case "MemAvailable": 43 | hasAvailable = true 44 | memInfo.Available = num 45 | case "MemFree": 46 | memInfo.Free = num 47 | case "SwapTotal": 48 | memInfo.VirtualTotal = num 49 | case "SwapFree": 50 | memInfo.VirtualFree = num 51 | default: 52 | memInfo.Metrics[k] = num 53 | } 54 | 55 | return nil 56 | }) 57 | if err != nil { 58 | return nil, err 59 | } 60 | 61 | memInfo.Used = memInfo.Total - memInfo.Free 62 | memInfo.VirtualUsed = memInfo.VirtualTotal - memInfo.VirtualFree 63 | 64 | // MemAvailable was added in kernel 3.14. 65 | if !hasAvailable { 66 | // Linux uses this for the calculation (but we are using a simpler calculation). 67 | // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773 68 | memInfo.Available = memInfo.Free + memInfo.Metrics["Buffers"] + memInfo.Metrics["Cached"] 69 | } 70 | 71 | return memInfo, nil 72 | } 73 | -------------------------------------------------------------------------------- /providers/linux/process_linux_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "testing" 22 | 23 | "github.com/stretchr/testify/assert" 24 | 25 | "github.com/elastic/go-sysinfo/internal/registry" 26 | "github.com/elastic/go-sysinfo/types" 27 | ) 28 | 29 | var ( 30 | _ registry.HostProvider = linuxSystem{} 31 | _ registry.ProcessProvider = linuxSystem{} 32 | ) 33 | 34 | func TestProcessNetstat(t *testing.T) { 35 | proc, err := newLinuxSystem("").Self() 36 | if err != nil { 37 | t.Fatal(err) 38 | } 39 | procNetwork, ok := proc.(types.NetworkCounters) 40 | if !ok { 41 | t.Fatalf("error, cannot cast to types.NetworkCounters") 42 | } 43 | stats, err := procNetwork.NetworkCounters() 44 | if err != nil { 45 | t.Fatal(err) 46 | } 47 | 48 | assert.NotEmpty(t, stats.SNMP.ICMP, "ICMP") 49 | assert.NotEmpty(t, stats.SNMP.IP, "IP") 50 | assert.NotEmpty(t, stats.SNMP.TCP, "TCP") 51 | assert.NotEmpty(t, stats.SNMP.UDP, "UDP") 52 | } 53 | -------------------------------------------------------------------------------- /providers/linux/procnet.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "errors" 22 | "fmt" 23 | "reflect" 24 | "strconv" 25 | "strings" 26 | 27 | "github.com/elastic/go-sysinfo/types" 28 | ) 29 | 30 | // fillStruct is some reflection work that can dynamically fill one of our tagged `netstat` structs with netstat data 31 | func fillStruct(str interface{}, data map[string]map[string]uint64) { 32 | val := reflect.ValueOf(str).Elem() 33 | typ := reflect.TypeOf(str).Elem() 34 | 35 | for i := 0; i < typ.NumField(); i++ { 36 | field := typ.Field(i) 37 | if tag := field.Tag.Get("netstat"); tag != "" { 38 | if values, ok := data[tag]; ok { 39 | val.Field(i).Set(reflect.ValueOf(values)) 40 | } 41 | } 42 | } 43 | } 44 | 45 | // parseEntry parses two lines from the net files, the first line being keys, the second being values 46 | func parseEntry(line1, line2 string) (map[string]uint64, error) { 47 | keyArr := strings.Split(strings.TrimSpace(line1), " ") 48 | valueArr := strings.Split(strings.TrimSpace(line2), " ") 49 | 50 | if len(keyArr) != len(valueArr) { 51 | return nil, errors.New("key and value lines are mismatched") 52 | } 53 | 54 | counters := make(map[string]uint64, len(valueArr)) 55 | for iter, value := range valueArr { 56 | 57 | // This if-else block is to deal with the MaxConn value in SNMP, 58 | // which is a signed value according to RFC2012. 59 | // This library emulates the behavior of the kernel: store all values as a uint, then cast to a signed value for printing 60 | // Users of this library need to be aware that this value should be printed as a signed int or hex value to make it useful. 61 | var parsed uint64 62 | var err error 63 | if strings.Contains(value, "-") { 64 | signedParsed, err := strconv.ParseInt(value, 10, 64) 65 | if err != nil { 66 | return nil, fmt.Errorf("error parsing string to int in line: %#v: %w", valueArr, err) 67 | } 68 | parsed = uint64(signedParsed) 69 | } else { 70 | parsed, err = strconv.ParseUint(value, 10, 64) 71 | if err != nil { 72 | return nil, fmt.Errorf("error parsing string to int in line: %#v: %w", valueArr, err) 73 | } 74 | } 75 | 76 | counters[keyArr[iter]] = parsed 77 | } 78 | return counters, nil 79 | } 80 | 81 | // parseNetFile parses an entire file, and returns a 2D map, representing how files are sorted by protocol 82 | func parseNetFile(body string) (map[string]map[string]uint64, error) { 83 | fileMetrics := make(map[string]map[string]uint64) 84 | bodySplit := strings.Split(strings.TrimSpace(body), "\n") 85 | // There should be an even number of lines. If not, something is wrong. 86 | if len(bodySplit)%2 != 0 { 87 | return nil, fmt.Errorf("badly parsed body: %s", body) 88 | } 89 | // in the network counters, data is divided into two-line sections: a line of keys, and a line of values 90 | // With each line 91 | for index := 0; index < len(bodySplit); index += 2 { 92 | keysSplit := strings.Split(bodySplit[index], ":") 93 | valuesSplit := strings.Split(bodySplit[index+1], ":") 94 | if len(keysSplit) != 2 || len(valuesSplit) != 2 { 95 | return nil, fmt.Errorf("wrong number of keys: %#v", keysSplit) 96 | } 97 | valMap, err := parseEntry(keysSplit[1], valuesSplit[1]) 98 | if err != nil { 99 | return nil, fmt.Errorf("error parsing lines: %w", err) 100 | } 101 | fileMetrics[valuesSplit[0]] = valMap 102 | } 103 | return fileMetrics, nil 104 | } 105 | 106 | // getNetSnmpStats pulls snmp stats from /proc/net 107 | func getNetSnmpStats(raw []byte) (types.SNMP, error) { 108 | snmpData, err := parseNetFile(string(raw)) 109 | if err != nil { 110 | return types.SNMP{}, fmt.Errorf("error parsing SNMP: %w", err) 111 | } 112 | output := types.SNMP{} 113 | fillStruct(&output, snmpData) 114 | 115 | return output, nil 116 | } 117 | 118 | // getNetstatStats pulls netstat stats from /proc/net 119 | func getNetstatStats(raw []byte) (types.Netstat, error) { 120 | netstatData, err := parseNetFile(string(raw)) 121 | if err != nil { 122 | return types.Netstat{}, fmt.Errorf("error parsing netstat: %w", err) 123 | } 124 | output := types.Netstat{} 125 | fillStruct(&output, netstatData) 126 | return output, nil 127 | } 128 | -------------------------------------------------------------------------------- /providers/linux/procnet_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "testing" 22 | 23 | "github.com/stretchr/testify/assert" 24 | 25 | "github.com/elastic/go-sysinfo/types" 26 | ) 27 | 28 | func TestParseFile(t *testing.T) { 29 | file := `Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates 30 | Ip: 1 64 23123056 0 19 21075 0 0 21842645 16017256 1 4 0 0 0 0 0 0 0 31 | Icmp: InMsgs InErrors InCsumErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps 32 | Icmp: 487 1 0 486 0 0 0 0 1 0 0 0 0 0 570 0 569 0 0 0 0 0 1 0 0 0 0 33 | IcmpMsg: InType3 InType8 OutType0 OutType3 34 | IcmpMsg: 486 1 1 569 35 | Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts InCsumErrors 36 | Tcp: 1 200 120000 -1 4160 873 1408 334 10 21825426 34620510 10474 0 6102 0 37 | Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors IgnoredMulti 38 | Udp: 16755 33 0 16829 0 0 0 0 39 | UdpLite: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors IgnoredMulti 40 | UdpLite: 0 0 0 0 0 0 0 0` 41 | mapStr, err := parseNetFile(file) 42 | if err != nil { 43 | t.Fatalf("error: %s", err) 44 | } 45 | testOut := types.SNMP{} 46 | fillStruct(&testOut, mapStr) 47 | 48 | assert.NotEmpty(t, testOut.IP) 49 | assert.Equal(t, uint64(16755), testOut.UDP["InDatagrams"]) 50 | assert.Equal(t, uint64(0xffffffffffffffff), testOut.TCP["MaxConn"]) 51 | } 52 | -------------------------------------------------------------------------------- /providers/linux/seccomp_linux.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "strconv" 22 | 23 | "github.com/elastic/go-sysinfo/types" 24 | ) 25 | 26 | type SeccompMode uint8 27 | 28 | const ( 29 | SeccompModeDisabled SeccompMode = iota 30 | SeccompModeStrict 31 | SeccompModeFilter 32 | ) 33 | 34 | func (m SeccompMode) String() string { 35 | switch m { 36 | case SeccompModeDisabled: 37 | return "disabled" 38 | case SeccompModeStrict: 39 | return "strict" 40 | case SeccompModeFilter: 41 | return "filter" 42 | default: 43 | return strconv.Itoa(int(m)) 44 | } 45 | } 46 | 47 | func readSeccompFields(content []byte) (*types.SeccompInfo, error) { 48 | var seccomp types.SeccompInfo 49 | 50 | err := parseKeyValue(content, ':', func(key, value []byte) error { 51 | switch string(key) { 52 | case "Seccomp": 53 | mode, err := strconv.ParseUint(string(value), 10, 8) 54 | if err != nil { 55 | return err 56 | } 57 | seccomp.Mode = SeccompMode(mode).String() 58 | case "NoNewPrivs": 59 | noNewPrivs, err := strconv.ParseBool(string(value)) 60 | if err != nil { 61 | return err 62 | } 63 | seccomp.NoNewPrivs = &noNewPrivs 64 | } 65 | return nil 66 | }) 67 | 68 | return &seccomp, err 69 | } 70 | -------------------------------------------------------------------------------- /providers/linux/testdata/almalinux10/etc/almalinux-release: -------------------------------------------------------------------------------- 1 | AlmaLinux release 10.0 (Purple Lion) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/almalinux10/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/almalinux10/etc/redhat-release: -------------------------------------------------------------------------------- 1 | almalinux-release -------------------------------------------------------------------------------- /providers/linux/testdata/almalinux10/etc/system-release: -------------------------------------------------------------------------------- 1 | almalinux-release -------------------------------------------------------------------------------- /providers/linux/testdata/almalinux10/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME="AlmaLinux" 2 | VERSION="10.0 (Purple Lion)" 3 | ID="almalinux" 4 | ID_LIKE="rhel centos fedora" 5 | VERSION_ID="10.0" 6 | PLATFORM_ID="platform:el10" 7 | PRETTY_NAME="AlmaLinux 10.0 (Purple Lion)" 8 | ANSI_COLOR="0;34" 9 | LOGO="fedora-logo-icon" 10 | CPE_NAME="cpe:/o:almalinux:almalinux:10::baseos" 11 | HOME_URL="https://almalinux.org/" 12 | DOCUMENTATION_URL="https://wiki.almalinux.org/" 13 | BUG_REPORT_URL="https://bugs.almalinux.org/" 14 | 15 | ALMALINUX_MANTISBT_PROJECT="AlmaLinux-10" 16 | ALMALINUX_MANTISBT_PROJECT_VERSION="10.0" 17 | REDHAT_SUPPORT_PRODUCT="AlmaLinux" 18 | REDHAT_SUPPORT_PRODUCT_VERSION="10.0" 19 | -------------------------------------------------------------------------------- /providers/linux/testdata/almalinux9/etc/almalinux-release: -------------------------------------------------------------------------------- 1 | AlmaLinux release 9.1 (Lime Lynx) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/almalinux9/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/almalinux9/etc/redhat-release: -------------------------------------------------------------------------------- 1 | almalinux-release -------------------------------------------------------------------------------- /providers/linux/testdata/almalinux9/etc/system-release: -------------------------------------------------------------------------------- 1 | almalinux-release -------------------------------------------------------------------------------- /providers/linux/testdata/almalinux9/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME="AlmaLinux" 2 | VERSION="9.1 (Lime Lynx)" 3 | ID="almalinux" 4 | ID_LIKE="rhel centos fedora" 5 | VERSION_ID="9.1" 6 | PLATFORM_ID="platform:el9" 7 | PRETTY_NAME="AlmaLinux 9.1 (Lime Lynx)" 8 | ANSI_COLOR="0;34" 9 | LOGO="fedora-logo-icon" 10 | CPE_NAME="cpe:/o:almalinux:almalinux:9::baseos" 11 | HOME_URL="https://almalinux.org/" 12 | DOCUMENTATION_URL="https://wiki.almalinux.org/" 13 | BUG_REPORT_URL="https://bugs.almalinux.org/" 14 | 15 | ALMALINUX_MANTISBT_PROJECT="AlmaLinux-9" 16 | ALMALINUX_MANTISBT_PROJECT_VERSION="9.1" 17 | REDHAT_SUPPORT_PRODUCT="AlmaLinux" 18 | REDHAT_SUPPORT_PRODUCT_VERSION="9.1" 19 | -------------------------------------------------------------------------------- /providers/linux/testdata/alpine3.17/etc/alpine-release: -------------------------------------------------------------------------------- 1 | 3.17.3 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/alpine3.17/etc/os-release: -------------------------------------------------------------------------------- 1 | NAME="Alpine Linux" 2 | ID=alpine 3 | VERSION_ID=3.17.3 4 | PRETTY_NAME="Alpine Linux v3.17" 5 | HOME_URL="https://alpinelinux.org/" 6 | BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues" 7 | -------------------------------------------------------------------------------- /providers/linux/testdata/amazon2017.03/etc/os-release: -------------------------------------------------------------------------------- 1 | NAME="Amazon Linux AMI" 2 | VERSION="2017.03" 3 | ID="amzn" 4 | ID_LIKE="rhel fedora" 5 | VERSION_ID="2017.03" 6 | PRETTY_NAME="Amazon Linux AMI 2017.03" 7 | ANSI_COLOR="0;33" 8 | CPE_NAME="cpe:/o:amazon:linux:2017.03:ga" 9 | HOME_URL="http://aws.amazon.com/amazon-linux-ami/" 10 | -------------------------------------------------------------------------------- /providers/linux/testdata/amazon2017.03/etc/system-release: -------------------------------------------------------------------------------- 1 | Amazon Linux AMI release 2017.03 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/archlinux/etc/arch-release: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/go-sysinfo/4f2a4c67e96568b6f10a07ba716a19f05d72e13a/providers/linux/testdata/archlinux/etc/arch-release -------------------------------------------------------------------------------- /providers/linux/testdata/archlinux/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/archlinux/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME="Arch Linux ARM" 2 | PRETTY_NAME="Arch Linux ARM" 3 | ID=archarm 4 | ID_LIKE=arch 5 | BUILD_ID=rolling 6 | ANSI_COLOR="38;2;23;147;209" 7 | HOME_URL="https://archlinuxarm.org/" 8 | DOCUMENTATION_URL="https://archlinuxarm.org/wiki" 9 | SUPPORT_URL="https://archlinuxarm.org/forum" 10 | BUG_REPORT_URL="https://github.com/archlinuxarm/PKGBUILDs/issues" 11 | LOGO=archlinux-logo 12 | -------------------------------------------------------------------------------- /providers/linux/testdata/centos6/etc/centos-release: -------------------------------------------------------------------------------- 1 | CentOS release 6.9 (Final) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/centos6/etc/redhat-release: -------------------------------------------------------------------------------- 1 | centos-release -------------------------------------------------------------------------------- /providers/linux/testdata/centos6/etc/system-release: -------------------------------------------------------------------------------- 1 | centos-release -------------------------------------------------------------------------------- /providers/linux/testdata/centos7.8/etc/centos-release: -------------------------------------------------------------------------------- 1 | CentOS Linux release 7.8.2003 (Core) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/centos7.8/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/centos7.8/etc/redhat-release: -------------------------------------------------------------------------------- 1 | centos-release -------------------------------------------------------------------------------- /providers/linux/testdata/centos7.8/etc/system-release: -------------------------------------------------------------------------------- 1 | centos-release -------------------------------------------------------------------------------- /providers/linux/testdata/centos7.8/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME="CentOS Linux" 2 | VERSION="7 (Core)" 3 | ID="centos" 4 | ID_LIKE="rhel fedora" 5 | VERSION_ID="7" 6 | PRETTY_NAME="CentOS Linux 7 (Core)" 7 | ANSI_COLOR="0;31" 8 | CPE_NAME="cpe:/o:centos:centos:7" 9 | HOME_URL="https://www.centos.org/" 10 | BUG_REPORT_URL="https://bugs.centos.org/" 11 | 12 | CENTOS_MANTISBT_PROJECT="CentOS-7" 13 | CENTOS_MANTISBT_PROJECT_VERSION="7" 14 | REDHAT_SUPPORT_PRODUCT="centos" 15 | REDHAT_SUPPORT_PRODUCT_VERSION="7" 16 | 17 | -------------------------------------------------------------------------------- /providers/linux/testdata/centos7/etc/centos-release: -------------------------------------------------------------------------------- 1 | CentOS Linux release 7.4.1708 (Core) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/centos7/etc/os-release: -------------------------------------------------------------------------------- 1 | NAME="CentOS Linux" 2 | VERSION="7 (Core)" 3 | ID="centos" 4 | ID_LIKE="rhel fedora" 5 | VERSION_ID="7" 6 | PRETTY_NAME="CentOS Linux 7 (Core)" 7 | ANSI_COLOR="0;31" 8 | CPE_NAME="cpe:/o:centos:centos:7" 9 | HOME_URL="https://www.centos.org/" 10 | BUG_REPORT_URL="https://bugs.centos.org/" 11 | 12 | CENTOS_MANTISBT_PROJECT="CentOS-7" 13 | CENTOS_MANTISBT_PROJECT_VERSION="7" 14 | REDHAT_SUPPORT_PRODUCT="centos" 15 | REDHAT_SUPPORT_PRODUCT_VERSION="7" 16 | 17 | -------------------------------------------------------------------------------- /providers/linux/testdata/centos7/etc/redhat-release: -------------------------------------------------------------------------------- 1 | centos-release -------------------------------------------------------------------------------- /providers/linux/testdata/centos7/etc/system-release: -------------------------------------------------------------------------------- 1 | centos-release -------------------------------------------------------------------------------- /providers/linux/testdata/debian6/etc/debian_version: -------------------------------------------------------------------------------- 1 | 6.0.10 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/debian9/etc/debian_version: -------------------------------------------------------------------------------- 1 | 9.3 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/debian9/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/debian9/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | PRETTY_NAME="Debian GNU/Linux 9 (stretch)" 2 | NAME="Debian GNU/Linux" 3 | VERSION_ID="9" 4 | VERSION="9 (stretch)" 5 | ID=debian 6 | HOME_URL="https://www.debian.org/" 7 | SUPPORT_URL="https://www.debian.org/support" 8 | BUG_REPORT_URL="https://bugs.debian.org/" 9 | -------------------------------------------------------------------------------- /providers/linux/testdata/dir_release/etc/aaa-release/.dir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/go-sysinfo/4f2a4c67e96568b6f10a07ba716a19f05d72e13a/providers/linux/testdata/dir_release/etc/aaa-release/.dir -------------------------------------------------------------------------------- /providers/linux/testdata/dir_release/etc/centos-release: -------------------------------------------------------------------------------- 1 | CentOS Linux release 7.4.1708 (Core) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/dir_release/etc/os-release: -------------------------------------------------------------------------------- 1 | NAME="CentOS Linux" 2 | VERSION="7 (Core)" 3 | ID="centos" 4 | ID_LIKE="rhel fedora" 5 | VERSION_ID="7" 6 | PRETTY_NAME="CentOS Linux 7 (Core)" 7 | ANSI_COLOR="0;31" 8 | CPE_NAME="cpe:/o:centos:centos:7" 9 | HOME_URL="https://www.centos.org/" 10 | BUG_REPORT_URL="https://bugs.centos.org/" 11 | 12 | CENTOS_MANTISBT_PROJECT="CentOS-7" 13 | CENTOS_MANTISBT_PROJECT_VERSION="7" 14 | REDHAT_SUPPORT_PRODUCT="centos" 15 | REDHAT_SUPPORT_PRODUCT_VERSION="7" 16 | 17 | -------------------------------------------------------------------------------- /providers/linux/testdata/dir_release/etc/redhat-release: -------------------------------------------------------------------------------- 1 | centos-release -------------------------------------------------------------------------------- /providers/linux/testdata/dir_release/etc/system-release: -------------------------------------------------------------------------------- 1 | centos-release -------------------------------------------------------------------------------- /providers/linux/testdata/fedora30/etc/fedora-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/fedora-release -------------------------------------------------------------------------------- /providers/linux/testdata/fedora30/etc/machine-id: -------------------------------------------------------------------------------- 1 | 144d62edb0f142458f320852f495b72c 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/fedora30/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/fedora30/etc/redhat-release: -------------------------------------------------------------------------------- 1 | fedora-release -------------------------------------------------------------------------------- /providers/linux/testdata/fedora30/etc/system-release: -------------------------------------------------------------------------------- 1 | fedora-release -------------------------------------------------------------------------------- /providers/linux/testdata/fedora30/proc/net/netstat: -------------------------------------------------------------------------------- 1 | TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed EmbryonicRsts PruneCalled RcvPruned OfoPruned OutOfWindowIcmps LockDroppedIcmps ArpFilter TW TWRecycled TWKilled PAWSActive PAWSEstab DelayedACKs DelayedACKLocked DelayedACKLost ListenOverflows ListenDrops TCPHPHits TCPPureAcks TCPHPAcks TCPRenoRecovery TCPSackRecovery TCPSACKReneging TCPSACKReorder TCPRenoReorder TCPTSReorder TCPFullUndo TCPPartialUndo TCPDSACKUndo TCPLossUndo TCPLostRetransmit TCPRenoFailures TCPSackFailures TCPLossFailures TCPFastRetrans TCPSlowStartRetrans TCPTimeouts TCPLossProbes TCPLossProbeRecovery TCPRenoRecoveryFail TCPSackRecoveryFail TCPRcvCollapsed TCPBacklogCoalesce TCPDSACKOldSent TCPDSACKOfoSent TCPDSACKRecv TCPDSACKOfoRecv TCPAbortOnData TCPAbortOnClose TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger TCPAbortFailed TCPMemoryPressures TCPMemoryPressuresChrono TCPSACKDiscard TCPDSACKIgnoredOld TCPDSACKIgnoredNoUndo TCPSpuriousRTOs TCPMD5NotFound TCPMD5Unexpected TCPMD5Failure TCPSackShifted TCPSackMerged TCPSackShiftFallback TCPBacklogDrop PFMemallocDrop TCPMinTTLDrop TCPDeferAcceptDrop IPReversePathFilter TCPTimeWaitOverflow TCPReqQFullDoCookies TCPReqQFullDrop TCPRetransFail TCPRcvCoalesce TCPOFOQueue TCPOFODrop TCPOFOMerge TCPChallengeACK TCPSYNChallenge TCPFastOpenActive TCPFastOpenActiveFail TCPFastOpenPassive TCPFastOpenPassiveFail TCPFastOpenListenOverflow TCPFastOpenCookieReqd TCPFastOpenBlackhole TCPSpuriousRtxHostQueues BusyPollRxPackets TCPAutoCorking TCPFromZeroWindowAdv TCPToZeroWindowAdv TCPWantZeroWindowAdv TCPSynRetrans TCPOrigDataSent TCPHystartTrainDetect TCPHystartTrainCwnd TCPHystartDelayDetect TCPHystartDelayCwnd TCPACKSkippedSynRecv TCPACKSkippedPAWS TCPACKSkippedSeq TCPACKSkippedFinWait2 TCPACKSkippedTimeWait TCPACKSkippedChallenge TCPWinProbe TCPKeepAlive TCPMTUPFail TCPMTUPSuccess TCPDelivered TCPDeliveredCE TCPAckCompressed TCPZeroWindowDrop TCPRcvQDrop 2 | TcpExt: 0 0 2 2 0 0 0 8 0 0 934 0 0 0 15 287657 86 1174 0 0 13549524 3703992 2542609 0 118 0 467 0 168 3 39 35 359 1387 0 5 1 3781 2 1955 7458 366 0 2 0 278312 1238 11 4216 2 1494 272 0 77 0 0 0 0 82 186 1869 3 0 0 0 25682 9680 660 0 0 0 0 0 0 0 0 0 3548522 127400 0 10 0 0 0 0 0 0 0 0 0 0 0 104 883 883 71010 257 29255516 148 3243 18 2382 3 1 3 0 0 0 0 204720 0 0 29260768 0 109908 0 0 3 | IpExt: InNoRoutes InTruncatedPkts InMcastPkts OutMcastPkts InBcastPkts OutBcastPkts InOctets OutOctets InMcastOctets OutMcastOctets InBcastOctets OutBcastOctets InCsumErrors InNoECTPkts InECT1Pkts InECT0Pkts InCEPkts ReasmOverlaps 4 | IpExt: 0 0 0 0 601711 0 102243038277 39839396260 0 0 143425103 0 0 76854883 0 3160941 0 0 5 | -------------------------------------------------------------------------------- /providers/linux/testdata/fedora30/proc/net/snmp: -------------------------------------------------------------------------------- 1 | Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates 2 | Ip: 1 64 23685774 0 19 22122 0 0 22328773 16478755 1 4 0 0 0 0 0 0 0 3 | Icmp: InMsgs InErrors InCsumErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps 4 | Icmp: 487 1 0 486 0 0 0 0 1 0 0 0 0 0 571 0 570 0 0 0 0 0 1 0 0 0 0 5 | IcmpMsg: InType3 InType8 OutType0 OutType3 6 | IcmpMsg: 486 1 1 570 7 | Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts InCsumErrors 8 | Tcp: 1 200 120000 -1 4224 885 1408 343 8 22311083 35810350 10752 0 6286 0 9 | Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors IgnoredMulti 10 | Udp: 17225 34 0 17301 0 0 0 0 11 | UdpLite: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors IgnoredMulti 12 | UdpLite: 0 0 0 0 0 0 0 0 13 | -------------------------------------------------------------------------------- /providers/linux/testdata/fedora30/proc/stat: -------------------------------------------------------------------------------- 1 | cpu 31608779 223223 15924288 1134746753 223880 4348430 1995355 266903 0 0 2 | cpu0 7929502 52284 3994607 283776341 58002 1041339 448737 62980 0 0 3 | cpu1 7871778 55337 3986872 283642724 50819 1099882 580838 68839 0 0 4 | cpu2 7951421 68162 4002718 283618789 59074 1071996 526388 65991 0 0 5 | cpu3 7856076 47438 3940090 283708897 55983 1135211 439391 69093 0 0 6 | intr 3649757765 110 9 0 0 0 0 0 0 1 0 1493876 32 18 0 0 2918021 0 0 0 0 0 0 0 0 0 0 0 8660478 0 19957110 246 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 | ctxt 5607775026 8 | btime 1571459083 9 | processes 4891735 10 | procs_running 1 11 | procs_blocked 0 12 | softirq 1934569580 0 876016023 1299 20736488 9710454 0 130 357152191 25831 670927164 13 | -------------------------------------------------------------------------------- /providers/linux/testdata/fedora30/usr/lib/fedora-release: -------------------------------------------------------------------------------- 1 | Fedora release 30 (Thirty) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/fedora30/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME=Fedora 2 | VERSION="30 (Container Image)" 3 | ID=fedora 4 | VERSION_ID=30 5 | VERSION_CODENAME="" 6 | PLATFORM_ID="platform:f30" 7 | PRETTY_NAME="Fedora 30 (Container Image)" 8 | ANSI_COLOR="0;34" 9 | LOGO=fedora-logo-icon 10 | CPE_NAME="cpe:/o:fedoraproject:fedora:30" 11 | HOME_URL="https://fedoraproject.org/" 12 | DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f30/system-administrators-guide/" 13 | SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help" 14 | BUG_REPORT_URL="https://bugzilla.redhat.com/" 15 | REDHAT_BUGZILLA_PRODUCT="Fedora" 16 | REDHAT_BUGZILLA_PRODUCT_VERSION=30 17 | REDHAT_SUPPORT_PRODUCT="Fedora" 18 | REDHAT_SUPPORT_PRODUCT_VERSION=30 19 | PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy" 20 | VARIANT="Container Image" 21 | VARIANT_ID=container 22 | -------------------------------------------------------------------------------- /providers/linux/testdata/fedora30/usr/lib/redhat-release: -------------------------------------------------------------------------------- 1 | Fedora release 30 (Thirty) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/fedora30/usr/lib/system-release: -------------------------------------------------------------------------------- 1 | Fedora release 30 (Thirty) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/fedora40/proc/33925/stat: -------------------------------------------------------------------------------- 1 | 33925 (rpc.statd) S 1 33925 33925 0 -1 4194624 104 0 0 0 1 0 0 0 20 0 1 0 840035 10326016 664 18446744073709551615 1 1 0 0 0 0 0 69632 18947 0 0 0 17 3 0 0 0 0 0 0 0 0 0 0 0 0 0 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/linuxmint20/etc/lsb-release: -------------------------------------------------------------------------------- 1 | DISTRIB_ID=LinuxMint 2 | DISTRIB_RELEASE=20 3 | DISTRIB_CODENAME=ulyana 4 | DISTRIB_DESCRIPTION="Linux Mint 20 Ulyana" 5 | -------------------------------------------------------------------------------- /providers/linux/testdata/linuxmint20/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/linuxmint20/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME="Linux Mint" 2 | VERSION="20 (Ulyana)" 3 | ID=linuxmint 4 | ID_LIKE=ubuntu 5 | PRETTY_NAME="Linux Mint 20" 6 | VERSION_ID="20" 7 | HOME_URL="https://www.linuxmint.com/" 8 | SUPPORT_URL="https://forums.linuxmint.com/" 9 | BUG_REPORT_URL="http://linuxmint-troubleshooting-guide.readthedocs.io/en/latest/" 10 | PRIVACY_POLICY_URL="https://www.linuxmint.com/" 11 | VERSION_CODENAME=ulyana 12 | UBUNTU_CODENAME=focal 13 | -------------------------------------------------------------------------------- /providers/linux/testdata/manjaro23/etc/arch-release: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/go-sysinfo/4f2a4c67e96568b6f10a07ba716a19f05d72e13a/providers/linux/testdata/manjaro23/etc/arch-release -------------------------------------------------------------------------------- /providers/linux/testdata/manjaro23/etc/lsb-release: -------------------------------------------------------------------------------- 1 | DISTRIB_ID=Manjaro-ARM 2 | DISTRIB_RELEASE=23.02 3 | DISTRIB_CODENAME= 4 | DISTRIB_DESCRIPTION="Manjaro ARM Linux" 5 | -------------------------------------------------------------------------------- /providers/linux/testdata/manjaro23/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/manjaro23/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME="Manjaro ARM" 2 | ID="manjaro-arm" 3 | ID_LIKE="manjaro arch" 4 | PRETTY_NAME="Manjaro ARM" 5 | ANSI_COLOR="1;32" 6 | HOME_URL="https://www.manjaro.org/" 7 | SUPPORT_URL="https://forum.manjaro.org/c/arm/" 8 | LOGO=manjarolinux 9 | -------------------------------------------------------------------------------- /providers/linux/testdata/openeuler20.03/etc/openEuler-release: -------------------------------------------------------------------------------- 1 | openEuler release 20.03 (LTS-SP3) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/openeuler20.03/etc/os-release: -------------------------------------------------------------------------------- 1 | NAME="openEuler" 2 | VERSION="20.03 (LTS-SP3)" 3 | ID="openEuler" 4 | VERSION_ID="20.03" 5 | PRETTY_NAME="openEuler 20.03 (LTS-SP3)" 6 | ANSI_COLOR="0;31" 7 | 8 | -------------------------------------------------------------------------------- /providers/linux/testdata/openeuler20.03/etc/system-release: -------------------------------------------------------------------------------- 1 | openEuler-release -------------------------------------------------------------------------------- /providers/linux/testdata/opensuse-leap15.4/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/opensuse-leap15.4/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME="openSUSE Leap" 2 | VERSION="15.4" 3 | ID="opensuse-leap" 4 | ID_LIKE="suse opensuse" 5 | VERSION_ID="15.4" 6 | PRETTY_NAME="openSUSE Leap 15.4" 7 | ANSI_COLOR="0;32" 8 | CPE_NAME="cpe:/o:opensuse:leap:15.4" 9 | BUG_REPORT_URL="https://bugs.opensuse.org" 10 | HOME_URL="https://www.opensuse.org/" 11 | DOCUMENTATION_URL="https://en.opensuse.org/Portal:Leap" 12 | LOGO="distributor-logo-Leap" 13 | -------------------------------------------------------------------------------- /providers/linux/testdata/opensuse-tumbleweed/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/opensuse-tumbleweed/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME="openSUSE Tumbleweed" 2 | # VERSION="20230108" 3 | ID="opensuse-tumbleweed" 4 | ID_LIKE="opensuse suse" 5 | VERSION_ID="20230108" 6 | PRETTY_NAME="openSUSE Tumbleweed" 7 | ANSI_COLOR="0;32" 8 | CPE_NAME="cpe:/o:opensuse:tumbleweed:20230108" 9 | BUG_REPORT_URL="https://bugs.opensuse.org" 10 | HOME_URL="https://www.opensuse.org/" 11 | DOCUMENTATION_URL="https://en.opensuse.org/Portal:Tumbleweed" 12 | LOGO="distributor-logo-Tumbleweed" 13 | -------------------------------------------------------------------------------- /providers/linux/testdata/oraclelinux7/etc/oracle-release: -------------------------------------------------------------------------------- 1 | Oracle Linux Server release 7.9 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/oraclelinux7/etc/os-release: -------------------------------------------------------------------------------- 1 | NAME="Oracle Linux Server" 2 | VERSION="7.9" 3 | ID="ol" 4 | ID_LIKE="fedora" 5 | VARIANT="Server" 6 | VARIANT_ID="server" 7 | VERSION_ID="7.9" 8 | PRETTY_NAME="Oracle Linux Server 7.9" 9 | ANSI_COLOR="0;31" 10 | CPE_NAME="cpe:/o:oracle:linux:7:9:server" 11 | HOME_URL="https://linux.oracle.com/" 12 | BUG_REPORT_URL="https://bugzilla.oracle.com/" 13 | 14 | ORACLE_BUGZILLA_PRODUCT="Oracle Linux 7" 15 | ORACLE_BUGZILLA_PRODUCT_VERSION=7.9 16 | ORACLE_SUPPORT_PRODUCT="Oracle Linux" 17 | ORACLE_SUPPORT_PRODUCT_VERSION=7.9 18 | -------------------------------------------------------------------------------- /providers/linux/testdata/oraclelinux7/etc/redhat-release: -------------------------------------------------------------------------------- 1 | Red Hat Enterprise Linux Server release 7.9 (Maipo) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/oraclelinux7/etc/system-release: -------------------------------------------------------------------------------- 1 | oracle-release -------------------------------------------------------------------------------- /providers/linux/testdata/raspbian9/etc/debian_version: -------------------------------------------------------------------------------- 1 | 9.4 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/raspbian9/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/raspbian9/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)" 2 | NAME="Raspbian GNU/Linux" 3 | VERSION_ID="9" 4 | VERSION="9 (stretch)" 5 | ID=raspbian 6 | ID_LIKE=debian 7 | HOME_URL="http://www.raspbian.org/" 8 | SUPPORT_URL="http://www.raspbian.org/RaspbianForums" 9 | BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs" 10 | -------------------------------------------------------------------------------- /providers/linux/testdata/redhat10/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/redhat10/etc/redhat-release: -------------------------------------------------------------------------------- 1 | Red Hat Enterprise Linux release 10.0 (Coughlan) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/redhat10/etc/system-release: -------------------------------------------------------------------------------- 1 | redhat-release -------------------------------------------------------------------------------- /providers/linux/testdata/redhat10/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME="Red Hat Enterprise Linux" 2 | VERSION="10.0 (Coughlan)" 3 | ID="rhel" 4 | ID_LIKE="centos fedora" 5 | VERSION_ID="10.0" 6 | PLATFORM_ID="platform:el10" 7 | PRETTY_NAME="Red Hat Enterprise Linux 10.0 (Coughlan)" 8 | ANSI_COLOR="0;31" 9 | LOGO="fedora-logo-icon" 10 | CPE_NAME="cpe:/o:redhat:enterprise_linux:10::baseos" 11 | HOME_URL="https://www.redhat.com/" 12 | VENDOR_NAME="Red Hat" 13 | VENDOR_URL="https://www.redhat.com/" 14 | DOCUMENTATION_URL="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/10" 15 | BUG_REPORT_URL="https://issues.redhat.com/" 16 | 17 | REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 10" 18 | REDHAT_BUGZILLA_PRODUCT_VERSION=10.0 19 | REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux" 20 | REDHAT_SUPPORT_PRODUCT_VERSION="10.0" 21 | -------------------------------------------------------------------------------- /providers/linux/testdata/redhat7/etc/os-release: -------------------------------------------------------------------------------- 1 | NAME="Red Hat Enterprise Linux Server" 2 | VERSION="7.6 (Maipo)" 3 | ID="rhel" 4 | ID_LIKE="fedora" 5 | VARIANT="Server" 6 | VARIANT_ID="server" 7 | VERSION_ID="7.6" 8 | PRETTY_NAME="Red Hat Enterprise Linux Server 7.6 (Maipo)" 9 | ANSI_COLOR="0;31" 10 | CPE_NAME="cpe:/o:redhat:enterprise_linux:7.6:GA:server" 11 | HOME_URL="https://www.redhat.com/" 12 | BUG_REPORT_URL="https://bugzilla.redhat.com/" 13 | 14 | REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 7" 15 | REDHAT_BUGZILLA_PRODUCT_VERSION=7.6 16 | REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux" 17 | REDHAT_SUPPORT_PRODUCT_VERSION="7.6" 18 | -------------------------------------------------------------------------------- /providers/linux/testdata/redhat7/etc/redhat-release: -------------------------------------------------------------------------------- 1 | Red Hat Enterprise Linux Server release 7.6 (Maipo) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/redhat7/etc/system-release: -------------------------------------------------------------------------------- 1 | redhat-release -------------------------------------------------------------------------------- /providers/linux/testdata/redhat9/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/redhat9/etc/redhat-release: -------------------------------------------------------------------------------- 1 | Red Hat Enterprise Linux release 9.0 (Plow) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/redhat9/etc/system-release: -------------------------------------------------------------------------------- 1 | redhat-release -------------------------------------------------------------------------------- /providers/linux/testdata/redhat9/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME="Red Hat Enterprise Linux" 2 | VERSION="9.0 (Plow)" 3 | ID="rhel" 4 | ID_LIKE="fedora" 5 | VERSION_ID="9.0" 6 | PLATFORM_ID="platform:el9" 7 | PRETTY_NAME="Red Hat Enterprise Linux 9.0 (Plow)" 8 | ANSI_COLOR="0;31" 9 | LOGO="fedora-logo-icon" 10 | CPE_NAME="cpe:/o:redhat:enterprise_linux:9::baseos" 11 | HOME_URL="https://www.redhat.com/" 12 | DOCUMENTATION_URL="https://access.redhat.com/documentation/red_hat_enterprise_linux/9/" 13 | BUG_REPORT_URL="https://bugzilla.redhat.com/" 14 | 15 | REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 9" 16 | REDHAT_BUGZILLA_PRODUCT_VERSION=9.0 17 | REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux" 18 | REDHAT_SUPPORT_PRODUCT_VERSION="9.0" 19 | -------------------------------------------------------------------------------- /providers/linux/testdata/rockylinux9/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/rockylinux9/etc/redhat-release: -------------------------------------------------------------------------------- 1 | rocky-release -------------------------------------------------------------------------------- /providers/linux/testdata/rockylinux9/etc/rocky-release: -------------------------------------------------------------------------------- 1 | Rocky Linux release 9.0 (Blue Onyx) 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/rockylinux9/etc/system-release: -------------------------------------------------------------------------------- 1 | rocky-release -------------------------------------------------------------------------------- /providers/linux/testdata/rockylinux9/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME="Rocky Linux" 2 | VERSION="9.0 (Blue Onyx)" 3 | ID="rocky" 4 | ID_LIKE="rhel centos fedora" 5 | VERSION_ID="9.0" 6 | PLATFORM_ID="platform:el9" 7 | PRETTY_NAME="Rocky Linux 9.0 (Blue Onyx)" 8 | ANSI_COLOR="0;32" 9 | LOGO="fedora-logo-icon" 10 | CPE_NAME="cpe:/o:rocky:rocky:9::baseos" 11 | HOME_URL="https://rockylinux.org/" 12 | BUG_REPORT_URL="https://bugs.rockylinux.org/" 13 | ROCKY_SUPPORT_PRODUCT="Rocky-Linux-9" 14 | ROCKY_SUPPORT_PRODUCT_VERSION="9.0" 15 | REDHAT_SUPPORT_PRODUCT="Rocky Linux" 16 | REDHAT_SUPPORT_PRODUCT_VERSION="9.0" 17 | -------------------------------------------------------------------------------- /providers/linux/testdata/sled15sp5/etc/os-release: -------------------------------------------------------------------------------- 1 | NAME="SLED" 2 | VERSION="15-SP5" 3 | VERSION_ID="15.5" 4 | PRETTY_NAME="SUSE Linux Enterprise Desktop 15 SP5" 5 | ID="sled" 6 | ID_LIKE="suse" 7 | ANSI_COLOR="0;32" 8 | CPE_NAME="cpe:/o:suse:sled:15:sp5" 9 | DOCUMENTATION_URL="https://documentation.suse.com/" 10 | -------------------------------------------------------------------------------- /providers/linux/testdata/sles15sp5/etc/os-release: -------------------------------------------------------------------------------- 1 | NAME="SLES" 2 | VERSION="15-SP5" 3 | VERSION_ID="15.5" 4 | PRETTY_NAME="SUSE Linux Enterprise Server 15 SP5" 5 | ID="sles" 6 | ID_LIKE="suse" 7 | ANSI_COLOR="0;32" 8 | CPE_NAME="cpe:/o:suse:sles:15:sp5" 9 | DOCUMENTATION_URL="https://documentation.suse.com/" 10 | -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu1204/etc/lsb-release: -------------------------------------------------------------------------------- 1 | DISTRIB_ID=Ubuntu 2 | DISTRIB_RELEASE=12.04 3 | DISTRIB_CODENAME=precise 4 | DISTRIB_DESCRIPTION="Ubuntu 12.04.5 LTS" 5 | -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu1204/etc/os-release: -------------------------------------------------------------------------------- 1 | NAME="Ubuntu" 2 | VERSION="12.04.5 LTS, Precise Pangolin" 3 | ID=ubuntu 4 | ID_LIKE=debian 5 | PRETTY_NAME="Ubuntu precise (12.04.5 LTS)" 6 | VERSION_ID="12.04" 7 | -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu1404/etc/debian_version: -------------------------------------------------------------------------------- 1 | jessie/sid 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu1404/etc/lsb-release: -------------------------------------------------------------------------------- 1 | DISTRIB_ID=Ubuntu 2 | DISTRIB_RELEASE=14.04 3 | DISTRIB_CODENAME=trusty 4 | DISTRIB_DESCRIPTION="Ubuntu 14.04.5 LTS" 5 | -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu1404/etc/os-release: -------------------------------------------------------------------------------- 1 | NAME="Ubuntu" 2 | VERSION="14.04.5 LTS, Trusty Tahr" 3 | ID=ubuntu 4 | ID_LIKE=debian 5 | PRETTY_NAME="Ubuntu 14.04.5 LTS" 6 | VERSION_ID="14.04" 7 | HOME_URL="http://www.ubuntu.com/" 8 | SUPPORT_URL="http://help.ubuntu.com/" 9 | BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" 10 | -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu1710/etc/debian_version: -------------------------------------------------------------------------------- 1 | stretch/sid 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu1710/etc/lsb-release: -------------------------------------------------------------------------------- 1 | DISTRIB_ID=Ubuntu 2 | DISTRIB_RELEASE=17.10 3 | DISTRIB_CODENAME=artful 4 | DISTRIB_DESCRIPTION="Ubuntu 17.10" 5 | -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu1710/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu1710/proc/loadavg: -------------------------------------------------------------------------------- 1 | 1.55 1.74 1.73 2/1318 46377 2 | -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu1710/proc/meminfo: -------------------------------------------------------------------------------- 1 | MemTotal: 4042048 kB 2 | MemFree: 2551468 kB 3 | MemAvailable: 3651940 kB 4 | Buffers: 33316 kB 5 | Cached: 1248984 kB 6 | SwapCached: 0 kB 7 | Active: 210556 kB 8 | Inactive: 1181880 kB 9 | Active(anon): 111080 kB 10 | Inactive(anon): 660 kB 11 | Active(file): 99476 kB 12 | Inactive(file): 1181220 kB 13 | Unevictable: 0 kB 14 | Mlocked: 0 kB 15 | SwapTotal: 1048572 kB 16 | SwapFree: 1048572 kB 17 | Dirty: 0 kB 18 | Writeback: 0 kB 19 | AnonPages: 110216 kB 20 | Mapped: 91028 kB 21 | Shmem: 1536 kB 22 | Slab: 68708 kB 23 | SReclaimable: 49852 kB 24 | SUnreclaim: 18856 kB 25 | KernelStack: 5632 kB 26 | PageTables: 1652 kB 27 | NFS_Unstable: 0 kB 28 | Bounce: 0 kB 29 | WritebackTmp: 0 kB 30 | CommitLimit: 3069596 kB 31 | Committed_AS: 418744 kB 32 | VmallocTotal: 34359738367 kB 33 | VmallocUsed: 0 kB 34 | VmallocChunk: 0 kB 35 | AnonHugePages: 0 kB 36 | ShmemHugePages: 0 kB 37 | ShmemPmdMapped: 0 kB 38 | HugePages_Total: 0 39 | HugePages_Free: 0 40 | HugePages_Rsvd: 0 41 | HugePages_Surp: 0 42 | Hugepagesize: 2048 kB 43 | DirectMap4k: 32172 kB 44 | DirectMap2M: 3112960 kB 45 | DirectMap1G: 3145728 kB 46 | -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu1710/proc/stat: -------------------------------------------------------------------------------- 1 | cpu 2277627 0 1464379 1303119903 200372 0 27401 0 0 0 2 | cpu0 593545 0 431398 325286468 50343 0 14435 0 0 0 3 | cpu1 552949 0 341664 325964281 47304 0 5468 0 0 0 4 | cpu2 568758 0 359758 325909025 49470 0 3791 0 0 0 5 | cpu3 562375 0 331559 325960129 53255 0 3707 0 0 0 6 | intr 421434840 27 0 0 0 1100 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 22085 3951831 3272 52 0 2035574 1 0 236 0 25512135 27798885 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 | ctxt 888692448 8 | btime 1518838073 9 | processes 754326 10 | procs_running 3 11 | procs_blocked 0 12 | softirq 162361882 0 61330255 3576 5818933 3941332 0 1 60746100 0 30521685 13 | -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu1710/proc/vmstat: -------------------------------------------------------------------------------- 1 | nr_free_pages 50545 2 | nr_zone_inactive_anon 66 3 | nr_zone_active_anon 26799 4 | nr_zone_inactive_file 31849 5 | nr_zone_active_file 94164 6 | nr_zone_unevictable 0 7 | nr_zone_write_pending 7 8 | nr_mlock 0 9 | nr_page_table_pages 1225 10 | nr_kernel_stack 2496 11 | nr_bounce 0 12 | nr_zspages 0 13 | nr_free_cma 0 14 | numa_hit 44470329 15 | numa_miss 0 16 | numa_foreign 0 17 | numa_interleave 16296 18 | numa_local 44470329 19 | numa_other 0 20 | nr_inactive_anon 66 21 | nr_active_anon 26799 22 | nr_inactive_file 31849 23 | nr_active_file 94164 24 | nr_unevictable 0 25 | nr_slab_reclaimable 31763 26 | nr_slab_unreclaimable 10329 27 | nr_isolated_anon 0 28 | nr_isolated_file 0 29 | workingset_refault 302914 30 | workingset_activate 108959 31 | workingset_nodereclaim 6422 32 | nr_anon_pages 26218 33 | nr_mapped 8641 34 | nr_file_pages 126182 35 | nr_dirty 7 36 | nr_writeback 0 37 | nr_writeback_temp 0 38 | nr_shmem 169 39 | nr_shmem_hugepages 0 40 | nr_shmem_pmdmapped 0 41 | nr_anon_transparent_hugepages 0 42 | nr_unstable 0 43 | nr_vmscan_write 35 44 | nr_vmscan_immediate_reclaim 9832 45 | nr_dirtied 7188920 46 | nr_written 6479005 47 | nr_dirty_threshold 31736 48 | nr_dirty_background_threshold 15848 49 | pgpgin 17010697 50 | pgpgout 27734292 51 | pswpin 0 52 | pswpout 0 53 | pgalloc_dma 241378 54 | pgalloc_dma32 45788683 55 | pgalloc_normal 0 56 | pgalloc_movable 0 57 | allocstall_dma 0 58 | allocstall_dma32 0 59 | allocstall_normal 5 60 | allocstall_movable 8 61 | pgskip_dma 0 62 | pgskip_dma32 0 63 | pgskip_normal 0 64 | pgskip_movable 0 65 | pgfree 46085578 66 | pgactivate 2475069 67 | pgdeactivate 636658 68 | pglazyfree 9426 69 | pgfault 46777498 70 | pgmajfault 19204 71 | pglazyfreed 0 72 | pgrefill 707817 73 | pgsteal_kswapd 3798890 74 | pgsteal_direct 1466 75 | pgscan_kswapd 3868525 76 | pgscan_direct 1483 77 | pgscan_direct_throttle 0 78 | zone_reclaim_failed 0 79 | pginodesteal 1710 80 | slabs_scanned 8348560 81 | kswapd_inodesteal 3142001 82 | kswapd_low_wmark_hit_quickly 541 83 | kswapd_high_wmark_hit_quickly 332 84 | pageoutrun 1492 85 | pgrotated 29725 86 | drop_pagecache 0 87 | drop_slab 0 88 | oom_kill 0 89 | numa_pte_updates 0 90 | numa_huge_pte_updates 0 91 | numa_hint_faults 0 92 | numa_hint_faults_local 0 93 | numa_pages_migrated 0 94 | pgmigrate_success 4539 95 | pgmigrate_fail 156 96 | compact_migrate_scanned 9331 97 | compact_free_scanned 136266 98 | compact_isolated 9407 99 | compact_stall 2 100 | compact_fail 0 101 | compact_success 2 102 | compact_daemon_wake 21 103 | compact_daemon_migrate_scanned 8311 104 | compact_daemon_free_scanned 107086 105 | htlb_buddy_alloc_success 0 106 | htlb_buddy_alloc_fail 0 107 | unevictable_pgs_culled 19 108 | unevictable_pgs_scanned 0 109 | unevictable_pgs_rescued 304 110 | unevictable_pgs_mlocked 304 111 | unevictable_pgs_munlocked 304 112 | unevictable_pgs_cleared 0 113 | unevictable_pgs_stranded 0 114 | thp_fault_alloc 2 115 | thp_fault_fallback 0 116 | thp_collapse_alloc 2 117 | thp_collapse_alloc_failed 0 118 | thp_file_alloc 0 119 | thp_file_mapped 0 120 | thp_split_page 0 121 | thp_split_page_failed 0 122 | thp_deferred_split_page 4 123 | thp_split_pmd 1 124 | thp_split_pud 0 125 | thp_zero_page_alloc 0 126 | thp_zero_page_alloc_failed 0 127 | thp_swpout 0 128 | thp_swpout_fallback 0 129 | balloon_inflate 0 130 | balloon_deflate 0 131 | balloon_migrate 0 132 | swap_ra 0 133 | swap_ra_hit 0 -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu1710/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME="Ubuntu" 2 | VERSION="17.10 (Artful Aardvark)" 3 | ID=ubuntu 4 | ID_LIKE=debian 5 | PRETTY_NAME="Ubuntu 17.10" 6 | VERSION_ID="17.10" 7 | HOME_URL="https://www.ubuntu.com/" 8 | SUPPORT_URL="https://help.ubuntu.com/" 9 | BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" 10 | PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" 11 | VERSION_CODENAME=artful 12 | UBUNTU_CODENAME=artful 13 | -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu2204/etc/lsb-release: -------------------------------------------------------------------------------- 1 | DISTRIB_ID=Ubuntu 2 | DISTRIB_RELEASE=22.04 3 | DISTRIB_CODENAME=jammy 4 | DISTRIB_DESCRIPTION="Ubuntu 22.04 LTS" 5 | -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu2204/etc/os-release: -------------------------------------------------------------------------------- 1 | ../usr/lib/os-release -------------------------------------------------------------------------------- /providers/linux/testdata/ubuntu2204/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | PRETTY_NAME="Ubuntu 22.04 LTS" 2 | NAME="Ubuntu" 3 | VERSION_ID="22.04" 4 | VERSION="22.04 LTS (Jammy Jellyfish)" 5 | VERSION_CODENAME=jammy 6 | ID=ubuntu 7 | ID_LIKE=debian 8 | HOME_URL="https://www.ubuntu.com/" 9 | SUPPORT_URL="https://help.ubuntu.com/" 10 | BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" 11 | PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" 12 | UBUNTU_CODENAME=jammy 13 | -------------------------------------------------------------------------------- /providers/linux/util.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "bufio" 22 | "bytes" 23 | "errors" 24 | "fmt" 25 | "os" 26 | "strconv" 27 | ) 28 | 29 | // parseKeyValue parses key/val pairs separated by the provided separator from 30 | // each line in content and invokes the callback. White-space is trimmed from 31 | // val. Empty lines are ignored. All non-empty lines must contain the separator 32 | // otherwise an error is returned. 33 | func parseKeyValue(content []byte, separator byte, callback func(key, value []byte) error) error { 34 | var line []byte 35 | 36 | for len(content) > 0 { 37 | line, content, _ = bytes.Cut(content, []byte{'\n'}) 38 | if len(line) == 0 { 39 | continue 40 | } 41 | 42 | key, value, ok := bytes.Cut(line, []byte{separator}) 43 | if !ok { 44 | return fmt.Errorf("separator %q not found", separator) 45 | } 46 | 47 | callback(key, bytes.TrimSpace(value)) 48 | } 49 | 50 | return nil 51 | } 52 | 53 | func findValue(filename, separator, key string) (string, error) { 54 | content, err := os.ReadFile(filename) 55 | if err != nil { 56 | return "", err 57 | } 58 | 59 | var line []byte 60 | sc := bufio.NewScanner(bytes.NewReader(content)) 61 | for sc.Scan() { 62 | if bytes.HasPrefix(sc.Bytes(), []byte(key)) { 63 | line = sc.Bytes() 64 | break 65 | } 66 | } 67 | if len(line) == 0 { 68 | return "", fmt.Errorf("%v not found", key) 69 | } 70 | 71 | parts := bytes.SplitN(line, []byte(separator), 2) 72 | if len(parts) != 2 { 73 | return "", fmt.Errorf("unexpected line format for '%v'", string(line)) 74 | } 75 | 76 | return string(bytes.TrimSpace(parts[1])), nil 77 | } 78 | 79 | func decodeBitMap(s string, lookupName func(int) string) ([]string, error) { 80 | mask, err := strconv.ParseUint(s, 16, 64) 81 | if err != nil { 82 | return nil, err 83 | } 84 | 85 | var names []string 86 | for i := 0; i < 64; i++ { 87 | bit := mask & (1 << uint(i)) 88 | if bit > 0 { 89 | names = append(names, lookupName(i)) 90 | } 91 | } 92 | 93 | return names, nil 94 | } 95 | 96 | // parses a meminfo field, returning either a raw numerical value, or the kB value converted to bytes 97 | func parseBytesOrNumber(data []byte) (uint64, error) { 98 | parts := bytes.Fields(data) 99 | 100 | if len(parts) == 0 { 101 | return 0, errors.New("empty value") 102 | } 103 | 104 | num, err := strconv.ParseUint(string(parts[0]), 10, 64) 105 | if err != nil { 106 | return 0, fmt.Errorf("failed to parse value: %w", err) 107 | } 108 | 109 | var multiplier uint64 = 1 110 | if len(parts) >= 2 { 111 | switch string(parts[1]) { 112 | case "kB": 113 | multiplier = 1024 114 | default: 115 | return 0, fmt.Errorf("unhandled unit %v", string(parts[1])) 116 | } 117 | } 118 | 119 | return num * multiplier, nil 120 | } 121 | -------------------------------------------------------------------------------- /providers/linux/vmstat.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "fmt" 22 | "reflect" 23 | 24 | "github.com/elastic/go-sysinfo/types" 25 | ) 26 | 27 | // vmstatTagToFieldIndex contains a mapping of json struct tags to struct field indices. 28 | var vmstatTagToFieldIndex = make(map[string]int) 29 | 30 | func init() { 31 | var vmstat types.VMStatInfo 32 | val := reflect.ValueOf(vmstat) 33 | typ := reflect.TypeOf(vmstat) 34 | 35 | for i := 0; i < val.NumField(); i++ { 36 | field := typ.Field(i) 37 | if tag := field.Tag.Get("json"); tag != "" { 38 | vmstatTagToFieldIndex[tag] = i 39 | } 40 | } 41 | } 42 | 43 | // parseVMStat parses the contents of /proc/vmstat. 44 | func parseVMStat(content []byte) (*types.VMStatInfo, error) { 45 | var vmStat types.VMStatInfo 46 | refValues := reflect.ValueOf(&vmStat).Elem() 47 | 48 | err := parseKeyValue(content, ' ', func(key, value []byte) error { 49 | // turn our []byte value into an int 50 | val, err := parseBytesOrNumber(value) 51 | if err != nil { 52 | return fmt.Errorf("failed to parse %v value of %v: %w", string(key), string(value), err) 53 | } 54 | 55 | idx, ok := vmstatTagToFieldIndex[string(key)] 56 | if !ok { 57 | return nil 58 | } 59 | 60 | sval := refValues.Field(idx) 61 | 62 | if sval.CanSet() { 63 | sval.SetUint(val) 64 | } 65 | return nil 66 | }) 67 | 68 | return &vmStat, err 69 | } 70 | -------------------------------------------------------------------------------- /providers/linux/vmstat_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package linux 19 | 20 | import ( 21 | "testing" 22 | 23 | "github.com/stretchr/testify/assert" 24 | ) 25 | 26 | var rawInput = ` 27 | nr_free_pages 50545 28 | nr_zone_inactive_anon 66 29 | nr_zone_active_anon 26799 30 | nr_zone_inactive_file 31849 31 | nr_zone_active_file 94164 32 | nr_zone_unevictable 0 33 | nr_zone_write_pending 7 34 | nr_mlock 0 35 | nr_page_table_pages 1225 36 | nr_kernel_stack 2496 37 | nr_bounce 0 38 | nr_zspages 0 39 | nr_free_cma 0 40 | numa_hit 44470329 41 | numa_miss 0 42 | numa_foreign 0 43 | numa_interleave 16296 44 | numa_local 44470329 45 | numa_other 0 46 | nr_inactive_anon 66 47 | nr_active_anon 26799 48 | nr_inactive_file 31849 49 | nr_active_file 94164 50 | nr_unevictable 0 51 | nr_slab_reclaimable 31763 52 | nr_slab_unreclaimable 10329 53 | nr_isolated_anon 0 54 | nr_isolated_file 0 55 | workingset_refault 302914 56 | workingset_activate 108959 57 | workingset_nodereclaim 6422 58 | nr_anon_pages 26218 59 | nr_mapped 8641 60 | nr_file_pages 126182 61 | nr_dirty 7 62 | nr_writeback 0 63 | nr_writeback_temp 0 64 | nr_shmem 169 65 | nr_shmem_hugepages 0 66 | nr_shmem_pmdmapped 0 67 | nr_anon_transparent_hugepages 0 68 | nr_unstable 0 69 | nr_vmscan_write 35 70 | nr_vmscan_immediate_reclaim 9832 71 | nr_dirtied 7188920 72 | nr_written 6479005 73 | nr_dirty_threshold 31736 74 | nr_dirty_background_threshold 15848 75 | pgpgin 17010697 76 | pgpgout 27734292 77 | pswpin 0 78 | pswpout 0 79 | pgalloc_dma 241378 80 | pgalloc_dma32 45788683 81 | pgalloc_normal 0 82 | pgalloc_movable 0 83 | allocstall_dma 0 84 | allocstall_dma32 0 85 | allocstall_normal 5 86 | allocstall_movable 8 87 | pgskip_dma 0 88 | pgskip_dma32 0 89 | pgskip_normal 0 90 | pgskip_movable 0 91 | pgfree 46085578 92 | pgactivate 2475069 93 | pgdeactivate 636658 94 | pglazyfree 9426 95 | pgfault 46777498 96 | pgmajfault 19204 97 | pglazyfreed 0 98 | pgrefill 707817 99 | pgsteal_kswapd 3798890 100 | pgsteal_direct 1466 101 | pgscan_kswapd 3868525 102 | pgscan_direct 1483 103 | pgscan_direct_throttle 0 104 | zone_reclaim_failed 0 105 | pginodesteal 1710 106 | slabs_scanned 8348560 107 | kswapd_inodesteal 3142001 108 | kswapd_low_wmark_hit_quickly 541 109 | kswapd_high_wmark_hit_quickly 332 110 | pageoutrun 1492 111 | pgrotated 29725 112 | drop_pagecache 0 113 | drop_slab 0 114 | oom_kill 0 115 | numa_pte_updates 0 116 | numa_huge_pte_updates 0 117 | numa_hint_faults 0 118 | numa_hint_faults_local 0 119 | numa_pages_migrated 0 120 | pgmigrate_success 4539 121 | pgmigrate_fail 156 122 | compact_migrate_scanned 9331 123 | compact_free_scanned 136266 124 | compact_isolated 9407 125 | compact_stall 2 126 | compact_fail 0 127 | compact_success 2 128 | compact_daemon_wake 21 129 | compact_daemon_migrate_scanned 8311 130 | compact_daemon_free_scanned 107086 131 | htlb_buddy_alloc_success 0 132 | htlb_buddy_alloc_fail 0 133 | unevictable_pgs_culled 19 134 | unevictable_pgs_scanned 0 135 | unevictable_pgs_rescued 304 136 | unevictable_pgs_mlocked 304 137 | unevictable_pgs_munlocked 304 138 | unevictable_pgs_cleared 0 139 | unevictable_pgs_stranded 0 140 | thp_fault_alloc 2 141 | thp_fault_fallback 0 142 | thp_collapse_alloc 2 143 | thp_collapse_alloc_failed 0 144 | thp_file_alloc 0 145 | thp_file_mapped 0 146 | thp_split_page 0 147 | thp_split_page_failed 0 148 | thp_deferred_split_page 4 149 | thp_split_pmd 1 150 | thp_split_pud 0 151 | thp_zero_page_alloc 0 152 | thp_zero_page_alloc_failed 0 153 | thp_swpout 0 154 | thp_swpout_fallback 0 155 | balloon_inflate 0 156 | balloon_deflate 0 157 | balloon_migrate 0 158 | swap_ra 0 159 | swap_ra_hit 0 160 | ` 161 | 162 | func TestVmStatParse(t *testing.T) { 163 | data, err := parseVMStat([]byte(rawInput)) 164 | if err != nil { 165 | t.Fatal(err) 166 | } 167 | // Check a few values 168 | assert.Equal(t, uint64(8348560), data.SlabsScanned) 169 | assert.Equal(t, uint64(0), data.SwapRa) 170 | assert.Equal(t, uint64(108959), data.WorkingsetActivate) 171 | } 172 | -------------------------------------------------------------------------------- /providers/shared/fqdn.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build linux || darwin || aix 19 | 20 | package shared 21 | 22 | import ( 23 | "context" 24 | "fmt" 25 | "net" 26 | "os" 27 | "strings" 28 | ) 29 | 30 | // FQDNWithContext attempts to lookup the host's fully-qualified domain name and returns it. 31 | // It does so using the following algorithm: 32 | // 33 | // 1. It gets the hostname from the OS. If this step fails, it returns an error. 34 | // 35 | // 2. It tries to perform a CNAME DNS lookup for the hostname. If this succeeds, it 36 | // returns the CNAME (after trimming any trailing period) as the FQDN. 37 | // 38 | // 3. It tries to perform an IP lookup for the hostname. If this succeeds, it tries 39 | // to perform a reverse DNS lookup on the returned IPs and returns the first 40 | // successful result (after trimming any trailing period) as the FQDN. 41 | // 42 | // 4. If steps 2 and 3 both fail, an empty string is returned as the FQDN along with 43 | // errors from those steps. 44 | func FQDNWithContext(ctx context.Context) (string, error) { 45 | hostname, err := os.Hostname() 46 | if err != nil { 47 | return "", fmt.Errorf("could not get hostname to look for FQDN: %w", err) 48 | } 49 | 50 | return fqdn(ctx, hostname) 51 | } 52 | 53 | // FQDN just calls FQDNWithContext with a background context. 54 | // Deprecated. 55 | func FQDN() (string, error) { 56 | return FQDNWithContext(context.Background()) 57 | } 58 | 59 | func fqdn(ctx context.Context, hostname string) (string, error) { 60 | var errs error 61 | cname, err := net.DefaultResolver.LookupCNAME(ctx, hostname) 62 | if err != nil { 63 | errs = fmt.Errorf("could not get FQDN, all methods failed: failed looking up CNAME: %w", 64 | err) 65 | } 66 | 67 | if cname != "" { 68 | cname = strings.TrimSuffix(cname, ".") 69 | 70 | // Go might lowercase the cname "for convenience". Therefore, if cname 71 | // is the same as hostname, return hostname as is. 72 | // See https://github.com/golang/go/blob/go1.22.5/src/net/hosts.go#L38 73 | if strings.ToLower(cname) == strings.ToLower(hostname) { 74 | return hostname, nil 75 | } 76 | 77 | return cname, nil 78 | } 79 | 80 | ips, err := net.DefaultResolver.LookupIP(ctx, "ip", hostname) 81 | if err != nil { 82 | errs = fmt.Errorf("%s: failed looking up IP: %w", errs, err) 83 | } 84 | 85 | for _, ip := range ips { 86 | names, err := net.DefaultResolver.LookupAddr(ctx, ip.String()) 87 | if err != nil || len(names) == 0 { 88 | continue 89 | } 90 | return strings.TrimSuffix(names[0], "."), nil 91 | } 92 | 93 | return "", errs 94 | } 95 | -------------------------------------------------------------------------------- /providers/shared/fqdn_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | //go:build linux || darwin 19 | 20 | package shared 21 | 22 | import ( 23 | "context" 24 | "fmt" 25 | "testing" 26 | "time" 27 | 28 | "github.com/stretchr/testify/require" 29 | ) 30 | 31 | func TestFQDN(t *testing.T) { 32 | tests := map[string]struct { 33 | osHostname string 34 | expectedFQDN string 35 | expectedErrRegex string 36 | timeout time.Duration 37 | }{ 38 | // This test case depends on network, particularly DNS, 39 | // being available. If it starts to fail often enough 40 | // due to occasional network/DNS unavailability, we should 41 | // probably just delete this test case. 42 | "long_real_hostname": { 43 | osHostname: "elastic.co", 44 | expectedFQDN: "elastic.co", 45 | expectedErrRegex: "", 46 | }, 47 | "long_nonexistent_hostname": { 48 | osHostname: "foo.bar.elastic.co", 49 | expectedFQDN: "", 50 | expectedErrRegex: makeErrorRegex("foo.bar.elastic.co", false), 51 | }, 52 | "short_nonexistent_hostname": { 53 | osHostname: "foobarbaz", 54 | expectedFQDN: "", 55 | expectedErrRegex: makeErrorRegex("foobarbaz", false), 56 | }, 57 | "long_mixed_case_hostname": { 58 | osHostname: "eLaSTic.co", 59 | expectedFQDN: "eLaSTic.co", 60 | expectedErrRegex: "", 61 | }, 62 | "nonexistent_timeout": { 63 | osHostname: "foobarbaz", 64 | expectedFQDN: "", 65 | expectedErrRegex: makeErrorRegex("foobarbaz", true), 66 | timeout: 1 * time.Millisecond, 67 | }, 68 | } 69 | 70 | for name, test := range tests { 71 | t.Run(name, func(t *testing.T) { 72 | timeout := test.timeout 73 | if timeout == 0 { 74 | timeout = 10 * time.Second 75 | } 76 | 77 | ctx, cancel := context.WithTimeout(context.Background(), timeout) 78 | defer cancel() 79 | 80 | actualFQDN, err := fqdn(ctx, test.osHostname) 81 | require.Equal(t, test.expectedFQDN, actualFQDN) 82 | 83 | if test.expectedErrRegex == "" { 84 | require.Nil(t, err) 85 | } else { 86 | require.Regexp(t, test.expectedErrRegex, err.Error()) 87 | } 88 | }) 89 | } 90 | } 91 | 92 | func makeErrorRegex(osHostname string, withTimeout bool) string { 93 | timeoutStr := "" 94 | if withTimeout { 95 | timeoutStr = ": i/o timeout" 96 | } 97 | 98 | return fmt.Sprintf( 99 | "could not get FQDN, all methods failed: "+ 100 | "failed looking up CNAME: lookup %s.*: "+ 101 | "failed looking up IP: lookup %s"+timeoutStr, 102 | osHostname, 103 | osHostname, 104 | ) 105 | } 106 | -------------------------------------------------------------------------------- /providers/shared/network.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package shared 19 | 20 | import ( 21 | "net" 22 | ) 23 | 24 | func Network() (ips, macs []string, err error) { 25 | ifcs, err := net.Interfaces() 26 | if err != nil { 27 | return nil, nil, err 28 | } 29 | 30 | // This function fetches all the addresses in a single syscall. Fetching addresses individually for each interface 31 | // can be expensive when the host has a lot of interfaces. This usually happens when the host is doing virtualized 32 | // networking for guests, in Kubernetes for example. 33 | addrs, err := net.InterfaceAddrs() 34 | if err != nil { 35 | return nil, nil, err 36 | } 37 | ips = make([]string, 0, len(addrs)) 38 | for _, addr := range addrs { 39 | ips = append(ips, addr.String()) 40 | } 41 | 42 | macs = make([]string, 0, len(ifcs)) 43 | for _, ifc := range ifcs { 44 | mac := ifc.HardwareAddr.String() 45 | if mac != "" { 46 | macs = append(macs, mac) 47 | } 48 | } 49 | 50 | return ips, macs, nil 51 | } 52 | -------------------------------------------------------------------------------- /providers/windows/arch_windows.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package windows 19 | 20 | import ( 21 | "errors" 22 | 23 | "golang.org/x/sys/windows" 24 | 25 | gowindows "github.com/elastic/go-windows" 26 | ) 27 | 28 | const ( 29 | imageFileMachineAmd64 = 0x8664 30 | imageFileMachineArm64 = 0xAA64 31 | archIntel = "x86_64" 32 | archArm64 = "arm64" 33 | ) 34 | 35 | func Architecture() (string, error) { 36 | systemInfo, err := gowindows.GetNativeSystemInfo() 37 | if err != nil { 38 | return "", err 39 | } 40 | 41 | return systemInfo.ProcessorArchitecture.String(), nil 42 | } 43 | 44 | func NativeArchitecture() (string, error) { 45 | var processMachine, nativeMachine uint16 46 | // the pseudo handle doesn't need to be closed 47 | currentProcessHandle := windows.CurrentProcess() 48 | 49 | // IsWow64Process2 was introduced in version 1709 (build 16299 acording to the tables) 50 | // https://learn.microsoft.com/en-us/windows/release-health/release-information 51 | // https://learn.microsoft.com/en-us/windows/release-health/windows-server-release-info 52 | err := windows.IsWow64Process2(currentProcessHandle, &processMachine, &nativeMachine) 53 | if err != nil { 54 | if errors.Is(err, windows.ERROR_PROC_NOT_FOUND) { 55 | major, minor, build := windows.RtlGetNtVersionNumbers() 56 | if major < 10 || (major == 10 && minor == 0 && build < 16299) { 57 | return "", nil 58 | } 59 | } 60 | return "", err 61 | } 62 | 63 | var nativeArch string 64 | 65 | switch nativeMachine { 66 | case imageFileMachineAmd64: 67 | // for parity with Architecture() as amd64 and x86_64 are used interchangeably 68 | nativeArch = archIntel 69 | case imageFileMachineArm64: 70 | nativeArch = archArm64 71 | } 72 | 73 | return nativeArch, nil 74 | } 75 | -------------------------------------------------------------------------------- /providers/windows/arch_windows_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package windows 19 | 20 | import ( 21 | "testing" 22 | 23 | "github.com/stretchr/testify/assert" 24 | ) 25 | 26 | func TestArchitecture(t *testing.T) { 27 | a, err := Architecture() 28 | assert.NoError(t, err) 29 | assert.NotEmpty(t, a) 30 | } 31 | 32 | func TestNativeArchitecture(t *testing.T) { 33 | a, err := NativeArchitecture() 34 | assert.NoError(t, err) 35 | assert.NotEmpty(t, a) 36 | } 37 | -------------------------------------------------------------------------------- /providers/windows/boottime_windows.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package windows 19 | 20 | import ( 21 | "time" 22 | 23 | "golang.org/x/sys/windows" 24 | ) 25 | 26 | func BootTime() (time.Time, error) { 27 | bootTime := time.Now().Add(-1 * windows.DurationSinceBoot()) 28 | 29 | // According to GetTickCount64, the resolution of the value is limited to 30 | // the resolution of the system timer, which is typically in the range of 31 | // 10 milliseconds to 16 milliseconds. So this will round the value to the 32 | // nearest second to not mislead anyone about the precision of the value 33 | // and to provide a stable value. 34 | bootTime = bootTime.Round(time.Second) 35 | return bootTime, nil 36 | } 37 | -------------------------------------------------------------------------------- /providers/windows/boottime_windows_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package windows 19 | 20 | import ( 21 | "testing" 22 | 23 | "github.com/stretchr/testify/assert" 24 | "github.com/stretchr/testify/require" 25 | ) 26 | 27 | func TestBootTime(t *testing.T) { 28 | bootTime, err := BootTime() 29 | require.NoError(t, err) 30 | 31 | // There should be no sub-second precision in the time. 32 | assert.Equal(t, 0, bootTime.Nanosecond()) 33 | } 34 | -------------------------------------------------------------------------------- /providers/windows/device_windows_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package windows 19 | 20 | import ( 21 | "fmt" 22 | "testing" 23 | 24 | "github.com/stretchr/testify/assert" 25 | ) 26 | 27 | func TestDeviceMapper(t *testing.T) { 28 | devMapper := deviceMapper{ 29 | deviceProvider: testingDeviceProvider(map[byte]string{ 30 | 'A': `\Device\Floppy0`, 31 | 'B': `\Device\Floppy1`, 32 | 'C': `\Device\Harddisk0Volume2`, 33 | 'D': `\Device\Harddisk1Volume1`, 34 | 'E': `\Device\Cdrom0`, 35 | // Virtualbox-style share 36 | 'W': `\Device\Share;w:\dataserver\programs`, 37 | // Network share 38 | 'Z': `\Device\LANManRedirector;z:01234567812313123\officeserver\documents`, 39 | }), 40 | } 41 | for testIdx, testCase := range []struct { 42 | devicePath, expected string 43 | }{ 44 | {`\DEVICE\FLOPPY0\README.TXT`, `A:\README.TXT`}, 45 | {`\Device\cdrom0\autorun.INF`, `E:\autorun.INF`}, 46 | {`\Device\Harddisk0Volume2\WINDOWS\System32\drivers\etc\hosts`, `C:\WINDOWS\System32\drivers\etc\hosts`}, 47 | {`\Device\share\DATASERVER\PROGRAMS\elastic\packetbeat\PACKETBEAT.EXE`, `W:\elastic\packetbeat\PACKETBEAT.EXE`}, 48 | {`\Device\MUP\OfficeServer\Documents\report.pdf`, `Z:\report.pdf`}, 49 | {`\Device\share\othershare\files\run.EXE`, ``}, 50 | {`\Device\MUP\networkserver\share\.git`, `\\networkserver\share\.git`}, 51 | {`\Device\Harddisk1Volume1`, `D:\`}, 52 | {`\Device\Harddisk1Volume1\`, `D:\`}, 53 | {`\Device`, ``}, 54 | {`C:\windows\calc.exe`, ``}, 55 | } { 56 | msg := fmt.Sprintf("test case #%d: %v", testIdx, testCase) 57 | path, err := devMapper.DevicePathToDrivePath(testCase.devicePath) 58 | if err == nil { 59 | assert.Equal(t, testCase.expected, path, msg) 60 | } else { 61 | if len(testCase.expected) != 0 { 62 | t.Fatal(err, msg) 63 | continue 64 | } 65 | assert.Equal(t, testCase.expected, path, msg) 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /providers/windows/doc.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | // Package windows implements the HostProvider and ProcessProvider interfaces 19 | // for providing information about Windows. 20 | package windows 21 | -------------------------------------------------------------------------------- /providers/windows/helpers_windows.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package windows 19 | 20 | import ( 21 | "fmt" 22 | 23 | syswin "golang.org/x/sys/windows" 24 | ) 25 | 26 | // sidToString wraps the `String()` functions used to return SID strings in golang.org/x/sys 27 | // These can return an error or no error, depending on the release. 28 | func sidToString(strFunc *syswin.SID) (string, error) { 29 | switch sig := (interface{})(strFunc).(type) { 30 | case fmt.Stringer: 31 | return sig.String(), nil 32 | case errString: 33 | return sig.String() 34 | default: 35 | return "", fmt.Errorf("missing or unexpected String() function signature for %#v", sig) 36 | } 37 | } 38 | 39 | type errString interface { 40 | String() (string, error) 41 | } 42 | -------------------------------------------------------------------------------- /providers/windows/host_windows_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package windows 19 | 20 | import ( 21 | "encoding/json" 22 | "testing" 23 | 24 | "github.com/elastic/go-sysinfo/internal/registry" 25 | ) 26 | 27 | var _ registry.HostProvider = windowsSystem{} 28 | 29 | func TestHost(t *testing.T) { 30 | host, err := windowsSystem{}.Host() 31 | if err != nil { 32 | t.Logf("could not get all host info: %v\n", err) 33 | } 34 | 35 | info := host.Info() 36 | data, _ := json.MarshalIndent(info, "", " ") 37 | t.Log(string(data)) 38 | } 39 | -------------------------------------------------------------------------------- /providers/windows/kernel_windows.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package windows 19 | 20 | import ( 21 | windows "github.com/elastic/go-windows" 22 | ) 23 | 24 | const windowsKernelExe = `C:\Windows\System32\ntoskrnl.exe` 25 | 26 | func KernelVersion() (string, error) { 27 | versionData, err := windows.GetFileVersionInfo(windowsKernelExe) 28 | if err != nil { 29 | return "", err 30 | } 31 | 32 | fileVersion, err := versionData.QueryValue("FileVersion") 33 | if err == nil { 34 | return fileVersion, nil 35 | } 36 | 37 | // Make a second attempt through the fixed version info. 38 | info, err := versionData.FixedFileInfo() 39 | if err != nil { 40 | return "", err 41 | } 42 | return info.ProductVersion(), nil 43 | } 44 | -------------------------------------------------------------------------------- /providers/windows/machineid_windows.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package windows 19 | 20 | import ( 21 | "fmt" 22 | 23 | "golang.org/x/sys/windows/registry" 24 | ) 25 | 26 | func MachineID() (string, error) { 27 | return getMachineGUID() 28 | } 29 | 30 | func getMachineGUID() (string, error) { 31 | const key = registry.LOCAL_MACHINE 32 | const path = `SOFTWARE\Microsoft\Cryptography` 33 | const name = "MachineGuid" 34 | 35 | k, err := registry.OpenKey(key, path, registry.READ|registry.WOW64_64KEY) 36 | if err != nil { 37 | return "", fmt.Errorf(`failed to open HKLM\%v: %w`, path, err) 38 | } 39 | defer k.Close() 40 | 41 | guid, _, err := k.GetStringValue(name) 42 | if err != nil { 43 | return "", fmt.Errorf(`failed to get value of HKLM\%v\%v: %w`, path, name, err) 44 | } 45 | 46 | return guid, nil 47 | } 48 | -------------------------------------------------------------------------------- /providers/windows/os_windows.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package windows 19 | 20 | import ( 21 | "fmt" 22 | "strconv" 23 | "strings" 24 | 25 | "golang.org/x/sys/windows/registry" 26 | 27 | "github.com/elastic/go-sysinfo/types" 28 | ) 29 | 30 | func OperatingSystem() (*types.OSInfo, error) { 31 | const key = registry.LOCAL_MACHINE 32 | const path = `SOFTWARE\Microsoft\Windows NT\CurrentVersion` 33 | const flags = registry.READ | registry.WOW64_64KEY 34 | 35 | k, err := registry.OpenKey(key, path, flags) 36 | if err != nil { 37 | return nil, fmt.Errorf(`failed to open HKLM\%v: %w`, path, err) 38 | } 39 | defer k.Close() 40 | 41 | osInfo := &types.OSInfo{ 42 | Type: "windows", 43 | Family: "windows", 44 | Platform: "windows", 45 | } 46 | name := "ProductName" 47 | osInfo.Name, _, err = k.GetStringValue(name) 48 | if err != nil { 49 | return nil, fmt.Errorf(`failed to get value of HKLM\%v\%v: %w`, path, name, err) 50 | } 51 | 52 | // Newer versions (Win 10 and 2016) have CurrentMajor/CurrentMinor. 53 | major, _, majorErr := k.GetIntegerValue("CurrentMajorVersionNumber") 54 | minor, _, minorErr := k.GetIntegerValue("CurrentMinorVersionNumber") 55 | if majorErr == nil && minorErr == nil { 56 | osInfo.Major = int(major) 57 | osInfo.Minor = int(minor) 58 | osInfo.Version = fmt.Sprintf("%d.%d", major, minor) 59 | } else { 60 | name = "CurrentVersion" 61 | osInfo.Version, _, err = k.GetStringValue(name) 62 | if err != nil { 63 | return nil, fmt.Errorf(`failed to get value of HKLM\%v\%v: %w`, path, name, err) 64 | } 65 | parts := strings.SplitN(osInfo.Version, ".", 3) 66 | for i, p := range parts { 67 | switch i { 68 | case 0: 69 | osInfo.Major, _ = strconv.Atoi(p) 70 | case 1: 71 | osInfo.Minor, _ = strconv.Atoi(p) 72 | } 73 | } 74 | } 75 | 76 | name = "CurrentBuild" 77 | currentBuild, _, err := k.GetStringValue(name) 78 | if err != nil { 79 | return nil, fmt.Errorf(`failed to get value of HKLM\%v\%v: %w`, path, name, err) 80 | } 81 | osInfo.Build = currentBuild 82 | 83 | // Update Build Revision (optional) 84 | name = "UBR" 85 | updateBuildRevision, _, err := k.GetIntegerValue(name) 86 | if err != nil && err != registry.ErrNotExist { 87 | return nil, fmt.Errorf(`failed to get value of HKLM\%v\%v: %w`, path, name, err) 88 | } else { 89 | osInfo.Build = fmt.Sprintf("%v.%d", osInfo.Build, updateBuildRevision) 90 | } 91 | 92 | fixWindows11Naming(currentBuild, osInfo) 93 | 94 | return osInfo, nil 95 | } 96 | 97 | // fixWindows11Naming adjusts the OS name because the ProductName registry value 98 | // was not changed in Windows 11 and still contains Windows 10. If the product 99 | // name contains "Windows 10" and the version is greater than or equal to 100 | // 10.0.22000 then "Windows 10" is replaced with "Windows 11" in the OS name. 101 | // 102 | // https://docs.microsoft.com/en-us/answers/questions/586619/windows-11-build-ver-is-still-10022000194.html 103 | func fixWindows11Naming(currentBuild string, osInfo *types.OSInfo) { 104 | buildNumber, err := strconv.Atoi(currentBuild) 105 | if err != nil { 106 | return 107 | } 108 | 109 | // "Anything above [or equal] 10.0.22000.0 is Win 11. Anything below is Win 10." 110 | if osInfo.Major > 10 || 111 | osInfo.Major == 10 && osInfo.Minor > 0 || 112 | osInfo.Major == 10 && osInfo.Minor == 0 && buildNumber >= 22000 { 113 | osInfo.Name = strings.Replace(osInfo.Name, "Windows 10", "Windows 11", 1) 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /providers/windows/os_windows_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package windows 19 | 20 | import ( 21 | "os/exec" 22 | "strconv" 23 | "strings" 24 | "testing" 25 | 26 | "github.com/stretchr/testify/assert" 27 | 28 | "github.com/elastic/go-sysinfo/types" 29 | ) 30 | 31 | func TestFixWindows11Naming(t *testing.T) { 32 | testCases := []struct { 33 | osInfo types.OSInfo 34 | expectedName string 35 | }{ 36 | { 37 | osInfo: types.OSInfo{ 38 | Major: 10, 39 | Minor: 0, 40 | Build: "22000", 41 | Name: "Windows 10 Pro", 42 | }, 43 | expectedName: "Windows 11 Pro", 44 | }, 45 | { 46 | osInfo: types.OSInfo{ 47 | Major: 10, 48 | Minor: 0, 49 | Build: "22001", 50 | Name: "Windows 10 Pro", 51 | }, 52 | expectedName: "Windows 11 Pro", 53 | }, 54 | { 55 | osInfo: types.OSInfo{ 56 | Major: 10, 57 | Minor: 1, 58 | Build: "0", 59 | Name: "Windows 10 Pro", 60 | }, 61 | expectedName: "Windows 11 Pro", 62 | }, 63 | { 64 | osInfo: types.OSInfo{ 65 | Major: 11, 66 | Minor: 0, 67 | Build: "0", 68 | Name: "Windows 10 Pro", 69 | }, 70 | expectedName: "Windows 11 Pro", 71 | }, 72 | { 73 | osInfo: types.OSInfo{ 74 | Major: 11, 75 | Minor: 0, 76 | Build: "0", 77 | Name: "Windows 12 Pro", 78 | }, 79 | expectedName: "Windows 12 Pro", 80 | }, 81 | { 82 | osInfo: types.OSInfo{ 83 | Major: 9, 84 | Minor: 0, 85 | Build: "22000", 86 | Name: "Windows 10 Pro", 87 | }, 88 | expectedName: "Windows 10 Pro", 89 | }, 90 | } 91 | 92 | for _, tc := range testCases { 93 | fixWindows11Naming(tc.osInfo.Build, &tc.osInfo) 94 | assert.Equal(t, tc.expectedName, tc.osInfo.Name) 95 | } 96 | } 97 | 98 | func TestOperatingSystemMajorMinor(t *testing.T) { 99 | // User PowerShell to get the expected OS version. 100 | var major, minor int 101 | if stdout, err := exec.Command("powershell.exe", "-c", "[System.Environment]::OSVersion.Version.Major").Output(); err != nil { 102 | t.Fatal(err) 103 | } else if major, err = strconv.Atoi(strings.TrimSpace(string(stdout))); err != nil { 104 | t.Fatal(err) 105 | } 106 | if stdout, err := exec.Command("powershell.exe", "-c", "[System.Environment]::OSVersion.Version.Minor").Output(); err != nil { 107 | t.Fatal(err) 108 | } else if minor, err = strconv.Atoi(strings.TrimSpace(string(stdout))); err != nil { 109 | t.Fatal(err) 110 | } 111 | 112 | // Verify expected output. 113 | osInfo, err := OperatingSystem() 114 | if err != nil { 115 | t.Fatal(err) 116 | } 117 | 118 | assert.Equal(t, major, osInfo.Major) 119 | assert.Equal(t, minor, osInfo.Minor) 120 | } 121 | -------------------------------------------------------------------------------- /providers/windows/process_windows_test.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package windows 19 | 20 | import ( 21 | "github.com/elastic/go-sysinfo/internal/registry" 22 | ) 23 | 24 | var ( 25 | _ registry.HostProvider = windowsSystem{} 26 | _ registry.ProcessProvider = windowsSystem{} 27 | ) 28 | -------------------------------------------------------------------------------- /system.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package sysinfo 19 | 20 | import ( 21 | "runtime" 22 | 23 | "github.com/elastic/go-sysinfo/internal/registry" 24 | "github.com/elastic/go-sysinfo/types" 25 | 26 | // Register host and process providers. 27 | _ "github.com/elastic/go-sysinfo/providers/aix" 28 | _ "github.com/elastic/go-sysinfo/providers/darwin" 29 | _ "github.com/elastic/go-sysinfo/providers/linux" 30 | _ "github.com/elastic/go-sysinfo/providers/windows" 31 | ) 32 | 33 | type ProviderOption func(*registry.ProviderOptions) 34 | 35 | // WithHostFS returns a provider with a custom HostFS root path, 36 | // enabling use of the library from within a container, or an alternate root path on linux. 37 | // For example, WithHostFS("/hostfs") can be used when /hostfs points to the root filesystem of the container host. 38 | // For full functionality, the alternate hostfs should have: 39 | // - /proc 40 | // - /var 41 | // - /etc 42 | func WithHostFS(hostfs string) ProviderOption { 43 | return func(po *registry.ProviderOptions) { 44 | po.Hostfs = hostfs 45 | } 46 | } 47 | 48 | // Go returns information about the Go runtime. 49 | func Go() types.GoInfo { 50 | return types.GoInfo{ 51 | OS: runtime.GOOS, 52 | Arch: runtime.GOARCH, 53 | MaxProcs: runtime.GOMAXPROCS(0), 54 | Version: runtime.Version(), 55 | } 56 | } 57 | 58 | func applyOptsAndReturnProvider(opts ...ProviderOption) registry.ProviderOptions { 59 | options := registry.ProviderOptions{} 60 | for _, opt := range opts { 61 | opt(&options) 62 | } 63 | return options 64 | } 65 | 66 | // setupProcessProvider returns a ProcessProvider. 67 | // Most of the exported functions here deal with processes, 68 | // so this just gets wrapped by all the external functions 69 | func setupProcessProvider(opts ...ProviderOption) (registry.ProcessProvider, error) { 70 | provider := registry.GetProcessProvider(applyOptsAndReturnProvider(opts...)) 71 | if provider == nil { 72 | return nil, types.ErrNotImplemented 73 | } 74 | return provider, nil 75 | } 76 | 77 | // Host returns information about host on which this process is running. If 78 | // host information collection is not implemented for this platform then 79 | // types.ErrNotImplemented is returned. 80 | // On Darwin (macOS) a types.ErrNotImplemented is returned with cgo disabled. 81 | func Host(opts ...ProviderOption) (types.Host, error) { 82 | provider := registry.GetHostProvider(applyOptsAndReturnProvider(opts...)) 83 | if provider == nil { 84 | return nil, types.ErrNotImplemented 85 | } 86 | return provider.Host() 87 | } 88 | 89 | // Process returns a types.Process object representing the process associated 90 | // with the given PID. The types.Process object can be used to query information 91 | // about the process. If process information collection is not implemented for 92 | // this platform then types.ErrNotImplemented is returned. 93 | func Process(pid int, opts ...ProviderOption) (types.Process, error) { 94 | provider, err := setupProcessProvider(opts...) 95 | if err != nil { 96 | return nil, err 97 | } 98 | return provider.Process(pid) 99 | } 100 | 101 | // Processes return a list of all processes. If process information collection 102 | // is not implemented for this platform then types.ErrNotImplemented is 103 | // returned. 104 | func Processes(opts ...ProviderOption) ([]types.Process, error) { 105 | provider, err := setupProcessProvider(opts...) 106 | if err != nil { 107 | return nil, err 108 | } 109 | return provider.Processes() 110 | } 111 | 112 | // Self return a types.Process object representing this process. If process 113 | // information collection is not implemented for this platform then 114 | // types.ErrNotImplemented is returned. 115 | func Self(opts ...ProviderOption) (types.Process, error) { 116 | provider, err := setupProcessProvider(opts...) 117 | if err != nil { 118 | return nil, err 119 | } 120 | return provider.Self() 121 | } 122 | -------------------------------------------------------------------------------- /types/errors.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package types 19 | 20 | import "errors" 21 | 22 | // ErrNotImplemented represents an error for a function that is not implemented on a particular platform. 23 | var ErrNotImplemented = errors.New("unimplemented") 24 | -------------------------------------------------------------------------------- /types/go.go: -------------------------------------------------------------------------------- 1 | // Licensed to Elasticsearch B.V. under one or more contributor 2 | // license agreements. See the NOTICE file distributed with 3 | // this work for additional information regarding copyright 4 | // ownership. Elasticsearch B.V. licenses this file to you under 5 | // the Apache License, Version 2.0 (the "License"); you may 6 | // not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | package types 19 | 20 | // GoInfo contains info about the go runtime 21 | type GoInfo struct { 22 | OS string `json:"os"` 23 | Arch string `json:"arch"` 24 | MaxProcs int `json:"max_procs"` 25 | Version string `json:"version"` 26 | } 27 | --------------------------------------------------------------------------------