From fac61320e5f12ad50e55da34ffee909faf33b26d Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 4 Jan 2023 16:40:55 +0100 Subject: [PATCH 01/65] linux and windows done --- providers/linux/host_linux.go | 25 ++++++++++++++++- providers/windows/host_windows.go | 38 +++++++++++++++++++++++++- providers/windows/host_windows_test.go | 21 ++++++++++++++ types/host.go | 1 + 4 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 providers/windows/host_windows_test.go diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index 9adb5cb3..32211075 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -18,11 +18,14 @@ package linux import ( + "bytes" "errors" "fmt" "io/ioutil" "os" + "os/exec" "path/filepath" + "strings" "time" "github.com/joeshaw/multierror" @@ -138,7 +141,7 @@ func (h *host) CPUTime() (types.CPUTimes, error) { } func newHost(fs procFS) (*host, error) { - stat, err := fs.NewStat() + stat, err := fs.Stat() if err != nil { return nil, fmt.Errorf("failed to read proc stat: %w", err) } @@ -149,11 +152,13 @@ func newHost(fs procFS) (*host, error) { r.bootTime(h) r.containerized(h) r.hostname(h) + r.fqdn(h) r.network(h) r.kernelVersion(h) r.os(h) r.time(h) r.uniqueID(h) + return h, r.Err() } @@ -210,6 +215,24 @@ func (r *reader) hostname(h *host) { h.info.Hostname = v } +func (r *reader) fqdn(h *host) { + const cmdPath, args = "/bin/hostname", "-f" + cmd := exec.Command(cmdPath, args) + + var stdout, stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + err := cmd.Run() + if err != nil { + r.addErr(fmt.Errorf("could not get linux FQDN:'%s %s' failed to run: %q: %w", + cmdPath, args, strings.Trim(stderr.String(), "\n"), err)) + return + } + + h.info.FQDN = strings.Trim(stdout.String(), "\n") +} + func (r *reader) network(h *host) { ips, macs, err := shared.Network() if r.addErr(err) { diff --git a/providers/windows/host_windows.go b/providers/windows/host_windows.go index 96a90d9a..81a9dec0 100644 --- a/providers/windows/host_windows.go +++ b/providers/windows/host_windows.go @@ -19,15 +19,18 @@ package windows import ( "errors" + "fmt" "os" + "syscall" "time" - windows "github.com/elastic/go-windows" "github.com/joeshaw/multierror" + stdwindows "golang.org/x/sys/windows" "github.com/elastic/go-sysinfo/internal/registry" "github.com/elastic/go-sysinfo/providers/shared" "github.com/elastic/go-sysinfo/types" + "github.com/elastic/go-windows" ) func init() { @@ -137,6 +140,39 @@ func (r *reader) hostname(h *host) { h.info.Hostname = v } +func (r *reader) fqdn(h *host) { + size := uint32(64) + for { + buff := make([]uint16, size) + err := stdwindows.GetComputerNameEx( + stdwindows.ComputerNamePhysicalDnsFullyQualified, &buff[0], &size) + if err == nil { + h.info.FQDN = syscall.UTF16ToString(buff[:size]) + return + } + + // ERROR_MORE_DATA means buff is too small and size is set to the + // number of bytes needed to store the FQDN. For details, see + // https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getcomputernameexw#return-value + if errors.Is(err, syscall.ERROR_MORE_DATA) { + if size <= uint32(len(buff)) { + // Safeguard to avoid an infinite loop. + r.addErr(fmt.Errorf( + "windows.GetComputerNameEx returned ERROR_MORE_DATA, " + + "but data size should fit into buffer")) + return + } else { + // Grow the buffer and try again. + // Should we limit its growth? + buff = make([]uint16, size) + continue + } + } + + r.addErr(fmt.Errorf("could not get windows FQDN: could not get windows.ComputerNamePhysicalDnsFullyQualified: %w", err)) + } +} + func (r *reader) network(h *host) { ips, macs, err := shared.Network() if r.addErr(err) { diff --git a/providers/windows/host_windows_test.go b/providers/windows/host_windows_test.go new file mode 100644 index 00000000..61503f45 --- /dev/null +++ b/providers/windows/host_windows_test.go @@ -0,0 +1,21 @@ +package windows + +import ( + "encoding/json" + "testing" + + "github.com/elastic/go-sysinfo/internal/registry" +) + +var _ registry.HostProvider = windowsSystem{} + +func TestHost(t *testing.T) { + host, err := windowsSystem{}.Host() + if err != nil { + t.Fatal(err) + } + + info := host.Info() + data, _ := json.MarshalIndent(info, "", " ") + t.Log(string(data)) +} diff --git a/types/host.go b/types/host.go index d2911eeb..ff4253f1 100644 --- a/types/host.go +++ b/types/host.go @@ -67,6 +67,7 @@ type HostInfo struct { BootTime time.Time `json:"boot_time"` // Host boot time. Containerized *bool `json:"containerized,omitempty"` // Is the process containerized. Hostname string `json:"name"` // Hostname + FQDN string `json:"fqdn"` // FQDN IPs []string `json:"ip,omitempty"` // List of all IPs. KernelVersion string `json:"kernel_version"` // Kernel version. MACs []string `json:"mac"` // List of MAC addresses. From 0c3f9c255d3f8a72bb81c28220c777f232301f31 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 4 Jan 2023 16:45:27 +0100 Subject: [PATCH 02/65] send --- providers/windows/host_windows.go | 1 + 1 file changed, 1 insertion(+) diff --git a/providers/windows/host_windows.go b/providers/windows/host_windows.go index 81a9dec0..754f3c8d 100644 --- a/providers/windows/host_windows.go +++ b/providers/windows/host_windows.go @@ -87,6 +87,7 @@ func newHost() (*host, error) { r.architecture(h) r.bootTime(h) r.hostname(h) + r.fqdn(h) r.network(h) r.kernelVersion(h) r.os(h) From 6843a8ff9a585fb9512b4e47e61f586568c7c660 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Thu, 5 Jan 2023 11:44:58 +0100 Subject: [PATCH 03/65] using gethostname and getdomainname instead of hostname -f --- providers/linux/host_linux.go | 47 ++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index 32211075..5ea7eb8f 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -17,16 +17,18 @@ package linux +// #include +// #include +import "C" + import ( - "bytes" "errors" "fmt" "io/ioutil" "os" - "os/exec" "path/filepath" - "strings" "time" + "unsafe" "github.com/joeshaw/multierror" "github.com/prometheus/procfs" @@ -216,21 +218,38 @@ func (r *reader) hostname(h *host) { } func (r *reader) fqdn(h *host) { - const cmdPath, args = "/bin/hostname", "-f" - cmd := exec.Command(cmdPath, args) - - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - - err := cmd.Run() + fqdn, err := fqdnC() if err != nil { - r.addErr(fmt.Errorf("could not get linux FQDN:'%s %s' failed to run: %q: %w", - cmdPath, args, strings.Trim(stderr.String(), "\n"), err)) + r.addErr(fmt.Errorf("could not get linux FQDN: %w", err)) return } - h.info.FQDN = strings.Trim(stdout.String(), "\n") + h.info.FQDN = fqdn +} + +func fqdnC() (string, error) { + const buffSize = 64 + buff := make([]byte, buffSize) + size := C.size_t(buffSize) + cString := C.CString(string(buff)) + defer C.free(unsafe.Pointer(cString)) + + _, errno := C.gethostname(cString, size) + if errno != nil { + return "", fmt.Errorf("syscall gethostname errored: %v", errno) + } + var hostname string = C.GoString(cString) + + _, errno = C.getdomainname(cString, size) + if errno != nil { + return "", fmt.Errorf("syscall getdomainname errored: %v", errno) + } + var domain string = C.GoString(cString) + if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour + domain = "lan" + } + + return fmt.Sprintf("%s.%s", hostname, domain), nil } func (r *reader) network(h *host) { From 38abc2e38871e07298867b5ec63288297866d21c Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Thu, 5 Jan 2023 11:53:33 +0100 Subject: [PATCH 04/65] don't use deprecated functions --- providers/linux/boottime_linux.go | 2 +- providers/linux/host_linux.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/providers/linux/boottime_linux.go b/providers/linux/boottime_linux.go index e229d54e..58665a7c 100644 --- a/providers/linux/boottime_linux.go +++ b/providers/linux/boottime_linux.go @@ -37,7 +37,7 @@ func bootTime(fs procfs.FS) (time.Time, error) { return bootTimeValue, nil } - stat, err := fs.NewStat() + stat, err := fs.Stat() if err != nil { return time.Time{}, err } diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index 5ea7eb8f..69219fde 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -125,7 +125,7 @@ func (h *host) NetworkCounters() (*types.NetworkCountersInfo, error) { } func (h *host) CPUTime() (types.CPUTimes, error) { - stat, err := h.procFS.NewStat() + stat, err := h.procFS.Stat() if err != nil { return types.CPUTimes{}, err } From a79bc82e65b019608fb494979b4d28c66865bffc Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Thu, 5 Jan 2023 15:50:20 +0100 Subject: [PATCH 05/65] . try linux implementation to darwin add license headers goimports fix buid? windows matching Linux behavior . . --- providers/darwin/host_darwin.go | 41 ++++++++++++++++++++++++++ providers/darwin/host_darwin_test.go | 41 ++++++++++++++++++++++++++ providers/linux/host_linux.go | 3 ++ providers/windows/host_windows.go | 33 ++++++++++++++++----- providers/windows/host_windows_test.go | 17 +++++++++++ 5 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 providers/darwin/host_darwin_test.go diff --git a/providers/darwin/host_darwin.go b/providers/darwin/host_darwin.go index 7d23d015..c87c7167 100644 --- a/providers/darwin/host_darwin.go +++ b/providers/darwin/host_darwin.go @@ -20,11 +20,13 @@ package darwin +import "C" import ( "errors" "fmt" "os" "time" + "unsafe" "github.com/joeshaw/multierror" @@ -160,6 +162,7 @@ func newHost() (*host, error) { r.architecture(h) r.bootTime(h) r.hostname(h) + r.fqdn(h) r.network(h) r.kernelVersion(h) r.os(h) @@ -213,6 +216,44 @@ func (r *reader) hostname(h *host) { h.info.Hostname = v } +func (r *reader) fqdn(h *host) { + fqdn, err := fqdnC() + if err != nil { + r.addErr(fmt.Errorf("could not get linux FQDN: %w", err)) + return + } + + h.info.FQDN = fqdn +} + +func fqdnC() (string, error) { + // Another option could be reading: + // - /proc/sys/kernel/hostname + // - /proc/sys/kernel/domainname + const buffSize = 64 + buff := make([]byte, buffSize) + size := C.size_t(buffSize) + cString := C.CString(string(buff)) + defer C.free(unsafe.Pointer(cString)) + + _, errno := C.gethostname(cString, size) + if errno != nil { + return "", fmt.Errorf("syscall gethostname errored: %v", errno) + } + var hostname string = C.GoString(cString) + + _, errno = C.getdomainname(cString, size) + if errno != nil { + return "", fmt.Errorf("syscall getdomainname errored: %v", errno) + } + var domain string = C.GoString(cString) + if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour + domain = "lan" + } + + return fmt.Sprintf("%s.%s", hostname, domain), nil +} + func (r *reader) network(h *host) { ips, macs, err := shared.Network() if r.addErr(err) { diff --git a/providers/darwin/host_darwin_test.go b/providers/darwin/host_darwin_test.go new file mode 100644 index 00000000..ec0450ae --- /dev/null +++ b/providers/darwin/host_darwin_test.go @@ -0,0 +1,41 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build amd64 || arm64 +// +build amd64 arm64 + +package darwin + +import ( + "encoding/json" + "testing" + + "github.com/elastic/go-sysinfo/internal/registry" +) + +var _ registry.HostProvider = darwinSystem{} + +func TestHost(t *testing.T) { + host, err := darwinSystem{}.Host() + if err != nil { + t.Fatal(err) + } + + info := host.Info() + data, _ := json.MarshalIndent(info, "", " ") + t.Log(string(data)) +} diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index 69219fde..da11c599 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -228,6 +228,9 @@ func (r *reader) fqdn(h *host) { } func fqdnC() (string, error) { + // Another option could be reading: + // - /proc/sys/kernel/hostname + // - /proc/sys/kernel/domainname const buffSize = 64 buff := make([]byte, buffSize) size := C.size_t(buffSize) diff --git a/providers/windows/host_windows.go b/providers/windows/host_windows.go index 754f3c8d..81657dd1 100644 --- a/providers/windows/host_windows.go +++ b/providers/windows/host_windows.go @@ -27,10 +27,11 @@ import ( "github.com/joeshaw/multierror" stdwindows "golang.org/x/sys/windows" + "github.com/elastic/go-windows" + "github.com/elastic/go-sysinfo/internal/registry" "github.com/elastic/go-sysinfo/providers/shared" "github.com/elastic/go-sysinfo/types" - "github.com/elastic/go-windows" ) func init() { @@ -142,14 +143,31 @@ func (r *reader) hostname(h *host) { } func (r *reader) fqdn(h *host) { + hostname, err := getComputerNameEx(stdwindows.ComputerNamePhysicalDnsHostname) + if err != nil { + r.addErr(fmt.Errorf("could not get windows hostname to build FQDN: %s", err)) + } + + dns, err := getComputerNameEx(stdwindows.ComputerNamePhysicalDnsDomain) + if err != nil { + r.addErr(fmt.Errorf("could not get windows dns to build FQDN: %s", err)) + } + if dns == "" { + dns = "lan" + } + + h.info.FQDN = fmt.Sprintf("%s.%s", hostname, dns) +} + +func getComputerNameEx(name uint32) (string, error) { size := uint32(64) + for { buff := make([]uint16, size) err := stdwindows.GetComputerNameEx( - stdwindows.ComputerNamePhysicalDnsFullyQualified, &buff[0], &size) + name, &buff[0], &size) if err == nil { - h.info.FQDN = syscall.UTF16ToString(buff[:size]) - return + return syscall.UTF16ToString(buff[:size]), nil } // ERROR_MORE_DATA means buff is too small and size is set to the @@ -158,10 +176,9 @@ func (r *reader) fqdn(h *host) { if errors.Is(err, syscall.ERROR_MORE_DATA) { if size <= uint32(len(buff)) { // Safeguard to avoid an infinite loop. - r.addErr(fmt.Errorf( + return "", fmt.Errorf( "windows.GetComputerNameEx returned ERROR_MORE_DATA, " + - "but data size should fit into buffer")) - return + "but data size should fit into buffer") } else { // Grow the buffer and try again. // Should we limit its growth? @@ -170,7 +187,7 @@ func (r *reader) fqdn(h *host) { } } - r.addErr(fmt.Errorf("could not get windows FQDN: could not get windows.ComputerNamePhysicalDnsFullyQualified: %w", err)) + return "", fmt.Errorf("could not get windows FQDN: could not get windows.ComputerNamePhysicalDnsFullyQualified: %w", err) } } diff --git a/providers/windows/host_windows_test.go b/providers/windows/host_windows_test.go index 61503f45..e649b020 100644 --- a/providers/windows/host_windows_test.go +++ b/providers/windows/host_windows_test.go @@ -1,3 +1,20 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + package windows import ( From c1b9c4877abe42b23d1a93421511294c40fb35f8 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Thu, 5 Jan 2023 17:31:19 +0100 Subject: [PATCH 06/65] nocgo fallback and fix darwin types --- providers/darwin/host_darwin.go | 32 +------------ providers/darwin/host_fqdn_cgo_darwin.go | 53 ++++++++++++++++++++ providers/darwin/host_fqdn_nocgo_darwin.go | 24 ++++++++++ providers/linux/host_fqdn_cgo_linux.go | 56 ++++++++++++++++++++++ providers/linux/host_fqdn_nocgo_linux.go | 24 ++++++++++ providers/linux/host_linux.go | 34 +------------ 6 files changed, 159 insertions(+), 64 deletions(-) create mode 100644 providers/darwin/host_fqdn_cgo_darwin.go create mode 100644 providers/darwin/host_fqdn_nocgo_darwin.go create mode 100644 providers/linux/host_fqdn_cgo_linux.go create mode 100644 providers/linux/host_fqdn_nocgo_linux.go diff --git a/providers/darwin/host_darwin.go b/providers/darwin/host_darwin.go index c87c7167..3a21c6f1 100644 --- a/providers/darwin/host_darwin.go +++ b/providers/darwin/host_darwin.go @@ -20,13 +20,11 @@ package darwin -import "C" import ( "errors" "fmt" "os" "time" - "unsafe" "github.com/joeshaw/multierror" @@ -217,7 +215,7 @@ func (r *reader) hostname(h *host) { } func (r *reader) fqdn(h *host) { - fqdn, err := fqdnC() + fqdn, err := fqdn() if err != nil { r.addErr(fmt.Errorf("could not get linux FQDN: %w", err)) return @@ -226,34 +224,6 @@ func (r *reader) fqdn(h *host) { h.info.FQDN = fqdn } -func fqdnC() (string, error) { - // Another option could be reading: - // - /proc/sys/kernel/hostname - // - /proc/sys/kernel/domainname - const buffSize = 64 - buff := make([]byte, buffSize) - size := C.size_t(buffSize) - cString := C.CString(string(buff)) - defer C.free(unsafe.Pointer(cString)) - - _, errno := C.gethostname(cString, size) - if errno != nil { - return "", fmt.Errorf("syscall gethostname errored: %v", errno) - } - var hostname string = C.GoString(cString) - - _, errno = C.getdomainname(cString, size) - if errno != nil { - return "", fmt.Errorf("syscall getdomainname errored: %v", errno) - } - var domain string = C.GoString(cString) - if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour - domain = "lan" - } - - return fmt.Sprintf("%s.%s", hostname, domain), nil -} - func (r *reader) network(h *host) { ips, macs, err := shared.Network() if r.addErr(err) { diff --git a/providers/darwin/host_fqdn_cgo_darwin.go b/providers/darwin/host_fqdn_cgo_darwin.go new file mode 100644 index 00000000..4ed013db --- /dev/null +++ b/providers/darwin/host_fqdn_cgo_darwin.go @@ -0,0 +1,53 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build cgo && (amd64 || arm64) + +package darwin + +// #include +// #include +import "C" +import ( + "fmt" + "unsafe" +) + +func fqdn() (string, error) { + const buffSize = 64 + buff := make([]byte, buffSize) + size := buffSize + cString := C.CString(string(buff)) + defer C.free(unsafe.Pointer(cString)) + + _, errno := C.gethostname(cString, C.size_t(size)) + if errno != nil { + return "", fmt.Errorf("syscall gethostname errored: %v", errno) + } + var hostname string = C.GoString(cString) + + _, errno = C.getdomainname(cString, C.int(size)) + if errno != nil { + return "", fmt.Errorf("syscall getdomainname errored: %v", errno) + } + var domain string = C.GoString(cString) + if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour + domain = "lan" + } + + return fmt.Sprintf("%s.%s", hostname, domain), nil +} diff --git a/providers/darwin/host_fqdn_nocgo_darwin.go b/providers/darwin/host_fqdn_nocgo_darwin.go new file mode 100644 index 00000000..8cf996c9 --- /dev/null +++ b/providers/darwin/host_fqdn_nocgo_darwin.go @@ -0,0 +1,24 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build !cgo && (amd64 || arm64) + +package darwin + +import "os" + +func fqdn() (string, error) { return os.Hostname() } diff --git a/providers/linux/host_fqdn_cgo_linux.go b/providers/linux/host_fqdn_cgo_linux.go new file mode 100644 index 00000000..4b478154 --- /dev/null +++ b/providers/linux/host_fqdn_cgo_linux.go @@ -0,0 +1,56 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build cgo && (amd64 || arm64) + +package linux + +// #include +// #include +import "C" +import ( + "fmt" + "unsafe" +) + +func fqdn() (string, error) { + // Another option could be reading: + // - /proc/sys/kernel/hostname + // - /proc/sys/kernel/domainname + const buffSize = 64 + buff := make([]byte, buffSize) + size := C.size_t(buffSize) + cString := C.CString(string(buff)) + defer C.free(unsafe.Pointer(cString)) + + _, errno := C.gethostname(cString, size) + if errno != nil { + return "", fmt.Errorf("syscall gethostname errored: %v", errno) + } + var hostname string = C.GoString(cString) + + _, errno = C.getdomainname(cString, size) + if errno != nil { + return "", fmt.Errorf("syscall getdomainname errored: %v", errno) + } + var domain string = C.GoString(cString) + if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour + domain = "lan" + } + + return fmt.Sprintf("%s.%s", hostname, domain), nil +} diff --git a/providers/linux/host_fqdn_nocgo_linux.go b/providers/linux/host_fqdn_nocgo_linux.go new file mode 100644 index 00000000..a833c6f3 --- /dev/null +++ b/providers/linux/host_fqdn_nocgo_linux.go @@ -0,0 +1,24 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build !cgo && (amd64 || arm64) + +package linux + +import "os" + +func fqdn() (string, error) { return os.Hostname() } diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index da11c599..0b304cbf 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -17,10 +17,7 @@ package linux -// #include -// #include import "C" - import ( "errors" "fmt" @@ -28,7 +25,6 @@ import ( "os" "path/filepath" "time" - "unsafe" "github.com/joeshaw/multierror" "github.com/prometheus/procfs" @@ -218,7 +214,7 @@ func (r *reader) hostname(h *host) { } func (r *reader) fqdn(h *host) { - fqdn, err := fqdnC() + fqdn, err := fqdn() if err != nil { r.addErr(fmt.Errorf("could not get linux FQDN: %w", err)) return @@ -227,34 +223,6 @@ func (r *reader) fqdn(h *host) { h.info.FQDN = fqdn } -func fqdnC() (string, error) { - // Another option could be reading: - // - /proc/sys/kernel/hostname - // - /proc/sys/kernel/domainname - const buffSize = 64 - buff := make([]byte, buffSize) - size := C.size_t(buffSize) - cString := C.CString(string(buff)) - defer C.free(unsafe.Pointer(cString)) - - _, errno := C.gethostname(cString, size) - if errno != nil { - return "", fmt.Errorf("syscall gethostname errored: %v", errno) - } - var hostname string = C.GoString(cString) - - _, errno = C.getdomainname(cString, size) - if errno != nil { - return "", fmt.Errorf("syscall getdomainname errored: %v", errno) - } - var domain string = C.GoString(cString) - if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour - domain = "lan" - } - - return fmt.Sprintf("%s.%s", hostname, domain), nil -} - func (r *reader) network(h *host) { ips, macs, err := shared.Network() if r.addErr(err) { From 92329213f24dd5f8eb90d5e70bbbabf606758286 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 17 Jan 2023 07:43:30 +0100 Subject: [PATCH 07/65] add doc --- types/host.go | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/types/host.go b/types/host.go index ff4253f1..80c3c293 100644 --- a/types/host.go +++ b/types/host.go @@ -63,18 +63,20 @@ type VMStat interface { // HostInfo contains basic host information. type HostInfo struct { - Architecture string `json:"architecture"` // Hardware architecture (e.g. x86_64, arm, ppc, mips). - BootTime time.Time `json:"boot_time"` // Host boot time. - Containerized *bool `json:"containerized,omitempty"` // Is the process containerized. - Hostname string `json:"name"` // Hostname - FQDN string `json:"fqdn"` // FQDN - IPs []string `json:"ip,omitempty"` // List of all IPs. - KernelVersion string `json:"kernel_version"` // Kernel version. - MACs []string `json:"mac"` // List of MAC addresses. - OS *OSInfo `json:"os"` // OS information. - Timezone string `json:"timezone"` // System timezone. - TimezoneOffsetSec int `json:"timezone_offset_sec"` // Timezone offset (seconds from UTC). - UniqueID string `json:"id,omitempty"` // Unique ID of the host (optional). + Architecture string `json:"architecture"` // Hardware architecture (e.g. x86_64, arm, ppc, mips). + BootTime time.Time `json:"boot_time"` // Host boot time. + Containerized *bool `json:"containerized,omitempty"` // Is the process containerized. + Hostname string `json:"name"` // Hostname + // FQDN is the Fully qualified domain name, for linux and darwin it requires CGO. + // if CGO is not enabled it'll fallback to os.Hostname(), the same as Hostname. + FQDN string `json:"fqdn"` + IPs []string `json:"ip,omitempty"` // List of all IPs. + KernelVersion string `json:"kernel_version"` // Kernel version. + MACs []string `json:"mac"` // List of MAC addresses. + OS *OSInfo `json:"os"` // OS information. + Timezone string `json:"timezone"` // System timezone. + TimezoneOffsetSec int `json:"timezone_offset_sec"` // Timezone offset (seconds from UTC). + UniqueID string `json:"id,omitempty"` // Unique ID of the host (optional). } // Uptime returns the system uptime From 78a3239b0e1b0fe33a7206409e962fa2a8b0b759 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 17 Jan 2023 07:48:24 +0100 Subject: [PATCH 08/65] wip --- providers/darwin/host_fqdn_cgo_darwin.go | 2 +- providers/darwin/host_fqdn_nocgo_darwin.go | 2 +- providers/linux/host_fqdn_cgo_linux.go | 2 +- providers/linux/host_fqdn_nocgo_linux.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/providers/darwin/host_fqdn_cgo_darwin.go b/providers/darwin/host_fqdn_cgo_darwin.go index 4ed013db..ac8fa5b9 100644 --- a/providers/darwin/host_fqdn_cgo_darwin.go +++ b/providers/darwin/host_fqdn_cgo_darwin.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -//go:build cgo && (amd64 || arm64) +//go:build cgo package darwin diff --git a/providers/darwin/host_fqdn_nocgo_darwin.go b/providers/darwin/host_fqdn_nocgo_darwin.go index 8cf996c9..fc1bfa47 100644 --- a/providers/darwin/host_fqdn_nocgo_darwin.go +++ b/providers/darwin/host_fqdn_nocgo_darwin.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -//go:build !cgo && (amd64 || arm64) +//go:build !cgo package darwin diff --git a/providers/linux/host_fqdn_cgo_linux.go b/providers/linux/host_fqdn_cgo_linux.go index 4b478154..9ff10d8e 100644 --- a/providers/linux/host_fqdn_cgo_linux.go +++ b/providers/linux/host_fqdn_cgo_linux.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -//go:build cgo && (amd64 || arm64) +//go:build cgo package linux diff --git a/providers/linux/host_fqdn_nocgo_linux.go b/providers/linux/host_fqdn_nocgo_linux.go index a833c6f3..13a2fe0a 100644 --- a/providers/linux/host_fqdn_nocgo_linux.go +++ b/providers/linux/host_fqdn_nocgo_linux.go @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -//go:build !cgo && (amd64 || arm64) +//go:build !cgo package linux From 7128e81a10644fd36b89d0ea614c77b00561064f Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 17 Jan 2023 07:52:18 +0100 Subject: [PATCH 09/65] remove unnecessary C import --- providers/linux/host_linux.go | 1 - 1 file changed, 1 deletion(-) diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index 0b304cbf..f1b0136c 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -17,7 +17,6 @@ package linux -import "C" import ( "errors" "fmt" From e387f3cf448c1f5014bb9f00f01175108b5c0010 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Mon, 23 Jan 2023 08:31:02 +0100 Subject: [PATCH 10/65] wip --- go.mod | 25 ++- go.sum | 98 ++++++++- providers/darwin/host_darwin.go | 9 + providers/darwin/host_fqdn_cgo_darwin.go | 30 ++- providers/darwin/host_fqdn_nocgo_darwin.go | 8 +- providers/linux/host_fqdn_cgo_linux.go | 38 ++-- .../linux/host_fqdn_integration_linux_test.go | 198 ++++++++++++++++++ providers/linux/host_fqdn_nocgo_linux.go | 8 +- providers/linux/host_linux.go | 9 + providers/linux/host_linux_test.go | 1 - providers/windows/host_windows.go | 29 ++- types/host.go | 2 + 12 files changed, 412 insertions(+), 43 deletions(-) create mode 100644 providers/linux/host_fqdn_integration_linux_test.go diff --git a/go.mod b/go.mod index 3116420c..380be64d 100644 --- a/go.mod +++ b/go.mod @@ -3,16 +3,33 @@ module github.com/elastic/go-sysinfo go 1.17 require ( + github.com/docker/docker v20.10.22+incompatible github.com/elastic/go-windows v1.0.0 github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 github.com/prometheus/procfs v0.8.0 - github.com/stretchr/testify v1.3.0 - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a + github.com/stretchr/testify v1.7.0 + golang.org/x/sys v0.1.0 howett.net/plist v0.0.0-20181124034731-591f970eefbb ) require ( - github.com/davecgh/go-spew v1.1.0 // indirect - github.com/pkg/errors v0.8.1 // indirect + github.com/Microsoft/go-winio v0.6.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/docker/distribution v2.8.1+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect + github.com/morikuni/aec v1.0.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect + golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.1.12 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect + gotest.tools/v3 v3.4.0 // indirect ) diff --git a/go.sum b/go.sum index 66a1db27..e77d436a 100644 --- a/go.sum +++ b/go.sum @@ -1,29 +1,121 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= +github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= +github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v20.10.22+incompatible h1:6jX4yB+NtcbldT90k7vBSaWJDB3i+zkVJT9BEK8kQkk= +github.com/docker/docker v20.10.22+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/elastic/go-windows v1.0.0 h1:qLURgZFkkrYyTTkvYpsZIgf83AUsdIHfvlJaqaZ7aSY= github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= +github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= +gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= diff --git a/providers/darwin/host_darwin.go b/providers/darwin/host_darwin.go index 3a21c6f1..71c956aa 100644 --- a/providers/darwin/host_darwin.go +++ b/providers/darwin/host_darwin.go @@ -160,6 +160,7 @@ func newHost() (*host, error) { r.architecture(h) r.bootTime(h) r.hostname(h) + r.domain(h) r.fqdn(h) r.network(h) r.kernelVersion(h) @@ -214,6 +215,14 @@ func (r *reader) hostname(h *host) { h.info.Hostname = v } +func (r *reader) domain(h *host) { + v, err := domain() + if r.addErr(err) { + return + } + h.info.Domain = v +} + func (r *reader) fqdn(h *host) { fqdn, err := fqdn() if err != nil { diff --git a/providers/darwin/host_fqdn_cgo_darwin.go b/providers/darwin/host_fqdn_cgo_darwin.go index ac8fa5b9..efec457a 100644 --- a/providers/darwin/host_fqdn_cgo_darwin.go +++ b/providers/darwin/host_fqdn_cgo_darwin.go @@ -24,30 +24,38 @@ package darwin import "C" import ( "fmt" + "os" "unsafe" ) func fqdn() (string, error) { + hostname, err := os.Hostname() + if err != nil { + return "", err + } + + domain, err := domain() + if err != nil { + return "", err + } + if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour + domain = "lan" + } + + return fmt.Sprintf("%s.%s", hostname, domain), nil +} + +func domain() (string, error) { const buffSize = 64 buff := make([]byte, buffSize) size := buffSize cString := C.CString(string(buff)) defer C.free(unsafe.Pointer(cString)) - _, errno := C.gethostname(cString, C.size_t(size)) - if errno != nil { - return "", fmt.Errorf("syscall gethostname errored: %v", errno) - } - var hostname string = C.GoString(cString) - _, errno = C.getdomainname(cString, C.int(size)) if errno != nil { return "", fmt.Errorf("syscall getdomainname errored: %v", errno) } - var domain string = C.GoString(cString) - if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour - domain = "lan" - } - return fmt.Sprintf("%s.%s", hostname, domain), nil + return C.GoString(cString), nil } diff --git a/providers/darwin/host_fqdn_nocgo_darwin.go b/providers/darwin/host_fqdn_nocgo_darwin.go index fc1bfa47..fd1503fd 100644 --- a/providers/darwin/host_fqdn_nocgo_darwin.go +++ b/providers/darwin/host_fqdn_nocgo_darwin.go @@ -19,6 +19,10 @@ package darwin -import "os" +func fqdn() (string, error) { + return "", nil +} -func fqdn() (string, error) { return os.Hostname() } +func domain() (string, error) { + return "", nil +} diff --git a/providers/linux/host_fqdn_cgo_linux.go b/providers/linux/host_fqdn_cgo_linux.go index 9ff10d8e..5b63d71a 100644 --- a/providers/linux/host_fqdn_cgo_linux.go +++ b/providers/linux/host_fqdn_cgo_linux.go @@ -24,33 +24,45 @@ package linux import "C" import ( "fmt" + "os" "unsafe" ) func fqdn() (string, error) { - // Another option could be reading: - // - /proc/sys/kernel/hostname - // - /proc/sys/kernel/domainname + hostname, err := os.Hostname() + if err != nil { + return "", err + } + + domain, err := domain() + if err != nil { + return "", err + } + + if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour + domain = "lan" + } + + return fmt.Sprintf("%s.%s", hostname, domain), nil +} + +func domain() (string, error) { const buffSize = 64 buff := make([]byte, buffSize) size := C.size_t(buffSize) cString := C.CString(string(buff)) defer C.free(unsafe.Pointer(cString)) - _, errno := C.gethostname(cString, size) - if errno != nil { - return "", fmt.Errorf("syscall gethostname errored: %v", errno) - } - var hostname string = C.GoString(cString) - - _, errno = C.getdomainname(cString, size) + _, errno := C.getdomainname(cString, size) if errno != nil { return "", fmt.Errorf("syscall getdomainname errored: %v", errno) } + var domain string = C.GoString(cString) - if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour - domain = "lan" + + if domain == "(none)" { // mimicking 'hostname -f' behaviour + domain = "" } - return fmt.Sprintf("%s.%s", hostname, domain), nil + return domain, nil } diff --git a/providers/linux/host_fqdn_integration_linux_test.go b/providers/linux/host_fqdn_integration_linux_test.go new file mode 100644 index 00000000..09bcc990 --- /dev/null +++ b/providers/linux/host_fqdn_integration_linux_test.go @@ -0,0 +1,198 @@ +package linux + +import ( + "context" + "fmt" + "io" + "os" + "testing" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/client" + "github.com/docker/docker/pkg/stdcopy" +) + +const wantHostname = "debian" +const wantDomainCgo = "cgo" + +func TestHost_FQDN_Domain_Cgo(t *testing.T) { + host, err := newLinuxSystem("").Host() + if err != nil { + t.Fatal(fmt.Errorf("could not het host information: %w", err)) + } + + got := host.Info() + if got.Hostname != wantHostname { + t.Errorf("got wrong hostname want: %q, got %q", wantHostname, got.Hostname) + } + if got.Domain != wantDomainCgo { + t.Errorf("got wrong domain want: %q, got %q", wantDomainCgo, got.Domain) + } + if got.FQDN != fmt.Sprintf("%s.%s", wantHostname, wantDomainCgo) { + t.Errorf("FQDN shpould not be empty") + } +} + +func TestHost_FQDN_No_Domain_Cgo(t *testing.T) { + host, err := newLinuxSystem("").Host() + if err != nil { + t.Fatal(fmt.Errorf("could not het host information: %w", err)) + } + + got := host.Info() + if got.Hostname != wantHostname { + t.Errorf("got wrong hostname want: %s, got %s", wantHostname, got.Hostname) + } + if got.Domain != "" { + t.Errorf("got wrong domain should be empty but got %s", got.Domain) + } + wantFQDN := fmt.Sprintf("%s.%s", wantHostname, "lan") + if got.FQDN != wantFQDN { + t.Errorf("got wrong FQDN, want: %s, got %s", wantFQDN, got.FQDN) + } +} + +func TestHost_FQDN_Domain_NoCgo(t *testing.T) { + t.SkipNow() + host, err := newLinuxSystem("").Host() + if err != nil { + t.Fatal(fmt.Errorf("could not het host information: %w", err)) + } + + got := host.Info() + if got.Hostname != wantHostname { + t.Errorf("hostname want: %s, got %s", wantHostname, got.Hostname) + } + if got.Domain != "" { + t.Errorf("domain should be empty but got %s", got.Domain) + } + if got.FQDN != "" { + t.Errorf("FQDN should empty, got: %s", got.FQDN) + } +} + +func TestHost_FQDN(t *testing.T) { + tcs := []struct { + name string + want string + cf container.Config + }{ + { + name: "debian Cgo with domain", + want: "debian.cgo", + cf: container.Config{ + Hostname: wantHostname, + Domainname: wantDomainCgo, + AttachStderr: testing.Verbose(), + AttachStdout: testing.Verbose(), + WorkingDir: "/usr/src/elastic/go-sysinfo", + Image: "golang:1.19-bullseye", + Cmd: []string{"go", "test", "-v", "-run", + "^TestHost_FQDN_Domain_Cgo", "./providers/linux"}, + Tty: false, + }, + }, + { + name: "debian Cgo no domain", + want: "debian.cgo", + cf: container.Config{ + Hostname: wantHostname, + AttachStderr: testing.Verbose(), + AttachStdout: testing.Verbose(), + WorkingDir: "/usr/src/elastic/go-sysinfo", + Image: "golang:1.19-bullseye", + Cmd: []string{"go", "test", "-v", "-run", + "^TestHost_FQDN_No_Domain_Cgo", "./providers/linux"}, + Tty: false, + }, + }, + { + name: "debian no Cgo", + want: "debian.nocgo", + cf: container.Config{ + Hostname: wantHostname, + AttachStderr: testing.Verbose(), + AttachStdout: testing.Verbose(), + Env: []string{"CGO_ENABLED=0"}, + WorkingDir: "/usr/src/elastic/go-sysinfo", + Image: "golang:1.19-bullseye", + Cmd: []string{"go", "test", "-v", "-run", + "^TestHost_FQDN_Domain_NoCgo", "./providers/linux"}, + Tty: false, + }, + }, + } + + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + panic(err) + } + defer cli.Close() + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + runOnDocker(t, cli, &tc.cf) + }) + } +} + +func runOnDocker(t *testing.T, cli *client.Client, cf *container.Config) { + ctx := context.Background() + + pwd, err := os.Getwd() + if err != nil { + panic(err) + } + wd := pwd + "../../../" + + reader, err := cli.ImagePull(ctx, cf.Image, types.ImagePullOptions{}) + if err != nil { + panic(err) + } + defer reader.Close() + io.Copy(os.Stdout, reader) + + resp, err := cli.ContainerCreate(ctx, cf, &container.HostConfig{ + AutoRemove: false, + Binds: []string{wd + ":/usr/src/elastic/go-sysinfo"}, + }, nil, nil, "") + if err != nil { + panic(err) + } + defer func() { + err = cli.ContainerRemove(ctx, resp.ID, types.ContainerRemoveOptions{ + Force: true, RemoveVolumes: true}) + if err != nil { + panic(err) + } + }() + + if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil { + panic(err) + } + + statusCh, errCh := cli.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning) + select { + case err := <-errCh: + if err != nil { + panic(err) + } + case s := <-statusCh: + if s.StatusCode != 0 { + var err error + if s.Error != nil { + err = fmt.Errorf("container errored: %s", s.Error.Message) + } + t.Errorf("conteiner exited with code %d: error: %v", s.StatusCode, err) + } + t.Log("docker starts channel:", s) + } + + out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStderr: true, ShowStdout: true}) + if err != nil { + panic(err) + } + + stdcopy.StdCopy(os.Stdout, os.Stderr, out) +} diff --git a/providers/linux/host_fqdn_nocgo_linux.go b/providers/linux/host_fqdn_nocgo_linux.go index 13a2fe0a..19f36293 100644 --- a/providers/linux/host_fqdn_nocgo_linux.go +++ b/providers/linux/host_fqdn_nocgo_linux.go @@ -19,6 +19,10 @@ package linux -import "os" +func fqdn() (string, error) { + return "", nil +} -func fqdn() (string, error) { return os.Hostname() } +func domain() (string, error) { + return "", nil +} diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index f1b0136c..a5412a62 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -149,6 +149,7 @@ func newHost(fs procFS) (*host, error) { r.bootTime(h) r.containerized(h) r.hostname(h) + r.domain(h) r.fqdn(h) r.network(h) r.kernelVersion(h) @@ -212,6 +213,14 @@ func (r *reader) hostname(h *host) { h.info.Hostname = v } +func (r *reader) domain(h *host) { + v, err := domain() + if r.addErr(err) { + return + } + h.info.Domain = v +} + func (r *reader) fqdn(h *host) { fqdn, err := fqdn() if err != nil { diff --git a/providers/linux/host_linux_test.go b/providers/linux/host_linux_test.go index 6884b4ec..5abe0908 100644 --- a/providers/linux/host_linux_test.go +++ b/providers/linux/host_linux_test.go @@ -34,7 +34,6 @@ func TestHost(t *testing.T) { if err != nil { t.Fatal(err) } - info := host.Info() data, _ := json.MarshalIndent(info, "", " ") t.Log(string(data)) diff --git a/providers/windows/host_windows.go b/providers/windows/host_windows.go index 81657dd1..542f4ab6 100644 --- a/providers/windows/host_windows.go +++ b/providers/windows/host_windows.go @@ -88,6 +88,7 @@ func newHost() (*host, error) { r.architecture(h) r.bootTime(h) r.hostname(h) + r.domain(h) r.fqdn(h) r.network(h) r.kernelVersion(h) @@ -142,21 +143,35 @@ func (r *reader) hostname(h *host) { h.info.Hostname = v } +func (r *reader) domain(h *host) { + v, err := domain + if r.addErr(err) { + return + } + h.info.Domain = v +} + func (r *reader) fqdn(h *host) { - hostname, err := getComputerNameEx(stdwindows.ComputerNamePhysicalDnsHostname) + hostname, err := os.Hostname() + + dnsDomain, err := getComputerNameEx(stdwindows.ComputerNamePhysicalDnsDomain) if err != nil { - r.addErr(fmt.Errorf("could not get windows hostname to build FQDN: %s", err)) + r.addErr(fmt.Errorf("could not get windows dnsDomain to build FQDN: %s", err)) + } + if dnsDomain == "" { + dnsDomain = "lan" } + h.info.FQDN = fmt.Sprintf("%s.%s", hostname, dnsDomain) +} + +func domain() { dns, err := getComputerNameEx(stdwindows.ComputerNamePhysicalDnsDomain) if err != nil { - r.addErr(fmt.Errorf("could not get windows dns to build FQDN: %s", err)) - } - if dns == "" { - dns = "lan" + return "", fmt.Errorf("could not get windows dns to build FQDN: %s", err) } - h.info.FQDN = fmt.Sprintf("%s.%s", hostname, dns) + return dns, nil } func getComputerNameEx(name uint32) (string, error) { diff --git a/types/host.go b/types/host.go index 80c3c293..be43ef3c 100644 --- a/types/host.go +++ b/types/host.go @@ -67,8 +67,10 @@ type HostInfo struct { BootTime time.Time `json:"boot_time"` // Host boot time. Containerized *bool `json:"containerized,omitempty"` // Is the process containerized. Hostname string `json:"name"` // Hostname + Domain string `json:"domain"` // Domain // FQDN is the Fully qualified domain name, for linux and darwin it requires CGO. // if CGO is not enabled it'll fallback to os.Hostname(), the same as Hostname. + // If no domain can be obtained, .lan will be used instead. FQDN string `json:"fqdn"` IPs []string `json:"ip,omitempty"` // List of all IPs. KernelVersion string `json:"kernel_version"` // Kernel version. From 79a48f45ed6ccce69173db48e1d5f38e2672392c Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Mon, 23 Jan 2023 08:34:44 +0100 Subject: [PATCH 11/65] . --- providers/windows/host_windows.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/windows/host_windows.go b/providers/windows/host_windows.go index 542f4ab6..d12e1200 100644 --- a/providers/windows/host_windows.go +++ b/providers/windows/host_windows.go @@ -154,7 +154,7 @@ func (r *reader) domain(h *host) { func (r *reader) fqdn(h *host) { hostname, err := os.Hostname() - dnsDomain, err := getComputerNameEx(stdwindows.ComputerNamePhysicalDnsDomain) + dnsDomain, err := domain if err != nil { r.addErr(fmt.Errorf("could not get windows dnsDomain to build FQDN: %s", err)) } From 21d5286f7e00543e5fd52a84fa1bb1236b82406f Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Mon, 23 Jan 2023 08:49:19 +0100 Subject: [PATCH 12/65] . --- providers/linux/host_fqdn_integration_linux_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/providers/linux/host_fqdn_integration_linux_test.go b/providers/linux/host_fqdn_integration_linux_test.go index 09bcc990..34c75ca9 100644 --- a/providers/linux/host_fqdn_integration_linux_test.go +++ b/providers/linux/host_fqdn_integration_linux_test.go @@ -75,12 +75,10 @@ func TestHost_FQDN_Domain_NoCgo(t *testing.T) { func TestHost_FQDN(t *testing.T) { tcs := []struct { name string - want string cf container.Config }{ { name: "debian Cgo with domain", - want: "debian.cgo", cf: container.Config{ Hostname: wantHostname, Domainname: wantDomainCgo, @@ -95,7 +93,6 @@ func TestHost_FQDN(t *testing.T) { }, { name: "debian Cgo no domain", - want: "debian.cgo", cf: container.Config{ Hostname: wantHostname, AttachStderr: testing.Verbose(), @@ -109,7 +106,6 @@ func TestHost_FQDN(t *testing.T) { }, { name: "debian no Cgo", - want: "debian.nocgo", cf: container.Config{ Hostname: wantHostname, AttachStderr: testing.Verbose(), From 8b03c7a29f53568b575fc5dfed99dd1cad1bcfc3 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Mon, 23 Jan 2023 08:59:33 +0100 Subject: [PATCH 13/65] . --- types/host.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/types/host.go b/types/host.go index be43ef3c..1a2fdfe3 100644 --- a/types/host.go +++ b/types/host.go @@ -67,10 +67,13 @@ type HostInfo struct { BootTime time.Time `json:"boot_time"` // Host boot time. Containerized *bool `json:"containerized,omitempty"` // Is the process containerized. Hostname string `json:"name"` // Hostname - Domain string `json:"domain"` // Domain - // FQDN is the Fully qualified domain name, for linux and darwin it requires CGO. - // if CGO is not enabled it'll fallback to os.Hostname(), the same as Hostname. - // If no domain can be obtained, .lan will be used instead. + // Domain requires Cgo for linux and darwin, therefore it'll be empty if Cgo + // is disabled. + Domain string `json:"domain"` // Domain + // FQDN (Fully qualified domain name) depends on Domain and therefore on Cgo + // for linux and darwin. + // When Cgo is disabled, FQDN is empty. If Domain is empty, but Cgo is enabled, + // FQDN will be "hostname.lan". FQDN string `json:"fqdn"` IPs []string `json:"ip,omitempty"` // List of all IPs. KernelVersion string `json:"kernel_version"` // Kernel version. From 65bd27482c82e7da798eb14a38c2d9ee40292d64 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Mon, 23 Jan 2023 09:14:42 +0100 Subject: [PATCH 14/65] add license header --- .../linux/host_fqdn_integration_linux_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/providers/linux/host_fqdn_integration_linux_test.go b/providers/linux/host_fqdn_integration_linux_test.go index 34c75ca9..89c76c55 100644 --- a/providers/linux/host_fqdn_integration_linux_test.go +++ b/providers/linux/host_fqdn_integration_linux_test.go @@ -1,3 +1,20 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + package linux import ( From 2b02410ec9b580696b798d6129ab3cf5971eecc5 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Mon, 23 Jan 2023 09:16:58 +0100 Subject: [PATCH 15/65] add integration build tag and run them on ci --- .ci/scripts/test.sh | 2 +- providers/linux/host_fqdn_integration_linux_test.go | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.ci/scripts/test.sh b/.ci/scripts/test.sh index e0d5d6b0..18a3f3b9 100755 --- a/.ci/scripts/test.sh +++ b/.ci/scripts/test.sh @@ -37,7 +37,7 @@ fi set +e export OUT_FILE="build/test-report.out" mkdir -p build -go test "./..." -v 2>&1 | tee ${OUT_FILE} +go test -tags integration "./..." -v 2>&1 | tee ${OUT_FILE} status=$? go install github.com/jstemmer/go-junit-report/v2@latest go-junit-report > "build/junit-${GO_VERSION}.xml" < ${OUT_FILE} diff --git a/providers/linux/host_fqdn_integration_linux_test.go b/providers/linux/host_fqdn_integration_linux_test.go index 89c76c55..54be893e 100644 --- a/providers/linux/host_fqdn_integration_linux_test.go +++ b/providers/linux/host_fqdn_integration_linux_test.go @@ -15,6 +15,8 @@ // specific language governing permissions and limitations // under the License. +//go:build integration + package linux import ( From 0587e49c80a0a7580640f7b952a7d9d69ba96cc2 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Mon, 23 Jan 2023 14:32:12 +0100 Subject: [PATCH 16/65] adjust tests --- providers/darwin/host_fqdn_cgo_darwin.go | 2 +- ...host_fqdn_integration_docker_linux_test.go | 80 +++++++++++++ .../linux/host_fqdn_integration_linux_test.go | 105 ++++++------------ providers/windows/host_windows.go | 6 +- 4 files changed, 115 insertions(+), 78 deletions(-) create mode 100644 providers/linux/host_fqdn_integration_docker_linux_test.go diff --git a/providers/darwin/host_fqdn_cgo_darwin.go b/providers/darwin/host_fqdn_cgo_darwin.go index efec457a..c88f531e 100644 --- a/providers/darwin/host_fqdn_cgo_darwin.go +++ b/providers/darwin/host_fqdn_cgo_darwin.go @@ -52,7 +52,7 @@ func domain() (string, error) { cString := C.CString(string(buff)) defer C.free(unsafe.Pointer(cString)) - _, errno = C.getdomainname(cString, C.int(size)) + _, errno := C.getdomainname(cString, C.int(size)) if errno != nil { return "", fmt.Errorf("syscall getdomainname errored: %v", errno) } diff --git a/providers/linux/host_fqdn_integration_docker_linux_test.go b/providers/linux/host_fqdn_integration_docker_linux_test.go new file mode 100644 index 00000000..f9f7c70e --- /dev/null +++ b/providers/linux/host_fqdn_integration_docker_linux_test.go @@ -0,0 +1,80 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build integration && docker + +package linux + +import ( + "fmt" + "testing" +) + +func TestHost_FQDN_Domain_Cgo(t *testing.T) { + host, err := newLinuxSystem("").Host() + if err != nil { + t.Fatal(fmt.Errorf("could not het host information: %w", err)) + } + + got := host.Info() + if got.Hostname != wantHostname { + t.Errorf("got wrong hostname want: %q, got %q", wantHostname, got.Hostname) + } + if got.Domain != wantDomainCgo { + t.Errorf("got wrong domain want: %q, got %q", wantDomainCgo, got.Domain) + } + if got.FQDN != fmt.Sprintf("%s.%s", wantHostname, wantDomainCgo) { + t.Errorf("FQDN shpould not be empty") + } +} + +func TestHost_FQDN_No_Domain_Cgo(t *testing.T) { + host, err := newLinuxSystem("").Host() + if err != nil { + t.Fatal(fmt.Errorf("could not het host information: %w", err)) + } + + got := host.Info() + if got.Hostname != wantHostname { + t.Errorf("got wrong hostname want: %s, got %s", wantHostname, got.Hostname) + } + if got.Domain != "" { + t.Errorf("got wrong domain should be empty but got %s", got.Domain) + } + wantFQDN := fmt.Sprintf("%s.%s", wantHostname, "lan") + if got.FQDN != wantFQDN { + t.Errorf("got wrong FQDN, want: %s, got %s", wantFQDN, got.FQDN) + } +} + +func TestHost_FQDN_Domain_NoCgo(t *testing.T) { + host, err := newLinuxSystem("").Host() + if err != nil { + t.Fatal(fmt.Errorf("could not het host information: %w", err)) + } + + got := host.Info() + if got.Hostname != wantHostname { + t.Errorf("hostname want: %s, got %s", wantHostname, got.Hostname) + } + if got.Domain != "" { + t.Errorf("domain should be empty but got %s", got.Domain) + } + if got.FQDN != "" { + t.Errorf("FQDN should empty, got: %s", got.FQDN) + } +} diff --git a/providers/linux/host_fqdn_integration_linux_test.go b/providers/linux/host_fqdn_integration_linux_test.go index 54be893e..6fca8eea 100644 --- a/providers/linux/host_fqdn_integration_linux_test.go +++ b/providers/linux/host_fqdn_integration_linux_test.go @@ -35,62 +35,6 @@ import ( const wantHostname = "debian" const wantDomainCgo = "cgo" -func TestHost_FQDN_Domain_Cgo(t *testing.T) { - host, err := newLinuxSystem("").Host() - if err != nil { - t.Fatal(fmt.Errorf("could not het host information: %w", err)) - } - - got := host.Info() - if got.Hostname != wantHostname { - t.Errorf("got wrong hostname want: %q, got %q", wantHostname, got.Hostname) - } - if got.Domain != wantDomainCgo { - t.Errorf("got wrong domain want: %q, got %q", wantDomainCgo, got.Domain) - } - if got.FQDN != fmt.Sprintf("%s.%s", wantHostname, wantDomainCgo) { - t.Errorf("FQDN shpould not be empty") - } -} - -func TestHost_FQDN_No_Domain_Cgo(t *testing.T) { - host, err := newLinuxSystem("").Host() - if err != nil { - t.Fatal(fmt.Errorf("could not het host information: %w", err)) - } - - got := host.Info() - if got.Hostname != wantHostname { - t.Errorf("got wrong hostname want: %s, got %s", wantHostname, got.Hostname) - } - if got.Domain != "" { - t.Errorf("got wrong domain should be empty but got %s", got.Domain) - } - wantFQDN := fmt.Sprintf("%s.%s", wantHostname, "lan") - if got.FQDN != wantFQDN { - t.Errorf("got wrong FQDN, want: %s, got %s", wantFQDN, got.FQDN) - } -} - -func TestHost_FQDN_Domain_NoCgo(t *testing.T) { - t.SkipNow() - host, err := newLinuxSystem("").Host() - if err != nil { - t.Fatal(fmt.Errorf("could not het host information: %w", err)) - } - - got := host.Info() - if got.Hostname != wantHostname { - t.Errorf("hostname want: %s, got %s", wantHostname, got.Hostname) - } - if got.Domain != "" { - t.Errorf("domain should be empty but got %s", got.Domain) - } - if got.FQDN != "" { - t.Errorf("FQDN should empty, got: %s", got.FQDN) - } -} - func TestHost_FQDN(t *testing.T) { tcs := []struct { name string @@ -105,8 +49,11 @@ func TestHost_FQDN(t *testing.T) { AttachStdout: testing.Verbose(), WorkingDir: "/usr/src/elastic/go-sysinfo", Image: "golang:1.19-bullseye", - Cmd: []string{"go", "test", "-v", "-run", - "^TestHost_FQDN_Domain_Cgo", "./providers/linux"}, + Cmd: []string{ + "go", "test", "-v", + "-tags", "integration,docker", + "-run", "^TestHost_FQDN_Domain_Cgo", + "./providers/linux"}, Tty: false, }, }, @@ -118,8 +65,11 @@ func TestHost_FQDN(t *testing.T) { AttachStdout: testing.Verbose(), WorkingDir: "/usr/src/elastic/go-sysinfo", Image: "golang:1.19-bullseye", - Cmd: []string{"go", "test", "-v", "-run", - "^TestHost_FQDN_No_Domain_Cgo", "./providers/linux"}, + Cmd: []string{ + "go", "test", "-v", "-count", "1", + "-tags", "integration,docker", + "-run", "^TestHost_FQDN_No_Domain_Cgo", + "./providers/linux"}, Tty: false, }, }, @@ -132,8 +82,11 @@ func TestHost_FQDN(t *testing.T) { Env: []string{"CGO_ENABLED=0"}, WorkingDir: "/usr/src/elastic/go-sysinfo", Image: "golang:1.19-bullseye", - Cmd: []string{"go", "test", "-v", "-run", - "^TestHost_FQDN_Domain_NoCgo", "./providers/linux"}, + Cmd: []string{ + "go", "test", "-v", + "-tags", "integration,docker", + "-run", "^TestHost_FQDN_Domain_NoCgo", + "./providers/linux"}, Tty: false, }, }, @@ -141,7 +94,7 @@ func TestHost_FQDN(t *testing.T) { cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { - panic(err) + t.Fatalf("failed to create docker client: %v", err) } defer cli.Close() @@ -157,13 +110,13 @@ func runOnDocker(t *testing.T, cli *client.Client, cf *container.Config) { pwd, err := os.Getwd() if err != nil { - panic(err) + t.Fatalf("could not get current directory: %v", err) } wd := pwd + "../../../" reader, err := cli.ImagePull(ctx, cf.Image, types.ImagePullOptions{}) if err != nil { - panic(err) + t.Fatalf("failed to pull image %s: %v", cf.Image, err) } defer reader.Close() io.Copy(os.Stdout, reader) @@ -173,40 +126,44 @@ func runOnDocker(t *testing.T, cli *client.Client, cf *container.Config) { Binds: []string{wd + ":/usr/src/elastic/go-sysinfo"}, }, nil, nil, "") if err != nil { - panic(err) + t.Fatalf("could not create docker conteiner: %v", err) } defer func() { err = cli.ContainerRemove(ctx, resp.ID, types.ContainerRemoveOptions{ Force: true, RemoveVolumes: true}) if err != nil { - panic(err) + t.Logf("WARNING: could not remove docker container: %v", err) } }() if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil { - panic(err) + t.Fatalf("could not start docker container: %v", err) } statusCh, errCh := cli.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning) select { case err := <-errCh: if err != nil { - panic(err) + // Not using fatal as we might be able to recover the container + // logs. + t.Errorf("docker ContainerWait failed: %v", err) } case s := <-statusCh: if s.StatusCode != 0 { - var err error + msg := fmt.Sprintf("container exited with status code %d", s.StatusCode) if s.Error != nil { - err = fmt.Errorf("container errored: %s", s.Error.Message) + msg = fmt.Sprintf("%s: error: %s", msg, s.Error.Message) } - t.Errorf("conteiner exited with code %d: error: %v", s.StatusCode, err) + + // Not using fatal as we might be able to recover the container + // logs. + t.Errorf(msg) } - t.Log("docker starts channel:", s) } out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStderr: true, ShowStdout: true}) if err != nil { - panic(err) + t.Fatalf("could not get container logs: %v", err) } stdcopy.StdCopy(os.Stdout, os.Stderr, out) diff --git a/providers/windows/host_windows.go b/providers/windows/host_windows.go index d12e1200..5badf22e 100644 --- a/providers/windows/host_windows.go +++ b/providers/windows/host_windows.go @@ -144,7 +144,7 @@ func (r *reader) hostname(h *host) { } func (r *reader) domain(h *host) { - v, err := domain + v, err := domain() if r.addErr(err) { return } @@ -154,7 +154,7 @@ func (r *reader) domain(h *host) { func (r *reader) fqdn(h *host) { hostname, err := os.Hostname() - dnsDomain, err := domain + dnsDomain, err := domain() if err != nil { r.addErr(fmt.Errorf("could not get windows dnsDomain to build FQDN: %s", err)) } @@ -165,7 +165,7 @@ func (r *reader) fqdn(h *host) { h.info.FQDN = fmt.Sprintf("%s.%s", hostname, dnsDomain) } -func domain() { +func domain() (string, error) { dns, err := getComputerNameEx(stdwindows.ComputerNamePhysicalDnsDomain) if err != nil { return "", fmt.Errorf("could not get windows dns to build FQDN: %s", err) From c5a4262b8f61006a572e290b7768ab5239ed9342 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 24 Jan 2023 17:20:59 +0100 Subject: [PATCH 17/65] more info on test errors --- types/process.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/process.go b/types/process.go index 74a396e3..c02ac9dc 100644 --- a/types/process.go +++ b/types/process.go @@ -24,7 +24,7 @@ type Process interface { CPUTimer // Info returns process info. // It may return partial information if the provider - // implementation is unable to collect all of the necessary data. + // implementation is unable to collect all the necessary data. Info() (ProcessInfo, error) Memory() (MemoryInfo, error) User() (UserInfo, error) From 99d7550726f6875dccc46b61db43634b5e442379 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 24 Jan 2023 17:37:21 +0100 Subject: [PATCH 18/65] force ci build --- providers/linux/host_linux.go | 1 + 1 file changed, 1 insertion(+) diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index a5412a62..a77a56ee 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -35,6 +35,7 @@ import ( func init() { registry.Register(newLinuxSystem("")) + } type linuxSystem struct { From b09b009e2a55dad7a1b3c52719d674806cef35c5 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 24 Jan 2023 17:37:35 +0100 Subject: [PATCH 19/65] force ci build - undo changes --- providers/linux/host_linux.go | 1 - 1 file changed, 1 deletion(-) diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index a77a56ee..a5412a62 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -35,7 +35,6 @@ import ( func init() { registry.Register(newLinuxSystem("")) - } type linuxSystem struct { From 791efa3bcab1cb692da4f1f0a38261fb3630c2f7 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Thu, 26 Jan 2023 10:35:36 +0100 Subject: [PATCH 20/65] force ci build --- providers/linux/host_linux.go | 1 + 1 file changed, 1 insertion(+) diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index a5412a62..a77a56ee 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -35,6 +35,7 @@ import ( func init() { registry.Register(newLinuxSystem("")) + } type linuxSystem struct { From 47ca564ef504bb25b708af6397ef22a76f8d87a1 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Thu, 26 Jan 2023 10:35:51 +0100 Subject: [PATCH 21/65] force ci build - undo changes --- providers/linux/host_linux.go | 1 - 1 file changed, 1 deletion(-) diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index a77a56ee..a5412a62 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -35,7 +35,6 @@ import ( func init() { registry.Register(newLinuxSystem("")) - } type linuxSystem struct { From 6ea80122cc723f68acf6800b9341d589e83d56f2 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Thu, 26 Jan 2023 11:26:15 +0100 Subject: [PATCH 22/65] fetch FQDN instead of building it on windows --- providers/windows/host_windows.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/providers/windows/host_windows.go b/providers/windows/host_windows.go index 5badf22e..a4e4c03c 100644 --- a/providers/windows/host_windows.go +++ b/providers/windows/host_windows.go @@ -152,23 +152,20 @@ func (r *reader) domain(h *host) { } func (r *reader) fqdn(h *host) { - hostname, err := os.Hostname() - - dnsDomain, err := domain() + fqdn, err := getComputerNameEx( + stdwindows.ComputerNamePhysicalDnsFullyQualified) if err != nil { - r.addErr(fmt.Errorf("could not get windows dnsDomain to build FQDN: %s", err)) - } - if dnsDomain == "" { - dnsDomain = "lan" + r.addErr(fmt.Errorf("could not get windows FQDN: %s", err)) + return } - h.info.FQDN = fmt.Sprintf("%s.%s", hostname, dnsDomain) + h.info.FQDN = fqdn } func domain() (string, error) { dns, err := getComputerNameEx(stdwindows.ComputerNamePhysicalDnsDomain) if err != nil { - return "", fmt.Errorf("could not get windows dns to build FQDN: %s", err) + return "", fmt.Errorf("could not get windows dns: %s", err) } return dns, nil From 81020023d241e6cf697da2f55753f9aa800b73f0 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Thu, 26 Jan 2023 11:28:42 +0100 Subject: [PATCH 23/65] use local instead of lan for darwin --- providers/darwin/host_darwin.go | 4 ++-- providers/darwin/host_fqdn_cgo_darwin.go | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/providers/darwin/host_darwin.go b/providers/darwin/host_darwin.go index 71c956aa..a559407e 100644 --- a/providers/darwin/host_darwin.go +++ b/providers/darwin/host_darwin.go @@ -216,7 +216,7 @@ func (r *reader) hostname(h *host) { } func (r *reader) domain(h *host) { - v, err := domain() + v, err := domainname() if r.addErr(err) { return } @@ -226,7 +226,7 @@ func (r *reader) domain(h *host) { func (r *reader) fqdn(h *host) { fqdn, err := fqdn() if err != nil { - r.addErr(fmt.Errorf("could not get linux FQDN: %w", err)) + r.addErr(fmt.Errorf("could not get darwin FQDN: %w", err)) return } diff --git a/providers/darwin/host_fqdn_cgo_darwin.go b/providers/darwin/host_fqdn_cgo_darwin.go index c88f531e..98e3deb7 100644 --- a/providers/darwin/host_fqdn_cgo_darwin.go +++ b/providers/darwin/host_fqdn_cgo_darwin.go @@ -34,18 +34,19 @@ func fqdn() (string, error) { return "", err } - domain, err := domain() + domain, err := domainname() if err != nil { return "", err } + if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour - domain = "lan" + domain = "local" } return fmt.Sprintf("%s.%s", hostname, domain), nil } -func domain() (string, error) { +func domainname() (string, error) { const buffSize = 64 buff := make([]byte, buffSize) size := buffSize From 1d7b6b3ac166fe62e0ddf1a9b9c1bcbb069d0354 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Thu, 26 Jan 2023 11:30:36 +0100 Subject: [PATCH 24/65] avoid shadowing --- providers/linux/host_fqdn_cgo_linux.go | 4 ++-- providers/linux/host_fqdn_nocgo_linux.go | 2 +- providers/linux/host_linux.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/providers/linux/host_fqdn_cgo_linux.go b/providers/linux/host_fqdn_cgo_linux.go index 5b63d71a..0050da80 100644 --- a/providers/linux/host_fqdn_cgo_linux.go +++ b/providers/linux/host_fqdn_cgo_linux.go @@ -34,7 +34,7 @@ func fqdn() (string, error) { return "", err } - domain, err := domain() + domain, err := domainname() if err != nil { return "", err } @@ -46,7 +46,7 @@ func fqdn() (string, error) { return fmt.Sprintf("%s.%s", hostname, domain), nil } -func domain() (string, error) { +func domainname() (string, error) { const buffSize = 64 buff := make([]byte, buffSize) size := C.size_t(buffSize) diff --git a/providers/linux/host_fqdn_nocgo_linux.go b/providers/linux/host_fqdn_nocgo_linux.go index 19f36293..832463df 100644 --- a/providers/linux/host_fqdn_nocgo_linux.go +++ b/providers/linux/host_fqdn_nocgo_linux.go @@ -23,6 +23,6 @@ func fqdn() (string, error) { return "", nil } -func domain() (string, error) { +func domainname() (string, error) { return "", nil } diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index a5412a62..ba298422 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -214,7 +214,7 @@ func (r *reader) hostname(h *host) { } func (r *reader) domain(h *host) { - v, err := domain() + v, err := domainname() if r.addErr(err) { return } From d28c9dfb948d1d94a329527f07e10bd3e9181cd3 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Thu, 26 Jan 2023 12:15:16 +0100 Subject: [PATCH 25/65] fix darwin no Cgo --- providers/darwin/host_fqdn_nocgo_darwin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/darwin/host_fqdn_nocgo_darwin.go b/providers/darwin/host_fqdn_nocgo_darwin.go index fd1503fd..96ad7a88 100644 --- a/providers/darwin/host_fqdn_nocgo_darwin.go +++ b/providers/darwin/host_fqdn_nocgo_darwin.go @@ -23,6 +23,6 @@ func fqdn() (string, error) { return "", nil } -func domain() (string, error) { +func domainname() (string, error) { return "", nil } From edf1a6fa660ad426f0d4828b5b700fc5e2c26f5c Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Fri, 27 Jan 2023 10:59:20 +0100 Subject: [PATCH 26/65] remove integration tests --- .ci/scripts/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/scripts/test.sh b/.ci/scripts/test.sh index 18a3f3b9..e0d5d6b0 100755 --- a/.ci/scripts/test.sh +++ b/.ci/scripts/test.sh @@ -37,7 +37,7 @@ fi set +e export OUT_FILE="build/test-report.out" mkdir -p build -go test -tags integration "./..." -v 2>&1 | tee ${OUT_FILE} +go test "./..." -v 2>&1 | tee ${OUT_FILE} status=$? go install github.com/jstemmer/go-junit-report/v2@latest go-junit-report > "build/junit-${GO_VERSION}.xml" < ${OUT_FILE} From 00761d95a76b789def8cc11529d01aebbbafda28 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Fri, 27 Jan 2023 11:38:04 +0100 Subject: [PATCH 27/65] enable integration tests --- .ci/scripts/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/scripts/test.sh b/.ci/scripts/test.sh index e0d5d6b0..18a3f3b9 100755 --- a/.ci/scripts/test.sh +++ b/.ci/scripts/test.sh @@ -37,7 +37,7 @@ fi set +e export OUT_FILE="build/test-report.out" mkdir -p build -go test "./..." -v 2>&1 | tee ${OUT_FILE} +go test -tags integration "./..." -v 2>&1 | tee ${OUT_FILE} status=$? go install github.com/jstemmer/go-junit-report/v2@latest go-junit-report > "build/junit-${GO_VERSION}.xml" < ${OUT_FILE} From 10bca7203e03d003760cbe2e8310a039251178c6 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Fri, 27 Jan 2023 12:13:20 +0100 Subject: [PATCH 28/65] testing things --- .ci/Jenkinsfile | 2 +- .ci/scripts/test.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index 8a6084a9..10cd9bc5 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -8,7 +8,7 @@ pipeline { REPO = "go-sysinfo" BASE_DIR = "src/github.com/elastic/${env.REPO}" JOB_GIT_CREDENTIALS = "f6c7695a-671e-4f4f-a331-acdce44ff9ba" - PIPELINE_LOG_LEVEL = 'INFO' + PIPELINE_LOG_LEVEL = 'DEBUG' } options { timeout(time: 1, unit: 'HOURS') diff --git a/.ci/scripts/test.sh b/.ci/scripts/test.sh index 18a3f3b9..cad41d22 100755 --- a/.ci/scripts/test.sh +++ b/.ci/scripts/test.sh @@ -37,7 +37,7 @@ fi set +e export OUT_FILE="build/test-report.out" mkdir -p build -go test -tags integration "./..." -v 2>&1 | tee ${OUT_FILE} +go test -tags integration -run TestHost_FQDN$ "./..." -v 2>&1 | tee ${OUT_FILE} status=$? go install github.com/jstemmer/go-junit-report/v2@latest go-junit-report > "build/junit-${GO_VERSION}.xml" < ${OUT_FILE} From a58e096f03d1c56c3cefa0250013af69d36f2be6 Mon Sep 17 00:00:00 2001 From: Victor Martinez Date: Fri, 27 Jan 2023 12:53:05 +0100 Subject: [PATCH 29/65] change permissions --- .ci/scripts/test.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .ci/scripts/test.sh diff --git a/.ci/scripts/test.sh b/.ci/scripts/test.sh old mode 100644 new mode 100755 From f9900cbbff01a60f038c6ec61c4a0ab5ce02c076 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Fri, 27 Jan 2023 13:34:36 +0100 Subject: [PATCH 30/65] run all tests and add TODO --- .ci/scripts/test.sh | 2 +- providers/linux/host_fqdn_integration_linux_test.go | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.ci/scripts/test.sh b/.ci/scripts/test.sh index 3125ed8c..1fd009fd 100755 --- a/.ci/scripts/test.sh +++ b/.ci/scripts/test.sh @@ -37,4 +37,4 @@ fi # Run the tests export OUT_FILE="build/test-report.out" mkdir -p build -gotestsum --format testname --junitfile "build/junit-${GO_VERSION}.xml" -- -tags integration -run TestHost_FQDN$ ./... +gotestsum --format testname --junitfile "build/junit-${GO_VERSION}.xml" -- -tags integration ./... diff --git a/providers/linux/host_fqdn_integration_linux_test.go b/providers/linux/host_fqdn_integration_linux_test.go index 6fca8eea..cda7fbd0 100644 --- a/providers/linux/host_fqdn_integration_linux_test.go +++ b/providers/linux/host_fqdn_integration_linux_test.go @@ -36,6 +36,8 @@ const wantHostname = "debian" const wantDomainCgo = "cgo" func TestHost_FQDN(t *testing.T) { + // TODO: read GO_VERSION and set the image accordingly + const image = "golang:1.19-bullseye" tcs := []struct { name string cf container.Config @@ -48,7 +50,7 @@ func TestHost_FQDN(t *testing.T) { AttachStderr: testing.Verbose(), AttachStdout: testing.Verbose(), WorkingDir: "/usr/src/elastic/go-sysinfo", - Image: "golang:1.19-bullseye", + Image: image, Cmd: []string{ "go", "test", "-v", "-tags", "integration,docker", @@ -64,7 +66,7 @@ func TestHost_FQDN(t *testing.T) { AttachStderr: testing.Verbose(), AttachStdout: testing.Verbose(), WorkingDir: "/usr/src/elastic/go-sysinfo", - Image: "golang:1.19-bullseye", + Image: image, Cmd: []string{ "go", "test", "-v", "-count", "1", "-tags", "integration,docker", @@ -81,7 +83,7 @@ func TestHost_FQDN(t *testing.T) { AttachStdout: testing.Verbose(), Env: []string{"CGO_ENABLED=0"}, WorkingDir: "/usr/src/elastic/go-sysinfo", - Image: "golang:1.19-bullseye", + Image: image, Cmd: []string{ "go", "test", "-v", "-tags", "integration,docker", @@ -119,7 +121,7 @@ func runOnDocker(t *testing.T, cli *client.Client, cf *container.Config) { t.Fatalf("failed to pull image %s: %v", cf.Image, err) } defer reader.Close() - io.Copy(os.Stdout, reader) + io.Copy(os.Stderr, reader) resp, err := cli.ContainerCreate(ctx, cf, &container.HostConfig{ AutoRemove: false, From 3f79759c70d5680a26be890088667c9df8198025 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Mon, 30 Jan 2023 19:45:40 +0100 Subject: [PATCH 31/65] WIP --- providers/linux/host_fqdn_cgo_linux.go | 21 ++++++++++ providers/linux/host_linux.go | 56 ++++++++++++++++++++++++++ providers/linux/host_linux_test.go | 29 +++++++++++++ 3 files changed, 106 insertions(+) diff --git a/providers/linux/host_fqdn_cgo_linux.go b/providers/linux/host_fqdn_cgo_linux.go index 0050da80..5ae4a009 100644 --- a/providers/linux/host_fqdn_cgo_linux.go +++ b/providers/linux/host_fqdn_cgo_linux.go @@ -46,6 +46,27 @@ func fqdn() (string, error) { return fmt.Sprintf("%s.%s", hostname, domain), nil } +func hostname() (string, error) { + const buffSize = 64 + buff := make([]byte, buffSize) + size := C.size_t(buffSize) + cString := C.CString(string(buff)) + defer C.free(unsafe.Pointer(cString)) + + _, errno := C.gethostname(cString, size) + if errno != nil { + return "", fmt.Errorf("cgo call gethostname errored: %v", errno) + } + + var name string = C.GoString(cString) + + if name == "(none)" { + name = "" + } + + return name, nil +} + func domainname() (string, error) { const buffSize = 64 buff := make([]byte, buffSize) diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index ba298422..005f5c2a 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -23,6 +23,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "time" "github.com/joeshaw/multierror" @@ -277,3 +278,58 @@ func (fs *procFS) path(p ...string) string { elem := append([]string{fs.mountPoint}, p...) return filepath.Join(elem...) } + +// TODO: check k8s: https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/ + +// type struct []etchosts { +// ip, canonical string +// aliases []string +// } +// +// func findInHosts(hostname, line string) (string, bool) { +// +// } +func parseLine(name, line string) (string, bool) { + nline, after, _ := strings.Cut(line, "#") + if len(nline) < 1 { + fmt.Printf("skip comment or empty: %q\n", line) + return "", false + } + + if len(after) > 0 { + fmt.Printf("ignoring comment: %q\n", after) + fmt.Printf("\tfull line: %q\n", line) + + } + + fileds := strings.FieldsFunc(nline, func(r rune) bool { + return r == ' ' || r == '\t' + }) + + if len(fileds) < 2 { + fmt.Printf("invalid line: %q\n", line) + + return "", false + } + + // fields[0] is the ip address + cannonical, aliases := fileds[1], fileds[1:] + + // TODO: confirm: a name should not repeat on different addresses. + if len(fileds) == 2 { + if fileds[1] == name { + return name, true + } + if hname, _, _ := strings.Cut(cannonical, "."); hname == name { + return cannonical, true + } + } + + for _, h := range aliases { + if h == name { + return cannonical, true + } + } + + return "", false +} diff --git a/providers/linux/host_linux_test.go b/providers/linux/host_linux_test.go index 5abe0908..706b9d81 100644 --- a/providers/linux/host_linux_test.go +++ b/providers/linux/host_linux_test.go @@ -19,6 +19,7 @@ package linux import ( "encoding/json" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -109,3 +110,31 @@ func TestHostNetworkCounters(t *testing.T) { } t.Log(string(data)) } + +const etcHosts = ` +# The following lines are desirable for IPv4 capable hosts +127.0.0.1 localhost + +# 127.0.1.1 is often used for the FQDN of the machine +127.0.1.1 thishost.mydomain.org thishost +192.168.1.10 foo.mydomain.org # foo +192.168.1.13 bar.mydomain.org bar # comment 1 +146.82.138.7 master.debian.org master # comment 2 +209.237.226.90 www.opensource.org +209.237.226.91INVALIDwww.opensource.org +213.456.178.9 ahost.no.alias + +# The following lines are desirable for IPv6 capable hosts +::1 localhost ip6-localhost ip6-loopback +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters +` + +func TestParseLine(t *testing.T) { + lines := strings.Split(etcHosts, "\n") + + for n, l := range lines { + fqdn, ok := parseLine("ahost", l) + t.Logf("[%d] fqdn: %s, ok: %t", n, fqdn, ok) + } +} From 30eb9e6d72cd3227ea540078a7aea1beee015896 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 31 Jan 2023 10:58:48 +0100 Subject: [PATCH 32/65] parse fqdn from hosts file --- providers/linux/host_linux.go | 90 ++++++++++++++++++++---------- providers/linux/host_linux_test.go | 80 ++++++++++++++++++-------- 2 files changed, 116 insertions(+), 54 deletions(-) diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index 005f5c2a..15d53188 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -18,8 +18,10 @@ package linux import ( + "bufio" "errors" "fmt" + "io/fs" "io/ioutil" "os" "path/filepath" @@ -222,13 +224,31 @@ func (r *reader) domain(h *host) { h.info.Domain = v } +const etcHosts = "/etc/hosts" + func (r *reader) fqdn(h *host) { - fqdn, err := fqdn() + f, err := os.Open(etcHosts) + if err != nil { + r.addErr(fmt.Errorf("could open %q to get FQDN: %w", etcHosts, err)) + return + } + + hname, err := os.Hostname() if err != nil { - r.addErr(fmt.Errorf("could not get linux FQDN: %w", err)) + r.addErr(fmt.Errorf("could get hostname to look for FQDN: %w", err)) return } + fqdn, err := fqdnFromHosts(hname, f) + if err != nil { + r.addErr(fmt.Errorf("error when looking for FQDN on %s: %w", etcHosts, err)) + return + } + + if fqdn == "" { + // FQDN not found on hosts file, fall back to net.Lookup? + // add an error? + } h.info.FQDN = fqdn } @@ -279,37 +299,43 @@ func (fs *procFS) path(p ...string) string { return filepath.Join(elem...) } -// TODO: check k8s: https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/ +// fqdnFromHosts looks for the FQDN for hostname on hostFile. +// If successfully it returns FQDN, nil. If no FQDN for hostname is found +// it returns "", nil. It returns "", err if any error happens. +func fqdnFromHosts(hostname string, hostsFile fs.File) (string, error) { + s := bufio.NewScanner(hostsFile) -// type struct []etchosts { -// ip, canonical string -// aliases []string -// } -// -// func findInHosts(hostname, line string) (string, bool) { -// -// } -func parseLine(name, line string) (string, bool) { - nline, after, _ := strings.Cut(line, "#") - if len(nline) < 1 { - fmt.Printf("skip comment or empty: %q\n", line) - return "", false + for s.Scan() { + fqdn := findInHostsLine(hostname, s.Text()) + if fqdn != "" { + return fqdn, nil + } + } + if err := s.Err(); err != nil { + return "", fmt.Errorf("error reading hosts file lines: %w", err) } - if len(after) > 0 { - fmt.Printf("ignoring comment: %q\n", after) - fmt.Printf("\tfull line: %q\n", line) + return "", nil +} +// findInHostsLine takes a HOSTS(5) line and searches for an alias matching +// hostname, if found it returns the canonical_hostname. The canonical_hostname +// should be the FQDN, see HOSTNAME(1). +// TODO: check k8s: https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/ +func findInHostsLine(hostname, hostsEntry string) string { + line, _, _ := strings.Cut(hostsEntry, "#") + if len(line) < 1 { + fmt.Printf("skip comment or empty: %q\n", hostsEntry) + return "" } - fileds := strings.FieldsFunc(nline, func(r rune) bool { + fileds := strings.FieldsFunc(line, func(r rune) bool { return r == ' ' || r == '\t' }) if len(fileds) < 2 { - fmt.Printf("invalid line: %q\n", line) - - return "", false + // invalid hostsEntry + return "" } // fields[0] is the ip address @@ -317,19 +343,23 @@ func parseLine(name, line string) (string, bool) { // TODO: confirm: a name should not repeat on different addresses. if len(fileds) == 2 { - if fileds[1] == name { - return name, true + if fileds[1] == hostname { + return cannonical } - if hname, _, _ := strings.Cut(cannonical, "."); hname == name { - return cannonical, true + + // If hostname was not set as an alias for FQDN, but the fist name + // before the dot is the hostname: + // 192.168.1.10 foo.mydomain.org # foo + if hname, _, _ := strings.Cut(cannonical, "."); hname == hostname { + return cannonical } } for _, h := range aliases { - if h == name { - return cannonical, true + if h == hostname { + return cannonical } } - return "", false + return "" } diff --git a/providers/linux/host_linux_test.go b/providers/linux/host_linux_test.go index 706b9d81..d8d9fbf8 100644 --- a/providers/linux/host_linux_test.go +++ b/providers/linux/host_linux_test.go @@ -19,7 +19,6 @@ package linux import ( "encoding/json" - "strings" "testing" "github.com/stretchr/testify/assert" @@ -111,30 +110,63 @@ func TestHostNetworkCounters(t *testing.T) { t.Log(string(data)) } -const etcHosts = ` -# The following lines are desirable for IPv4 capable hosts -127.0.0.1 localhost - -# 127.0.1.1 is often used for the FQDN of the machine -127.0.1.1 thishost.mydomain.org thishost -192.168.1.10 foo.mydomain.org # foo -192.168.1.13 bar.mydomain.org bar # comment 1 -146.82.138.7 master.debian.org master # comment 2 -209.237.226.90 www.opensource.org -209.237.226.91INVALIDwww.opensource.org -213.456.178.9 ahost.no.alias - -# The following lines are desirable for IPv6 capable hosts -::1 localhost ip6-localhost ip6-loopback -ff02::1 ip6-allnodes -ff02::2 ip6-allrouters -` - func TestParseLine(t *testing.T) { - lines := strings.Split(etcHosts, "\n") + tcs := []struct { + name string + hostname string + line string + want string + }{ + { + name: "find fqdn - spaces", + hostname: "thishost", + want: "thishost.mydomain.org", + line: "127.0.1.1 thishost.mydomain.org thishost", + }, + { + name: "find fqdn - tabs", + hostname: "thishost", + want: "thishost.mydomain.org", + line: "127.0.1.1 thishost.mydomain.org thishost", + }, + { + name: "find fqdn - tabs and spaces", + hostname: "thishost", + want: "thishost.mydomain.org", + line: "127.0.1.1 thishost.mydomain.org thishost", + }, + { + name: "find fqdn - line with comment", + hostname: "bar", + want: "bar.mydomain.org", + line: "192.168.1.13 bar.mydomain.org bar # comment 1", + }, + { + name: "find fqdn - fqdn with hostname but no alias", + hostname: "ahostWith", + want: "ahostWith.no.alias", + line: "213.456.178.9 ahostWith.no.alias", + }, + { + name: "ignore invalid line", + hostname: "ignore", + want: "", + line: "209.237.226.91INVALIDwww.opensource.org", + }, + { + name: "comment line", + hostname: "ignore", + want: "", + line: "# The following lines are desirable for IPv4 capable hosts", + }, + } - for n, l := range lines { - fqdn, ok := parseLine("ahost", l) - t.Logf("[%d] fqdn: %s, ok: %t", n, fqdn, ok) + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + got := findInHostsLine(tc.hostname, tc.line) + if got != tc.want { + t.Errorf("got %s, want %s", got, tc.want) + } + }) } } From 7b81bb8886fa74d0d167230fc45b167d88a3c6a7 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 31 Jan 2023 15:31:22 +0100 Subject: [PATCH 33/65] get fqdn from /etc/hosts for linux and darwin --- providers/darwin/host_darwin.go | 17 +-- providers/darwin/host_fqdn_cgo_darwin.go | 62 --------- providers/darwin/host_fqdn_nocgo_darwin.go | 28 ----- providers/linux/host_fqdn_cgo_linux.go | 89 ------------- ...host_fqdn_integration_docker_linux_test.go | 82 ++++++------ .../linux/host_fqdn_integration_linux_test.go | 37 +++--- providers/linux/host_fqdn_nocgo_linux.go | 28 ----- providers/linux/host_linux.go | 102 +-------------- providers/linux/host_linux_test.go | 61 --------- providers/shared/fqdn.go | 119 ++++++++++++++++++ providers/shared/fqdn_test.go | 81 ++++++++++++ providers/windows/host_windows.go | 18 --- types/host.go | 31 ++--- 13 files changed, 286 insertions(+), 469 deletions(-) delete mode 100644 providers/darwin/host_fqdn_cgo_darwin.go delete mode 100644 providers/darwin/host_fqdn_nocgo_darwin.go delete mode 100644 providers/linux/host_fqdn_cgo_linux.go delete mode 100644 providers/linux/host_fqdn_nocgo_linux.go create mode 100644 providers/shared/fqdn.go create mode 100644 providers/shared/fqdn_test.go diff --git a/providers/darwin/host_darwin.go b/providers/darwin/host_darwin.go index a559407e..5add2fd5 100644 --- a/providers/darwin/host_darwin.go +++ b/providers/darwin/host_darwin.go @@ -160,7 +160,6 @@ func newHost() (*host, error) { r.architecture(h) r.bootTime(h) r.hostname(h) - r.domain(h) r.fqdn(h) r.network(h) r.kernelVersion(h) @@ -215,24 +214,14 @@ func (r *reader) hostname(h *host) { h.info.Hostname = v } -func (r *reader) domain(h *host) { - v, err := domainname() - if r.addErr(err) { - return - } - h.info.Domain = v -} - func (r *reader) fqdn(h *host) { - fqdn, err := fqdn() - if err != nil { - r.addErr(fmt.Errorf("could not get darwin FQDN: %w", err)) + v, err := shared.FQDN() + if r.addErr(err) { return } - h.info.FQDN = fqdn + h.info.FQDN = v } - func (r *reader) network(h *host) { ips, macs, err := shared.Network() if r.addErr(err) { diff --git a/providers/darwin/host_fqdn_cgo_darwin.go b/providers/darwin/host_fqdn_cgo_darwin.go deleted file mode 100644 index 98e3deb7..00000000 --- a/providers/darwin/host_fqdn_cgo_darwin.go +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//go:build cgo - -package darwin - -// #include -// #include -import "C" -import ( - "fmt" - "os" - "unsafe" -) - -func fqdn() (string, error) { - hostname, err := os.Hostname() - if err != nil { - return "", err - } - - domain, err := domainname() - if err != nil { - return "", err - } - - if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour - domain = "local" - } - - return fmt.Sprintf("%s.%s", hostname, domain), nil -} - -func domainname() (string, error) { - const buffSize = 64 - buff := make([]byte, buffSize) - size := buffSize - cString := C.CString(string(buff)) - defer C.free(unsafe.Pointer(cString)) - - _, errno := C.getdomainname(cString, C.int(size)) - if errno != nil { - return "", fmt.Errorf("syscall getdomainname errored: %v", errno) - } - - return C.GoString(cString), nil -} diff --git a/providers/darwin/host_fqdn_nocgo_darwin.go b/providers/darwin/host_fqdn_nocgo_darwin.go deleted file mode 100644 index 96ad7a88..00000000 --- a/providers/darwin/host_fqdn_nocgo_darwin.go +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//go:build !cgo - -package darwin - -func fqdn() (string, error) { - return "", nil -} - -func domainname() (string, error) { - return "", nil -} diff --git a/providers/linux/host_fqdn_cgo_linux.go b/providers/linux/host_fqdn_cgo_linux.go deleted file mode 100644 index 5ae4a009..00000000 --- a/providers/linux/host_fqdn_cgo_linux.go +++ /dev/null @@ -1,89 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//go:build cgo - -package linux - -// #include -// #include -import "C" -import ( - "fmt" - "os" - "unsafe" -) - -func fqdn() (string, error) { - hostname, err := os.Hostname() - if err != nil { - return "", err - } - - domain, err := domainname() - if err != nil { - return "", err - } - - if domain == "" || domain == "(none)" { // mimicking 'hostname -f' behaviour - domain = "lan" - } - - return fmt.Sprintf("%s.%s", hostname, domain), nil -} - -func hostname() (string, error) { - const buffSize = 64 - buff := make([]byte, buffSize) - size := C.size_t(buffSize) - cString := C.CString(string(buff)) - defer C.free(unsafe.Pointer(cString)) - - _, errno := C.gethostname(cString, size) - if errno != nil { - return "", fmt.Errorf("cgo call gethostname errored: %v", errno) - } - - var name string = C.GoString(cString) - - if name == "(none)" { - name = "" - } - - return name, nil -} - -func domainname() (string, error) { - const buffSize = 64 - buff := make([]byte, buffSize) - size := C.size_t(buffSize) - cString := C.CString(string(buff)) - defer C.free(unsafe.Pointer(cString)) - - _, errno := C.getdomainname(cString, size) - if errno != nil { - return "", fmt.Errorf("syscall getdomainname errored: %v", errno) - } - - var domain string = C.GoString(cString) - - if domain == "(none)" { // mimicking 'hostname -f' behaviour - domain = "" - } - - return domain, nil -} diff --git a/providers/linux/host_fqdn_integration_docker_linux_test.go b/providers/linux/host_fqdn_integration_docker_linux_test.go index f9f7c70e..f31ec507 100644 --- a/providers/linux/host_fqdn_integration_docker_linux_test.go +++ b/providers/linux/host_fqdn_integration_docker_linux_test.go @@ -24,57 +24,69 @@ import ( "testing" ) -func TestHost_FQDN_Domain_Cgo(t *testing.T) { +func TestHost_FQDN_set(t *testing.T) { host, err := newLinuxSystem("").Host() if err != nil { t.Fatal(fmt.Errorf("could not het host information: %w", err)) } got := host.Info() - if got.Hostname != wantHostname { - t.Errorf("got wrong hostname want: %q, got %q", wantHostname, got.Hostname) - } - if got.Domain != wantDomainCgo { - t.Errorf("got wrong domain want: %q, got %q", wantDomainCgo, got.Domain) - } - if got.FQDN != fmt.Sprintf("%s.%s", wantHostname, wantDomainCgo) { - t.Errorf("FQDN shpould not be empty") + if got.FQDN != wantFQDN { + t.Errorf("got FQDN %q, want: %q", got.FQDN, wantFQDN) } } -func TestHost_FQDN_No_Domain_Cgo(t *testing.T) { +func TestHost_FQDN_not_set(t *testing.T) { host, err := newLinuxSystem("").Host() if err != nil { t.Fatal(fmt.Errorf("could not het host information: %w", err)) } got := host.Info() - if got.Hostname != wantHostname { - t.Errorf("got wrong hostname want: %s, got %s", wantHostname, got.Hostname) - } - if got.Domain != "" { - t.Errorf("got wrong domain should be empty but got %s", got.Domain) - } - wantFQDN := fmt.Sprintf("%s.%s", wantHostname, "lan") - if got.FQDN != wantFQDN { - t.Errorf("got wrong FQDN, want: %s, got %s", wantFQDN, got.FQDN) + if got.Hostname != got.FQDN { + t.Errorf("name and FQDN should be the same but hostname: %s, FQDN %s", got.Hostname, got.FQDN) } } -func TestHost_FQDN_Domain_NoCgo(t *testing.T) { - host, err := newLinuxSystem("").Host() - if err != nil { - t.Fatal(fmt.Errorf("could not het host information: %w", err)) - } +// ❯ docker run --hostname myhost.co --rm -v "$PWD":/usr/src/elastic/go-sysinfo -it -w /usr/src/elastic/go-sysinfo golang:1.19 /bin/bash +// root@myhost:/usr/src/elastic/go-sysinfo# hostname +// myhost.co +// root@myhost:/usr/src/elastic/go-sysinfo# hostname -s +// myhost +// root@myhost:/usr/src/elastic/go-sysinfo# hostname -f +// myhost.co +// root@myhost:/usr/src/elastic/go-sysinfo# hostname -d +// co +// root@myhost:/usr/src/elastic/go-sysinfo# cat /proc/sys/kernel/hostname +// myhost.co +// root@myhost:/usr/src/elastic/go-sysinfo# cat /proc/sys/kernel/domainname +// (none) +// root@myhost:/usr/src/elastic/go-sysinfo# cat /etc/hosts +// 127.0.0.1 localhost +// ::1 localhost ip6-localhost ip6-loopback +// fe00::0 ip6-localnet +// ff00::0 ip6-mcastprefix +// ff02::1 ip6-allnodes +// ff02::2 ip6-allrouters +// 172.17.0.2 myhost.co myhost +// root@myhost:/usr/src/elastic/go-sysinfo# - got := host.Info() - if got.Hostname != wantHostname { - t.Errorf("hostname want: %s, got %s", wantHostname, got.Hostname) - } - if got.Domain != "" { - t.Errorf("domain should be empty but got %s", got.Domain) - } - if got.FQDN != "" { - t.Errorf("FQDN should empty, got: %s", got.FQDN) - } -} +// ❯ docker run --hostname myhost --domainname co --rm -v "$PWD":/usr/src/elastic/go-sysinfo -it -w /usr/src/elastic/go-sysinfo golang:1.19 /bin/bash +// root@myhost:/usr/src/elastic/go-sysinfo# hostname +// myhost +// root@myhost:/usr/src/elastic/go-sysinfo# hostname -f +// myhost.co +// root@myhost:/usr/src/elastic/go-sysinfo# hostname -d +// co +// root@myhost:/usr/src/elastic/go-sysinfo# cat /proc/sys/kernel/hostname +// myhost +// root@myhost:/usr/src/elastic/go-sysinfo# cat /proc/sys/kernel/domainname +// co +// root@myhost:/usr/src/elastic/go-sysinfo# cat /etc/hosts +// 127.0.0.1 localhost +// ::1 localhost ip6-localhost ip6-loopback +// fe00::0 ip6-localnet +// ff00::0 ip6-mcastprefix +// ff02::1 ip6-allnodes +// ff02::2 ip6-allrouters +// 172.17.0.2 myhost.co myhost diff --git a/providers/linux/host_fqdn_integration_linux_test.go b/providers/linux/host_fqdn_integration_linux_test.go index cda7fbd0..84c96f6b 100644 --- a/providers/linux/host_fqdn_integration_linux_test.go +++ b/providers/linux/host_fqdn_integration_linux_test.go @@ -32,21 +32,28 @@ import ( "github.com/docker/docker/pkg/stdcopy" ) -const wantHostname = "debian" -const wantDomainCgo = "cgo" +const wantHostname = "hostname" +const wantDomain = "some.domain" +const wantFQDN = wantHostname + "." + wantDomain func TestHost_FQDN(t *testing.T) { - // TODO: read GO_VERSION and set the image accordingly - const image = "golang:1.19-bullseye" + const envKey = "GO_VERSION" + goversion, ok := os.LookupEnv(envKey) + if !ok { + t.Fatalf("environment variable %s not set, please set a Go version", + envKey) + } + image := "golang:" + goversion + tcs := []struct { name string cf container.Config }{ { - name: "debian Cgo with domain", + name: "TestHost_FQDN_set_hostname+domainname", cf: container.Config{ Hostname: wantHostname, - Domainname: wantDomainCgo, + Domainname: wantDomain, AttachStderr: testing.Verbose(), AttachStdout: testing.Verbose(), WorkingDir: "/usr/src/elastic/go-sysinfo", @@ -54,40 +61,38 @@ func TestHost_FQDN(t *testing.T) { Cmd: []string{ "go", "test", "-v", "-tags", "integration,docker", - "-run", "^TestHost_FQDN_Domain_Cgo", + "-run", "^TestHost_FQDN_set$", "./providers/linux"}, Tty: false, }, }, { - name: "debian Cgo no domain", + name: "TestHost_FQDN_set_hostname_only", cf: container.Config{ - Hostname: wantHostname, + Hostname: wantFQDN, AttachStderr: testing.Verbose(), AttachStdout: testing.Verbose(), WorkingDir: "/usr/src/elastic/go-sysinfo", Image: image, Cmd: []string{ - "go", "test", "-v", "-count", "1", + "go", "test", "-v", "-tags", "integration,docker", - "-run", "^TestHost_FQDN_No_Domain_Cgo", + "-run", "^TestHost_FQDN_set$", "./providers/linux"}, Tty: false, }, }, { - name: "debian no Cgo", + name: "TestHost_FQDN_not_set", cf: container.Config{ - Hostname: wantHostname, AttachStderr: testing.Verbose(), AttachStdout: testing.Verbose(), - Env: []string{"CGO_ENABLED=0"}, WorkingDir: "/usr/src/elastic/go-sysinfo", Image: image, Cmd: []string{ - "go", "test", "-v", + "go", "test", "-v", "-count", "1", "-tags", "integration,docker", - "-run", "^TestHost_FQDN_Domain_NoCgo", + "-run", "^TestHost_FQDN_not_set$", "./providers/linux"}, Tty: false, }, diff --git a/providers/linux/host_fqdn_nocgo_linux.go b/providers/linux/host_fqdn_nocgo_linux.go deleted file mode 100644 index 832463df..00000000 --- a/providers/linux/host_fqdn_nocgo_linux.go +++ /dev/null @@ -1,28 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//go:build !cgo - -package linux - -func fqdn() (string, error) { - return "", nil -} - -func domainname() (string, error) { - return "", nil -} diff --git a/providers/linux/host_linux.go b/providers/linux/host_linux.go index 15d53188..73615593 100644 --- a/providers/linux/host_linux.go +++ b/providers/linux/host_linux.go @@ -18,14 +18,11 @@ package linux import ( - "bufio" "errors" "fmt" - "io/fs" "io/ioutil" "os" "path/filepath" - "strings" "time" "github.com/joeshaw/multierror" @@ -152,7 +149,6 @@ func newHost(fs procFS) (*host, error) { r.bootTime(h) r.containerized(h) r.hostname(h) - r.domain(h) r.fqdn(h) r.network(h) r.kernelVersion(h) @@ -216,40 +212,13 @@ func (r *reader) hostname(h *host) { h.info.Hostname = v } -func (r *reader) domain(h *host) { - v, err := domainname() - if r.addErr(err) { - return - } - h.info.Domain = v -} - -const etcHosts = "/etc/hosts" - func (r *reader) fqdn(h *host) { - f, err := os.Open(etcHosts) - if err != nil { - r.addErr(fmt.Errorf("could open %q to get FQDN: %w", etcHosts, err)) - return - } - - hname, err := os.Hostname() - if err != nil { - r.addErr(fmt.Errorf("could get hostname to look for FQDN: %w", err)) - return - } - - fqdn, err := fqdnFromHosts(hname, f) - if err != nil { - r.addErr(fmt.Errorf("error when looking for FQDN on %s: %w", etcHosts, err)) + v, err := shared.FQDN() + if r.addErr(err) { return } - if fqdn == "" { - // FQDN not found on hosts file, fall back to net.Lookup? - // add an error? - } - h.info.FQDN = fqdn + h.info.FQDN = v } func (r *reader) network(h *host) { @@ -298,68 +267,3 @@ func (fs *procFS) path(p ...string) string { elem := append([]string{fs.mountPoint}, p...) return filepath.Join(elem...) } - -// fqdnFromHosts looks for the FQDN for hostname on hostFile. -// If successfully it returns FQDN, nil. If no FQDN for hostname is found -// it returns "", nil. It returns "", err if any error happens. -func fqdnFromHosts(hostname string, hostsFile fs.File) (string, error) { - s := bufio.NewScanner(hostsFile) - - for s.Scan() { - fqdn := findInHostsLine(hostname, s.Text()) - if fqdn != "" { - return fqdn, nil - } - } - if err := s.Err(); err != nil { - return "", fmt.Errorf("error reading hosts file lines: %w", err) - } - - return "", nil -} - -// findInHostsLine takes a HOSTS(5) line and searches for an alias matching -// hostname, if found it returns the canonical_hostname. The canonical_hostname -// should be the FQDN, see HOSTNAME(1). -// TODO: check k8s: https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/ -func findInHostsLine(hostname, hostsEntry string) string { - line, _, _ := strings.Cut(hostsEntry, "#") - if len(line) < 1 { - fmt.Printf("skip comment or empty: %q\n", hostsEntry) - return "" - } - - fileds := strings.FieldsFunc(line, func(r rune) bool { - return r == ' ' || r == '\t' - }) - - if len(fileds) < 2 { - // invalid hostsEntry - return "" - } - - // fields[0] is the ip address - cannonical, aliases := fileds[1], fileds[1:] - - // TODO: confirm: a name should not repeat on different addresses. - if len(fileds) == 2 { - if fileds[1] == hostname { - return cannonical - } - - // If hostname was not set as an alias for FQDN, but the fist name - // before the dot is the hostname: - // 192.168.1.10 foo.mydomain.org # foo - if hname, _, _ := strings.Cut(cannonical, "."); hname == hostname { - return cannonical - } - } - - for _, h := range aliases { - if h == hostname { - return cannonical - } - } - - return "" -} diff --git a/providers/linux/host_linux_test.go b/providers/linux/host_linux_test.go index d8d9fbf8..5abe0908 100644 --- a/providers/linux/host_linux_test.go +++ b/providers/linux/host_linux_test.go @@ -109,64 +109,3 @@ func TestHostNetworkCounters(t *testing.T) { } t.Log(string(data)) } - -func TestParseLine(t *testing.T) { - tcs := []struct { - name string - hostname string - line string - want string - }{ - { - name: "find fqdn - spaces", - hostname: "thishost", - want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", - }, - { - name: "find fqdn - tabs", - hostname: "thishost", - want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", - }, - { - name: "find fqdn - tabs and spaces", - hostname: "thishost", - want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", - }, - { - name: "find fqdn - line with comment", - hostname: "bar", - want: "bar.mydomain.org", - line: "192.168.1.13 bar.mydomain.org bar # comment 1", - }, - { - name: "find fqdn - fqdn with hostname but no alias", - hostname: "ahostWith", - want: "ahostWith.no.alias", - line: "213.456.178.9 ahostWith.no.alias", - }, - { - name: "ignore invalid line", - hostname: "ignore", - want: "", - line: "209.237.226.91INVALIDwww.opensource.org", - }, - { - name: "comment line", - hostname: "ignore", - want: "", - line: "# The following lines are desirable for IPv4 capable hosts", - }, - } - - for _, tc := range tcs { - t.Run(tc.name, func(t *testing.T) { - got := findInHostsLine(tc.hostname, tc.line) - if got != tc.want { - t.Errorf("got %s, want %s", got, tc.want) - } - }) - } -} diff --git a/providers/shared/fqdn.go b/providers/shared/fqdn.go new file mode 100644 index 00000000..740f5ee4 --- /dev/null +++ b/providers/shared/fqdn.go @@ -0,0 +1,119 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build linux || darwin + +package shared + +import ( + "bufio" + "fmt" + "io/fs" + "os" + "strings" +) + +const etcHosts = "/etc/hosts" + +func FQDN() (string, error) { + f, err := os.Open(etcHosts) + if err != nil { + return "", fmt.Errorf("could open %q to get FQDN: %w", etcHosts, err) + } + + hname, err := os.Hostname() + if err != nil { + return "", fmt.Errorf("could get hostname to look for FQDN: %w", err) + } + + fqdn, err := fqdnFromHosts(hname, f) + if err != nil { + return "", fmt.Errorf("error when looking for FQDN on %s: %w", etcHosts, err) + } + + if fqdn == "" { + // FQDN not found on hosts file, fall back to net.Lookup? + // add an error? + } + + return fqdn, nil +} + +// fqdnFromHosts looks for the FQDN for hostname on hostFile. +// If successfully it returns FQDN, nil. If no FQDN for hostname is found +// it returns "", nil. It returns "", err if any error happens. +func fqdnFromHosts(hostname string, hostsFile fs.File) (string, error) { + s := bufio.NewScanner(hostsFile) + + for s.Scan() { + fqdn := findInHostsLine(hostname, s.Text()) + if fqdn != "" { + return fqdn, nil + } + } + if err := s.Err(); err != nil { + return "", fmt.Errorf("error reading hosts file lines: %w", err) + } + + return "", nil +} + +// findInHostsLine takes a HOSTS(5) line and searches for an alias matching +// hostname, if found it returns the canonical_hostname. The canonical_hostname +// should be the FQDN, see HOSTNAME(1). +// TODO: check k8s: https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/ +func findInHostsLine(hostname, hostsEntry string) string { + line, _, _ := strings.Cut(hostsEntry, "#") + if len(line) < 1 { + fmt.Printf("skip comment or empty: %q\n", hostsEntry) + return "" + } + + fileds := strings.FieldsFunc(line, func(r rune) bool { + return r == ' ' || r == '\t' + }) + + if len(fileds) < 2 { + // invalid hostsEntry + return "" + } + + // fields[0] is the ip address + cannonical, aliases := fileds[1], fileds[1:] + + // TODO: confirm: a name should not repeat on different addresses. + if len(fileds) == 2 { + if fileds[1] == hostname { + return cannonical + } + + // If hostname was not set as an alias for FQDN, but the fist name + // before the dot is the hostname: + // 192.168.1.10 foo.mydomain.org # foo + if hname, _, _ := strings.Cut(cannonical, "."); hname == hostname { + return cannonical + } + } + + for _, h := range aliases { + if h == hostname { + return cannonical + } + } + + return "" +} diff --git a/providers/shared/fqdn_test.go b/providers/shared/fqdn_test.go new file mode 100644 index 00000000..9acd6754 --- /dev/null +++ b/providers/shared/fqdn_test.go @@ -0,0 +1,81 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package shared + +import "testing" + +func TestParseLine(t *testing.T) { + tcs := []struct { + name string + hostname string + line string + want string + }{ + { + name: "find fqdn - spaces", + hostname: "thishost", + want: "thishost.mydomain.org", + line: "127.0.1.1 thishost.mydomain.org thishost", + }, + { + name: "find fqdn - tabs", + hostname: "thishost", + want: "thishost.mydomain.org", + line: "127.0.1.1 thishost.mydomain.org thishost", + }, + { + name: "find fqdn - tabs and spaces", + hostname: "thishost", + want: "thishost.mydomain.org", + line: "127.0.1.1 thishost.mydomain.org thishost", + }, + { + name: "find fqdn - line with comment", + hostname: "bar", + want: "bar.mydomain.org", + line: "192.168.1.13 bar.mydomain.org bar # comment 1", + }, + { + name: "find fqdn - fqdn with hostname but no alias", + hostname: "ahostWith", + want: "ahostWith.no.alias", + line: "213.456.178.9 ahostWith.no.alias", + }, + { + name: "ignore invalid line", + hostname: "ignore", + want: "", + line: "209.237.226.91INVALIDwww.opensource.org", + }, + { + name: "comment line", + hostname: "ignore", + want: "", + line: "# The following lines are desirable for IPv4 capable hosts", + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + got := findInHostsLine(tc.hostname, tc.line) + if got != tc.want { + t.Errorf("got %s, want %s", got, tc.want) + } + }) + } +} diff --git a/providers/windows/host_windows.go b/providers/windows/host_windows.go index a4e4c03c..1a4d1f10 100644 --- a/providers/windows/host_windows.go +++ b/providers/windows/host_windows.go @@ -88,7 +88,6 @@ func newHost() (*host, error) { r.architecture(h) r.bootTime(h) r.hostname(h) - r.domain(h) r.fqdn(h) r.network(h) r.kernelVersion(h) @@ -143,14 +142,6 @@ func (r *reader) hostname(h *host) { h.info.Hostname = v } -func (r *reader) domain(h *host) { - v, err := domain() - if r.addErr(err) { - return - } - h.info.Domain = v -} - func (r *reader) fqdn(h *host) { fqdn, err := getComputerNameEx( stdwindows.ComputerNamePhysicalDnsFullyQualified) @@ -162,15 +153,6 @@ func (r *reader) fqdn(h *host) { h.info.FQDN = fqdn } -func domain() (string, error) { - dns, err := getComputerNameEx(stdwindows.ComputerNamePhysicalDnsDomain) - if err != nil { - return "", fmt.Errorf("could not get windows dns: %s", err) - } - - return dns, nil -} - func getComputerNameEx(name uint32) (string, error) { size := uint32(64) diff --git a/types/host.go b/types/host.go index 1a2fdfe3..ee8a07b5 100644 --- a/types/host.go +++ b/types/host.go @@ -63,25 +63,18 @@ type VMStat interface { // HostInfo contains basic host information. type HostInfo struct { - Architecture string `json:"architecture"` // Hardware architecture (e.g. x86_64, arm, ppc, mips). - BootTime time.Time `json:"boot_time"` // Host boot time. - Containerized *bool `json:"containerized,omitempty"` // Is the process containerized. - Hostname string `json:"name"` // Hostname - // Domain requires Cgo for linux and darwin, therefore it'll be empty if Cgo - // is disabled. - Domain string `json:"domain"` // Domain - // FQDN (Fully qualified domain name) depends on Domain and therefore on Cgo - // for linux and darwin. - // When Cgo is disabled, FQDN is empty. If Domain is empty, but Cgo is enabled, - // FQDN will be "hostname.lan". - FQDN string `json:"fqdn"` - IPs []string `json:"ip,omitempty"` // List of all IPs. - KernelVersion string `json:"kernel_version"` // Kernel version. - MACs []string `json:"mac"` // List of MAC addresses. - OS *OSInfo `json:"os"` // OS information. - Timezone string `json:"timezone"` // System timezone. - TimezoneOffsetSec int `json:"timezone_offset_sec"` // Timezone offset (seconds from UTC). - UniqueID string `json:"id,omitempty"` // Unique ID of the host (optional). + Architecture string `json:"architecture"` // Hardware architecture (e.g. x86_64, arm, ppc, mips). + BootTime time.Time `json:"boot_time"` // Host boot time. + Containerized *bool `json:"containerized,omitempty"` // Is the process containerized. + Hostname string `json:"name"` // Hostname + FQDN string `json:"fqdn"` + IPs []string `json:"ip,omitempty"` // List of all IPs. + KernelVersion string `json:"kernel_version"` // Kernel version. + MACs []string `json:"mac"` // List of MAC addresses. + OS *OSInfo `json:"os"` // OS information. + Timezone string `json:"timezone"` // System timezone. + TimezoneOffsetSec int `json:"timezone_offset_sec"` // Timezone offset (seconds from UTC). + UniqueID string `json:"id,omitempty"` // Unique ID of the host (optional). } // Uptime returns the system uptime From 5446c0c8452f650adfe12dde39bbfdff79fa5d53 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 31 Jan 2023 16:03:00 +0100 Subject: [PATCH 34/65] add fallback using net.Lookup --- providers/shared/fqdn.go | 54 ++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/providers/shared/fqdn.go b/providers/shared/fqdn.go index 740f5ee4..2c198bf9 100644 --- a/providers/shared/fqdn.go +++ b/providers/shared/fqdn.go @@ -23,6 +23,7 @@ import ( "bufio" "fmt" "io/fs" + "net" "os" "strings" ) @@ -30,27 +31,60 @@ import ( const etcHosts = "/etc/hosts" func FQDN() (string, error) { - f, err := os.Open(etcHosts) + hostname, err := os.Hostname() if err != nil { - return "", fmt.Errorf("could open %q to get FQDN: %w", etcHosts, err) + return "", fmt.Errorf("could get hostname to look for FQDN: %w", err) } - hname, err := os.Hostname() + var errs error + + fqdn, err := fqdnFromEtcHosts(hostname) if err != nil { - return "", fmt.Errorf("could get hostname to look for FQDN: %w", err) + errs = fmt.Errorf("could not get FQDN, all methods failed: %w", err) + } + if fqdn != "" { + return fqdn, nil } - fqdn, err := fqdnFromHosts(hname, f) + cname, err := net.LookupCNAME(hostname) if err != nil { - return "", fmt.Errorf("error when looking for FQDN on %s: %w", etcHosts, err) + errs = fmt.Errorf("%s: %w", errs, err) + } + if cname != "" { + return cname, nil + } + + ips, err := net.LookupIP(hostname) + if err != nil { + errs = fmt.Errorf("%s: %w", errs, err) + } + + for _, ip := range ips { + names, err := net.LookupAddr(ip.String()) + if err != nil || len(names) == 0 { + continue + } + return names[0], nil + } + + return "", errs +} + +func fqdnFromEtcHosts(hostname string) (string, error) { + f, err := os.Open(etcHosts) + if err != nil { + return "", fmt.Errorf("could open %q to get FQDN: %w", etcHosts, err) } - if fqdn == "" { - // FQDN not found on hosts file, fall back to net.Lookup? - // add an error? + fqdn, err := fqdnFromHosts(hostname, f) + if err != nil { + return "", fmt.Errorf("error when looking for FQDN on %s: %w", etcHosts, err) + } + if fqdn != "" { + return fqdn, nil } - return fqdn, nil + return "", fmt.Errorf("no entry for %q on %q", hostname, etcHosts) } // fqdnFromHosts looks for the FQDN for hostname on hostFile. From d5226bc6a8ed3aa7f65145d91df45f244568c096 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 31 Jan 2023 17:28:09 +0100 Subject: [PATCH 35/65] . --- providers/shared/fqdn_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/providers/shared/fqdn_test.go b/providers/shared/fqdn_test.go index 9acd6754..d6763f5d 100644 --- a/providers/shared/fqdn_test.go +++ b/providers/shared/fqdn_test.go @@ -17,7 +17,9 @@ package shared -import "testing" +import ( + "testing" +) func TestParseLine(t *testing.T) { tcs := []struct { From 24cb68fa5e6bb4bda969285a4d437a92f886bacf Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 31 Jan 2023 17:45:59 +0100 Subject: [PATCH 36/65] more logs --- .ci/scripts/check_format.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/scripts/check_format.go b/.ci/scripts/check_format.go index 5a234a10..c330109e 100644 --- a/.ci/scripts/check_format.go +++ b/.ci/scripts/check_format.go @@ -55,7 +55,7 @@ func main() { } if len(out) > 0 { fmt.Fprintln(os.Stderr, "Run goimports on the code.") - fmt.Printf(string(out)) + fmt.Fprintln(os.Stderr, string(out)) os.Exit(1) } } From 2a2e22227aa800a5aab7fe93af2a0b4b7864d8c3 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 31 Jan 2023 18:44:22 +0100 Subject: [PATCH 37/65] try to fix formating --- .ci/scripts/check_format.go | 2 +- providers/shared/fqdn_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.ci/scripts/check_format.go b/.ci/scripts/check_format.go index c330109e..31f43afe 100644 --- a/.ci/scripts/check_format.go +++ b/.ci/scripts/check_format.go @@ -48,7 +48,7 @@ func main() { } goimports := exec.Command(filepath.Join(build.Default.GOPATH, "bin", "goimports"), - append([]string{"-l", "-local", localPkgs}, paths...)...) + append([]string{"-d", "-l", "-local", localPkgs}, paths...)...) out, err = goimports.Output() if err != nil { log.Fatalf("failed to %v: %v", strings.Join(goimports.Args, " "), err) diff --git a/providers/shared/fqdn_test.go b/providers/shared/fqdn_test.go index d6763f5d..3ab7bbc1 100644 --- a/providers/shared/fqdn_test.go +++ b/providers/shared/fqdn_test.go @@ -38,13 +38,13 @@ func TestParseLine(t *testing.T) { name: "find fqdn - tabs", hostname: "thishost", want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", + line: "127.0.1.1 thishost.mydomain.org thishost", }, { name: "find fqdn - tabs and spaces", hostname: "thishost", want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", + line: "127.0.1.1 thishost.mydomain.org thishost", }, { name: "find fqdn - line with comment", From 9f411950951bee1cebd2bae14f540cb649d43a73 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 10:07:33 +0100 Subject: [PATCH 38/65] update go versions 1.18 and tests to 1.18 and 1.19 --- .ci/Jenkinsfile | 6 +++--- go.mod | 2 +- go.sum | 20 -------------------- 3 files changed, 4 insertions(+), 24 deletions(-) diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index 10cd9bc5..d415f89f 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -37,7 +37,7 @@ pipeline { axes { axis { name 'GO_VERSION' - values '1.17.11', '1.18.3' + values '1.18.10', '1.19.5' } axis { name 'PLATFORM' @@ -52,7 +52,7 @@ pipeline { exclude { axis { name 'GO_VERSION' - values '1.17.11' + values '1.18.10' } axis { name 'PLATFORM' @@ -62,7 +62,7 @@ pipeline { exclude { axis { name 'GO_VERSION' - values '1.18.3' + values '1.19.5' } axis { name 'PLATFORM' diff --git a/go.mod b/go.mod index 380be64d..fe11aba7 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/elastic/go-sysinfo -go 1.17 +go 1.18 require ( github.com/docker/docker v20.10.22+incompatible diff --git a/go.sum b/go.sum index e77d436a..7a2f58c2 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,6 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -20,7 +18,6 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= @@ -39,7 +36,6 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -47,21 +43,17 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= @@ -70,32 +62,20 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From 17c0e2de1531ca023be1d281b786774faa652f67 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 10:23:08 +0100 Subject: [PATCH 39/65] restore check_format and remove debug log --- .ci/scripts/check_format.go | 4 ++-- providers/shared/fqdn.go | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.ci/scripts/check_format.go b/.ci/scripts/check_format.go index 31f43afe..5a234a10 100644 --- a/.ci/scripts/check_format.go +++ b/.ci/scripts/check_format.go @@ -48,14 +48,14 @@ func main() { } goimports := exec.Command(filepath.Join(build.Default.GOPATH, "bin", "goimports"), - append([]string{"-d", "-l", "-local", localPkgs}, paths...)...) + append([]string{"-l", "-local", localPkgs}, paths...)...) out, err = goimports.Output() if err != nil { log.Fatalf("failed to %v: %v", strings.Join(goimports.Args, " "), err) } if len(out) > 0 { fmt.Fprintln(os.Stderr, "Run goimports on the code.") - fmt.Fprintln(os.Stderr, string(out)) + fmt.Printf(string(out)) os.Exit(1) } } diff --git a/providers/shared/fqdn.go b/providers/shared/fqdn.go index 2c198bf9..81031c78 100644 --- a/providers/shared/fqdn.go +++ b/providers/shared/fqdn.go @@ -113,7 +113,6 @@ func fqdnFromHosts(hostname string, hostsFile fs.File) (string, error) { func findInHostsLine(hostname, hostsEntry string) string { line, _, _ := strings.Cut(hostsEntry, "#") if len(line) < 1 { - fmt.Printf("skip comment or empty: %q\n", hostsEntry) return "" } From b062876436af4335d1f9066ae58d2d3fca73eb88 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 10:24:43 +0100 Subject: [PATCH 40/65] add build tag to test file --- providers/shared/fqdn_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/providers/shared/fqdn_test.go b/providers/shared/fqdn_test.go index 3ab7bbc1..c231f38a 100644 --- a/providers/shared/fqdn_test.go +++ b/providers/shared/fqdn_test.go @@ -15,6 +15,8 @@ // specific language governing permissions and limitations // under the License. +//go:build linux || darwin + package shared import ( @@ -38,13 +40,13 @@ func TestParseLine(t *testing.T) { name: "find fqdn - tabs", hostname: "thishost", want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", + line: "127.0.1.1 thishost.mydomain.org thishost", }, { name: "find fqdn - tabs and spaces", hostname: "thishost", want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", + line: "127.0.1.1 thishost.mydomain.org thishost", }, { name: "find fqdn - line with comment", From eca2e347a8707a381b3ccb9eace8b10495badc73 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 10:37:32 +0100 Subject: [PATCH 41/65] . --- .ci/scripts/check_format.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/scripts/check_format.go b/.ci/scripts/check_format.go index 5a234a10..cbca1b1a 100644 --- a/.ci/scripts/check_format.go +++ b/.ci/scripts/check_format.go @@ -48,7 +48,7 @@ func main() { } goimports := exec.Command(filepath.Join(build.Default.GOPATH, "bin", "goimports"), - append([]string{"-l", "-local", localPkgs}, paths...)...) + append([]string{"-d", "-l", "-local", localPkgs}, paths...)...) out, err = goimports.Output() if err != nil { log.Fatalf("failed to %v: %v", strings.Join(goimports.Args, " "), err) From 1061a2c94a4fe380eaba0f8b7e5f272b481920d7 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 10:38:49 +0100 Subject: [PATCH 42/65] goimports --- providers/shared/fqdn_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/providers/shared/fqdn_test.go b/providers/shared/fqdn_test.go index c231f38a..91435a32 100644 --- a/providers/shared/fqdn_test.go +++ b/providers/shared/fqdn_test.go @@ -40,13 +40,13 @@ func TestParseLine(t *testing.T) { name: "find fqdn - tabs", hostname: "thishost", want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", + line: "127.0.1.1 thishost.mydomain.org thishost", }, { name: "find fqdn - tabs and spaces", hostname: "thishost", want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", + line: "127.0.1.1 thishost.mydomain.org thishost", }, { name: "find fqdn - line with comment", From 52093388e52cb7ad9d813ec022c79a2d40f1060c Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 10:53:30 +0100 Subject: [PATCH 43/65] allow FQDN errors on test --- system_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system_test.go b/system_test.go index fa6b0ba7..a76c9f82 100644 --- a/system_test.go +++ b/system_test.go @@ -26,6 +26,7 @@ import ( "runtime" "sort" "strconv" + "strings" "syscall" "testing" "time" @@ -234,7 +235,7 @@ func TestHost(t *testing.T) { host, err := Host() if err == types.ErrNotImplemented { t.Skip("host provider not implemented on", runtime.GOOS) - } else if err != nil { + } else if err != nil || strings.Contains(err.Error(), "FQDN") { t.Fatal(err) } From bd62e403e0cb60d727bf43ebdb98cb8f645b9350 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 11:43:01 +0100 Subject: [PATCH 44/65] restore jenkins info level --- .ci/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index d415f89f..a05e7866 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -8,7 +8,7 @@ pipeline { REPO = "go-sysinfo" BASE_DIR = "src/github.com/elastic/${env.REPO}" JOB_GIT_CREDENTIALS = "f6c7695a-671e-4f4f-a331-acdce44ff9ba" - PIPELINE_LOG_LEVEL = 'DEBUG' + PIPELINE_LOG_LEVEL = 'INFO' } options { timeout(time: 1, unit: 'HOURS') From 4461fbce46465831d045c9ef7b5adf6a2d65733e Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 12:09:43 +0100 Subject: [PATCH 45/65] trigger build --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 409432cd..caf7edc4 100644 --- a/README.md +++ b/README.md @@ -79,3 +79,4 @@ This table lists the OS and architectures for which a "provider" is implemented. | windows/arm | | | * On darwin (macOS) host information like machineid and process information like memory, cpu, user and starttime require cgo. + From e3567d32f3dad2efcd2c337cc40d5d941f5f3879 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 12:10:02 +0100 Subject: [PATCH 46/65] undo - trigger build --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index caf7edc4..409432cd 100644 --- a/README.md +++ b/README.md @@ -79,4 +79,3 @@ This table lists the OS and architectures for which a "provider" is implemented. | windows/arm | | | * On darwin (macOS) host information like machineid and process information like memory, cpu, user and starttime require cgo. - From db6bdacf277f268743b00da112da5c359141f3e2 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 13:35:20 +0100 Subject: [PATCH 47/65] improve error message --- providers/shared/fqdn.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/providers/shared/fqdn.go b/providers/shared/fqdn.go index 81031c78..e3f83715 100644 --- a/providers/shared/fqdn.go +++ b/providers/shared/fqdn.go @@ -48,7 +48,7 @@ func FQDN() (string, error) { cname, err := net.LookupCNAME(hostname) if err != nil { - errs = fmt.Errorf("%s: %w", errs, err) + errs = fmt.Errorf("%s: failed looking up CNAME: %w", errs, err) } if cname != "" { return cname, nil @@ -56,7 +56,7 @@ func FQDN() (string, error) { ips, err := net.LookupIP(hostname) if err != nil { - errs = fmt.Errorf("%s: %w", errs, err) + errs = fmt.Errorf("%s: failed looking up IP: %w", errs, err) } for _, ip := range ips { From 02f9780c3f19e04b03c9bd2bd6e5551b6c43ed67 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 13:40:52 +0100 Subject: [PATCH 48/65] not fail on Hosts tests --- providers/darwin/host_darwin_test.go | 2 +- providers/linux/host_linux_test.go | 2 +- providers/windows/host_windows_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/providers/darwin/host_darwin_test.go b/providers/darwin/host_darwin_test.go index ec0450ae..c994d872 100644 --- a/providers/darwin/host_darwin_test.go +++ b/providers/darwin/host_darwin_test.go @@ -32,7 +32,7 @@ var _ registry.HostProvider = darwinSystem{} func TestHost(t *testing.T) { host, err := darwinSystem{}.Host() if err != nil { - t.Fatal(err) + t.Logf("could not get all host info: %v", err) } info := host.Info() diff --git a/providers/linux/host_linux_test.go b/providers/linux/host_linux_test.go index 5abe0908..9fd15807 100644 --- a/providers/linux/host_linux_test.go +++ b/providers/linux/host_linux_test.go @@ -32,7 +32,7 @@ var _ registry.HostProvider = linuxSystem{} func TestHost(t *testing.T) { host, err := newLinuxSystem("").Host() if err != nil { - t.Fatal(err) + t.Logf("could not get all host info: %v", err) } info := host.Info() data, _ := json.MarshalIndent(info, "", " ") diff --git a/providers/windows/host_windows_test.go b/providers/windows/host_windows_test.go index e649b020..34ab996d 100644 --- a/providers/windows/host_windows_test.go +++ b/providers/windows/host_windows_test.go @@ -29,7 +29,7 @@ var _ registry.HostProvider = windowsSystem{} func TestHost(t *testing.T) { host, err := windowsSystem{}.Host() if err != nil { - t.Fatal(err) + t.Logf("could not get all host info: %v", err) } info := host.Info() From 0df9a2864a3ad1fe83a8e6c557e117bf3f121aa6 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 14:52:13 +0100 Subject: [PATCH 49/65] . --- providers/darwin/host_darwin_test.go | 5 ++--- providers/linux/host_linux_test.go | 5 +++-- providers/windows/host_windows_test.go | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/providers/darwin/host_darwin_test.go b/providers/darwin/host_darwin_test.go index c994d872..477fd647 100644 --- a/providers/darwin/host_darwin_test.go +++ b/providers/darwin/host_darwin_test.go @@ -16,7 +16,6 @@ // under the License. //go:build amd64 || arm64 -// +build amd64 arm64 package darwin @@ -32,10 +31,10 @@ var _ registry.HostProvider = darwinSystem{} func TestHost(t *testing.T) { host, err := darwinSystem{}.Host() if err != nil { - t.Logf("could not get all host info: %v", err) + t.Logf("could not get all host info: %v\n", err) } info := host.Info() data, _ := json.MarshalIndent(info, "", " ") - t.Log(string(data)) + t.Logf(string(data)) } diff --git a/providers/linux/host_linux_test.go b/providers/linux/host_linux_test.go index 9fd15807..97d728d9 100644 --- a/providers/linux/host_linux_test.go +++ b/providers/linux/host_linux_test.go @@ -32,11 +32,12 @@ var _ registry.HostProvider = linuxSystem{} func TestHost(t *testing.T) { host, err := newLinuxSystem("").Host() if err != nil { - t.Logf("could not get all host info: %v", err) + t.Logf("could not get all host info: %v\n", err) } + info := host.Info() data, _ := json.MarshalIndent(info, "", " ") - t.Log(string(data)) + t.Logf(string(data)) } func TestHostMemoryInfo(t *testing.T) { diff --git a/providers/windows/host_windows_test.go b/providers/windows/host_windows_test.go index 34ab996d..9592d575 100644 --- a/providers/windows/host_windows_test.go +++ b/providers/windows/host_windows_test.go @@ -29,7 +29,7 @@ var _ registry.HostProvider = windowsSystem{} func TestHost(t *testing.T) { host, err := windowsSystem{}.Host() if err != nil { - t.Logf("could not get all host info: %v", err) + t.Logf("could not get all host info: %v\n", err) } info := host.Info() From 2d1b47acfd88d336846f9c98521ced17fb69f612 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 14:53:41 +0100 Subject: [PATCH 50/65] . --- system_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system_test.go b/system_test.go index a76c9f82..b28d3151 100644 --- a/system_test.go +++ b/system_test.go @@ -235,7 +235,7 @@ func TestHost(t *testing.T) { host, err := Host() if err == types.ErrNotImplemented { t.Skip("host provider not implemented on", runtime.GOOS) - } else if err != nil || strings.Contains(err.Error(), "FQDN") { + } else if err != nil && !strings.Contains(err.Error(), "FQDN") { t.Fatal(err) } From 6fc8457fd0d4c5fbad3e385de5139c59999f5f45 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 15:04:02 +0100 Subject: [PATCH 51/65] . --- providers/shared/fqdn_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/providers/shared/fqdn_test.go b/providers/shared/fqdn_test.go index 91435a32..c231f38a 100644 --- a/providers/shared/fqdn_test.go +++ b/providers/shared/fqdn_test.go @@ -40,13 +40,13 @@ func TestParseLine(t *testing.T) { name: "find fqdn - tabs", hostname: "thishost", want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", + line: "127.0.1.1 thishost.mydomain.org thishost", }, { name: "find fqdn - tabs and spaces", hostname: "thishost", want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", + line: "127.0.1.1 thishost.mydomain.org thishost", }, { name: "find fqdn - line with comment", From 69f45efda83f2d5b0991b8febd64ec25fe4daf44 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 15:20:16 +0100 Subject: [PATCH 52/65] . --- providers/shared/fqdn_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/providers/shared/fqdn_test.go b/providers/shared/fqdn_test.go index c231f38a..91435a32 100644 --- a/providers/shared/fqdn_test.go +++ b/providers/shared/fqdn_test.go @@ -40,13 +40,13 @@ func TestParseLine(t *testing.T) { name: "find fqdn - tabs", hostname: "thishost", want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", + line: "127.0.1.1 thishost.mydomain.org thishost", }, { name: "find fqdn - tabs and spaces", hostname: "thishost", want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", + line: "127.0.1.1 thishost.mydomain.org thishost", }, { name: "find fqdn - line with comment", From 64a11dff10152f1eb846d9082ef706e05158233a Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 15:56:54 +0100 Subject: [PATCH 53/65] quote tabs on tests --- providers/shared/fqdn_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/providers/shared/fqdn_test.go b/providers/shared/fqdn_test.go index 91435a32..adf40ffa 100644 --- a/providers/shared/fqdn_test.go +++ b/providers/shared/fqdn_test.go @@ -40,13 +40,13 @@ func TestParseLine(t *testing.T) { name: "find fqdn - tabs", hostname: "thishost", want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", + line: "127.0.1.1\tthishost.mydomain.org\tthishost", }, { name: "find fqdn - tabs and spaces", hostname: "thishost", want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", + line: "127.0.1.1\t thishost.mydomain.org\t thishost", }, { name: "find fqdn - line with comment", From d664ddb1e7416c08ce48c9ba3da00381e6e34fd3 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 16:24:12 +0100 Subject: [PATCH 54/65] remove debug --- .ci/scripts/check_format.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/scripts/check_format.go b/.ci/scripts/check_format.go index cbca1b1a..5a234a10 100644 --- a/.ci/scripts/check_format.go +++ b/.ci/scripts/check_format.go @@ -48,7 +48,7 @@ func main() { } goimports := exec.Command(filepath.Join(build.Default.GOPATH, "bin", "goimports"), - append([]string{"-d", "-l", "-local", localPkgs}, paths...)...) + append([]string{"-l", "-local", localPkgs}, paths...)...) out, err = goimports.Output() if err != nil { log.Fatalf("failed to %v: %v", strings.Join(goimports.Args, " "), err) From 4da8ad906ce98bcdb5fddd30cadbbb11390d2b8a Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 16:24:34 +0100 Subject: [PATCH 55/65] removing dot suffix --- providers/shared/fqdn.go | 4 ++-- providers/windows/host_windows.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/providers/shared/fqdn.go b/providers/shared/fqdn.go index e3f83715..653fe6f2 100644 --- a/providers/shared/fqdn.go +++ b/providers/shared/fqdn.go @@ -51,7 +51,7 @@ func FQDN() (string, error) { errs = fmt.Errorf("%s: failed looking up CNAME: %w", errs, err) } if cname != "" { - return cname, nil + return strings.TrimSuffix(cname, "."), nil } ips, err := net.LookupIP(hostname) @@ -64,7 +64,7 @@ func FQDN() (string, error) { if err != nil || len(names) == 0 { continue } - return names[0], nil + return strings.TrimSuffix(names[0], "."), nil } return "", errs diff --git a/providers/windows/host_windows.go b/providers/windows/host_windows.go index 1a4d1f10..30f0269c 100644 --- a/providers/windows/host_windows.go +++ b/providers/windows/host_windows.go @@ -150,7 +150,7 @@ func (r *reader) fqdn(h *host) { return } - h.info.FQDN = fqdn + h.info.FQDN = strings.TrimSuffix(fqdn, ".") } func getComputerNameEx(name uint32) (string, error) { From c8b0e3d2d2dd5068fe4efae2a191924e4943c382 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 1 Feb 2023 17:41:31 +0100 Subject: [PATCH 56/65] . --- providers/windows/host_windows.go | 1 + 1 file changed, 1 insertion(+) diff --git a/providers/windows/host_windows.go b/providers/windows/host_windows.go index 30f0269c..06710c93 100644 --- a/providers/windows/host_windows.go +++ b/providers/windows/host_windows.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "os" + "strings" "syscall" "time" From 85120c059269086012606cdfb427e8355ea69fba Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Thu, 2 Feb 2023 10:02:22 +0100 Subject: [PATCH 57/65] remove comments --- ...host_fqdn_integration_docker_linux_test.go | 43 ------------------- 1 file changed, 43 deletions(-) diff --git a/providers/linux/host_fqdn_integration_docker_linux_test.go b/providers/linux/host_fqdn_integration_docker_linux_test.go index f31ec507..65d4dd62 100644 --- a/providers/linux/host_fqdn_integration_docker_linux_test.go +++ b/providers/linux/host_fqdn_integration_docker_linux_test.go @@ -47,46 +47,3 @@ func TestHost_FQDN_not_set(t *testing.T) { t.Errorf("name and FQDN should be the same but hostname: %s, FQDN %s", got.Hostname, got.FQDN) } } - -// ❯ docker run --hostname myhost.co --rm -v "$PWD":/usr/src/elastic/go-sysinfo -it -w /usr/src/elastic/go-sysinfo golang:1.19 /bin/bash -// root@myhost:/usr/src/elastic/go-sysinfo# hostname -// myhost.co -// root@myhost:/usr/src/elastic/go-sysinfo# hostname -s -// myhost -// root@myhost:/usr/src/elastic/go-sysinfo# hostname -f -// myhost.co -// root@myhost:/usr/src/elastic/go-sysinfo# hostname -d -// co -// root@myhost:/usr/src/elastic/go-sysinfo# cat /proc/sys/kernel/hostname -// myhost.co -// root@myhost:/usr/src/elastic/go-sysinfo# cat /proc/sys/kernel/domainname -// (none) -// root@myhost:/usr/src/elastic/go-sysinfo# cat /etc/hosts -// 127.0.0.1 localhost -// ::1 localhost ip6-localhost ip6-loopback -// fe00::0 ip6-localnet -// ff00::0 ip6-mcastprefix -// ff02::1 ip6-allnodes -// ff02::2 ip6-allrouters -// 172.17.0.2 myhost.co myhost -// root@myhost:/usr/src/elastic/go-sysinfo# - -// ❯ docker run --hostname myhost --domainname co --rm -v "$PWD":/usr/src/elastic/go-sysinfo -it -w /usr/src/elastic/go-sysinfo golang:1.19 /bin/bash -// root@myhost:/usr/src/elastic/go-sysinfo# hostname -// myhost -// root@myhost:/usr/src/elastic/go-sysinfo# hostname -f -// myhost.co -// root@myhost:/usr/src/elastic/go-sysinfo# hostname -d -// co -// root@myhost:/usr/src/elastic/go-sysinfo# cat /proc/sys/kernel/hostname -// myhost -// root@myhost:/usr/src/elastic/go-sysinfo# cat /proc/sys/kernel/domainname -// co -// root@myhost:/usr/src/elastic/go-sysinfo# cat /etc/hosts -// 127.0.0.1 localhost -// ::1 localhost ip6-localhost ip6-loopback -// fe00::0 ip6-localnet -// ff00::0 ip6-mcastprefix -// ff02::1 ip6-allnodes -// ff02::2 ip6-allrouters -// 172.17.0.2 myhost.co myhost From c31ec2d90a6d144900646b97bfd70ceaa86517e9 Mon Sep 17 00:00:00 2001 From: Julien Lind Date: Tue, 7 Feb 2023 14:02:08 +0100 Subject: [PATCH 58/65] Update providers/shared/fqdn.go Co-authored-by: Lee E Hinman <57081003+leehinman@users.noreply.github.com> --- providers/shared/fqdn.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/shared/fqdn.go b/providers/shared/fqdn.go index 653fe6f2..b3b45d89 100644 --- a/providers/shared/fqdn.go +++ b/providers/shared/fqdn.go @@ -33,7 +33,7 @@ const etcHosts = "/etc/hosts" func FQDN() (string, error) { hostname, err := os.Hostname() if err != nil { - return "", fmt.Errorf("could get hostname to look for FQDN: %w", err) + return "", fmt.Errorf("could not get hostname to look for FQDN: %w", err) } var errs error From 8b7b6743b6a6a8315271d392601f0c8f4f270d02 Mon Sep 17 00:00:00 2001 From: Julien Lind Date: Tue, 7 Feb 2023 14:02:19 +0100 Subject: [PATCH 59/65] Update providers/linux/host_fqdn_integration_docker_linux_test.go Co-authored-by: Lee E Hinman <57081003+leehinman@users.noreply.github.com> --- providers/linux/host_fqdn_integration_docker_linux_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/linux/host_fqdn_integration_docker_linux_test.go b/providers/linux/host_fqdn_integration_docker_linux_test.go index 65d4dd62..f89c75b1 100644 --- a/providers/linux/host_fqdn_integration_docker_linux_test.go +++ b/providers/linux/host_fqdn_integration_docker_linux_test.go @@ -39,7 +39,7 @@ func TestHost_FQDN_set(t *testing.T) { func TestHost_FQDN_not_set(t *testing.T) { host, err := newLinuxSystem("").Host() if err != nil { - t.Fatal(fmt.Errorf("could not het host information: %w", err)) + t.Fatal(fmt.Errorf("could not get host information: %w", err)) } got := host.Info() From 687a46812c292e050ed1968b250701d6a6c2ec81 Mon Sep 17 00:00:00 2001 From: Julien Lind Date: Tue, 7 Feb 2023 14:02:27 +0100 Subject: [PATCH 60/65] Update providers/linux/host_fqdn_integration_docker_linux_test.go Co-authored-by: Lee E Hinman <57081003+leehinman@users.noreply.github.com> --- providers/linux/host_fqdn_integration_docker_linux_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/linux/host_fqdn_integration_docker_linux_test.go b/providers/linux/host_fqdn_integration_docker_linux_test.go index f89c75b1..135f2d6b 100644 --- a/providers/linux/host_fqdn_integration_docker_linux_test.go +++ b/providers/linux/host_fqdn_integration_docker_linux_test.go @@ -27,7 +27,7 @@ import ( func TestHost_FQDN_set(t *testing.T) { host, err := newLinuxSystem("").Host() if err != nil { - t.Fatal(fmt.Errorf("could not het host information: %w", err)) + t.Fatal(fmt.Errorf("could not get host information: %w", err)) } got := host.Info() From 01676da37668663538302ab2be0554a7ade86760 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 14 Feb 2023 12:30:51 +0100 Subject: [PATCH 61/65] review changes --- providers/shared/fqdn.go | 35 ++++++++++++++++++------------- providers/windows/host_windows.go | 5 +---- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/providers/shared/fqdn.go b/providers/shared/fqdn.go index 653fe6f2..e6ab35da 100644 --- a/providers/shared/fqdn.go +++ b/providers/shared/fqdn.go @@ -75,6 +75,7 @@ func fqdnFromEtcHosts(hostname string) (string, error) { if err != nil { return "", fmt.Errorf("could open %q to get FQDN: %w", etcHosts, err) } + defer f.Close() fqdn, err := fqdnFromHosts(hostname, f) if err != nil { @@ -107,8 +108,10 @@ func fqdnFromHosts(hostname string, hostsFile fs.File) (string, error) { } // findInHostsLine takes a HOSTS(5) line and searches for an alias matching -// hostname, if found it returns the canonical_hostname. The canonical_hostname +// hostname, if found, it returns the canonical hostname. The canonical hostname // should be the FQDN, see HOSTNAME(1). +// It will return the first match and if an entry with only the hostname and no +// aliases is found, the hostname is returned. // TODO: check k8s: https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/ func findInHostsLine(hostname, hostsEntry string) string { line, _, _ := strings.Cut(hostsEntry, "#") @@ -116,35 +119,39 @@ func findInHostsLine(hostname, hostsEntry string) string { return "" } - fileds := strings.FieldsFunc(line, func(r rune) bool { + fields := strings.FieldsFunc(line, func(r rune) bool { return r == ' ' || r == '\t' }) - if len(fileds) < 2 { + if len(fields) < 2 { // invalid hostsEntry return "" } // fields[0] is the ip address - cannonical, aliases := fileds[1], fileds[1:] + canonical, aliases := fields[1], fields[1:] - // TODO: confirm: a name should not repeat on different addresses. - if len(fileds) == 2 { - if fileds[1] == hostname { - return cannonical + // The hostname is the canonical hostname and there is no alias, then return + // it. + if len(fields) == 2 { + if fields[1] == hostname { + return canonical } - // If hostname was not set as an alias for FQDN, but the fist name - // before the dot is the hostname: - // 192.168.1.10 foo.mydomain.org # foo - if hname, _, _ := strings.Cut(cannonical, "."); hname == hostname { - return cannonical + // If hostname was not set as an alias for the canonical hostname, + // but the fist name before the dot matches the hostname. + // If foo is the hostname we're looking for and the entry is as follows + // 192.168.1.10 foo.mydomain.org + // foo.mydomain.org will be returned. + if hname, _, _ := strings.Cut(canonical, "."); hname == hostname { + return canonical } } + // Default case for _, h := range aliases { if h == hostname { - return cannonical + return canonical } } diff --git a/providers/windows/host_windows.go b/providers/windows/host_windows.go index 06710c93..ac484a47 100644 --- a/providers/windows/host_windows.go +++ b/providers/windows/host_windows.go @@ -28,8 +28,6 @@ import ( "github.com/joeshaw/multierror" stdwindows "golang.org/x/sys/windows" - "github.com/elastic/go-windows" - "github.com/elastic/go-sysinfo/internal/registry" "github.com/elastic/go-sysinfo/providers/shared" "github.com/elastic/go-sysinfo/types" @@ -169,14 +167,13 @@ func getComputerNameEx(name uint32) (string, error) { // number of bytes needed to store the FQDN. For details, see // https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getcomputernameexw#return-value if errors.Is(err, syscall.ERROR_MORE_DATA) { + // Safeguard to avoid an infinite loop. if size <= uint32(len(buff)) { - // Safeguard to avoid an infinite loop. return "", fmt.Errorf( "windows.GetComputerNameEx returned ERROR_MORE_DATA, " + "but data size should fit into buffer") } else { // Grow the buffer and try again. - // Should we limit its growth? buff = make([]uint16, size) continue } From 88dc9f8ca9eae3b15b1739be8183c78fe09c0442 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Tue, 14 Feb 2023 15:50:32 +0100 Subject: [PATCH 62/65] add missing import --- providers/windows/host_windows.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/providers/windows/host_windows.go b/providers/windows/host_windows.go index ac484a47..015f37eb 100644 --- a/providers/windows/host_windows.go +++ b/providers/windows/host_windows.go @@ -26,8 +26,11 @@ import ( "time" "github.com/joeshaw/multierror" + stdwindows "golang.org/x/sys/windows" + windows "github.com/elastic/go-windows" + "github.com/elastic/go-sysinfo/internal/registry" "github.com/elastic/go-sysinfo/providers/shared" "github.com/elastic/go-sysinfo/types" From f8d318e055dcf372ece90cb113172ed9f00a0c40 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 15 Feb 2023 10:47:20 +0100 Subject: [PATCH 63/65] don't parse /etc/hosts to get FQDN on linux and darwin --- providers/shared/fqdn.go | 104 +-------------------------------------- 1 file changed, 2 insertions(+), 102 deletions(-) diff --git a/providers/shared/fqdn.go b/providers/shared/fqdn.go index 57102f0f..387fda70 100644 --- a/providers/shared/fqdn.go +++ b/providers/shared/fqdn.go @@ -20,16 +20,12 @@ package shared import ( - "bufio" "fmt" - "io/fs" "net" "os" "strings" ) -const etcHosts = "/etc/hosts" - func FQDN() (string, error) { hostname, err := os.Hostname() if err != nil { @@ -37,18 +33,10 @@ func FQDN() (string, error) { } var errs error - - fqdn, err := fqdnFromEtcHosts(hostname) - if err != nil { - errs = fmt.Errorf("could not get FQDN, all methods failed: %w", err) - } - if fqdn != "" { - return fqdn, nil - } - cname, err := net.LookupCNAME(hostname) if err != nil { - errs = fmt.Errorf("%s: failed looking up CNAME: %w", errs, err) + errs = fmt.Errorf("could not get FQDN, all methods failed: failed looking up CNAME: %w", + err) } if cname != "" { return strings.TrimSuffix(cname, "."), nil @@ -69,91 +57,3 @@ func FQDN() (string, error) { return "", errs } - -func fqdnFromEtcHosts(hostname string) (string, error) { - f, err := os.Open(etcHosts) - if err != nil { - return "", fmt.Errorf("could open %q to get FQDN: %w", etcHosts, err) - } - defer f.Close() - - fqdn, err := fqdnFromHosts(hostname, f) - if err != nil { - return "", fmt.Errorf("error when looking for FQDN on %s: %w", etcHosts, err) - } - if fqdn != "" { - return fqdn, nil - } - - return "", fmt.Errorf("no entry for %q on %q", hostname, etcHosts) -} - -// fqdnFromHosts looks for the FQDN for hostname on hostFile. -// If successfully it returns FQDN, nil. If no FQDN for hostname is found -// it returns "", nil. It returns "", err if any error happens. -func fqdnFromHosts(hostname string, hostsFile fs.File) (string, error) { - s := bufio.NewScanner(hostsFile) - - for s.Scan() { - fqdn := findInHostsLine(hostname, s.Text()) - if fqdn != "" { - return fqdn, nil - } - } - if err := s.Err(); err != nil { - return "", fmt.Errorf("error reading hosts file lines: %w", err) - } - - return "", nil -} - -// findInHostsLine takes a HOSTS(5) line and searches for an alias matching -// hostname, if found, it returns the canonical hostname. The canonical hostname -// should be the FQDN, see HOSTNAME(1). -// It will return the first match and if an entry with only the hostname and no -// aliases is found, the hostname is returned. -// TODO: check k8s: https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/ -func findInHostsLine(hostname, hostsEntry string) string { - line, _, _ := strings.Cut(hostsEntry, "#") - if len(line) < 1 { - return "" - } - - fields := strings.FieldsFunc(line, func(r rune) bool { - return r == ' ' || r == '\t' - }) - - if len(fields) < 2 { - // invalid hostsEntry - return "" - } - - // fields[0] is the ip address - canonical, aliases := fields[1], fields[1:] - - // The hostname is the canonical hostname and there is no alias, then return - // it. - if len(fields) == 2 { - if fields[1] == hostname { - return canonical - } - - // If hostname was not set as an alias for the canonical hostname, - // but the fist name before the dot matches the hostname. - // If foo is the hostname we're looking for and the entry is as follows - // 192.168.1.10 foo.mydomain.org - // foo.mydomain.org will be returned. - if hname, _, _ := strings.Cut(canonical, "."); hname == hostname { - return canonical - } - } - - // Default case - for _, h := range aliases { - if h == hostname { - return canonical - } - } - - return "" -} From 9c01d406e3473467953fd0347f3b094ff39ed7ee Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 15 Feb 2023 15:40:23 +0100 Subject: [PATCH 64/65] remove tests for removed things --- providers/shared/fqdn_test.go | 85 ----------------------------------- 1 file changed, 85 deletions(-) delete mode 100644 providers/shared/fqdn_test.go diff --git a/providers/shared/fqdn_test.go b/providers/shared/fqdn_test.go deleted file mode 100644 index adf40ffa..00000000 --- a/providers/shared/fqdn_test.go +++ /dev/null @@ -1,85 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -//go:build linux || darwin - -package shared - -import ( - "testing" -) - -func TestParseLine(t *testing.T) { - tcs := []struct { - name string - hostname string - line string - want string - }{ - { - name: "find fqdn - spaces", - hostname: "thishost", - want: "thishost.mydomain.org", - line: "127.0.1.1 thishost.mydomain.org thishost", - }, - { - name: "find fqdn - tabs", - hostname: "thishost", - want: "thishost.mydomain.org", - line: "127.0.1.1\tthishost.mydomain.org\tthishost", - }, - { - name: "find fqdn - tabs and spaces", - hostname: "thishost", - want: "thishost.mydomain.org", - line: "127.0.1.1\t thishost.mydomain.org\t thishost", - }, - { - name: "find fqdn - line with comment", - hostname: "bar", - want: "bar.mydomain.org", - line: "192.168.1.13 bar.mydomain.org bar # comment 1", - }, - { - name: "find fqdn - fqdn with hostname but no alias", - hostname: "ahostWith", - want: "ahostWith.no.alias", - line: "213.456.178.9 ahostWith.no.alias", - }, - { - name: "ignore invalid line", - hostname: "ignore", - want: "", - line: "209.237.226.91INVALIDwww.opensource.org", - }, - { - name: "comment line", - hostname: "ignore", - want: "", - line: "# The following lines are desirable for IPv4 capable hosts", - }, - } - - for _, tc := range tcs { - t.Run(tc.name, func(t *testing.T) { - got := findInHostsLine(tc.hostname, tc.line) - if got != tc.want { - t.Errorf("got %s, want %s", got, tc.want) - } - }) - } -} From d88406aae9173bd7abdfaa47450ffd541a838650 Mon Sep 17 00:00:00 2001 From: Anderson Queiroz Date: Wed, 15 Feb 2023 16:12:15 +0100 Subject: [PATCH 65/65] add changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e771fb71..4f267712 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Add OS family mappings for `opensuse-leap` and `opensuse-tumbleweed`. [#146](https://github.com/elastic/go-sysinfo/pull/146) +- Add FQDN to host info. [#144](https://github.com/elastic/go-sysinfo/pull/144) ### Changed +- Requires Go 1.18+ [#144](https://github.com/elastic/go-sysinfo/pull/144) + ### Deprecated ### Removed