1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
// Copyright 2020 New Relic Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package sysinfo
import (
"os"
"syscall"
)
func getHostname() (string, error) {
// Try the builtin API first, which is designed to match the output of
// /bin/hostname, and fallback to uname(2) if that fails to match the
// behavior of gethostname(2) as implemented by glibc. On Linux, all
// these method should result in the same value because sethostname(2)
// limits the hostname to 64 bytes, the same size of the nodename field
// returned by uname(2). Note that is correspondence is not true on
// other platforms.
//
// os.Hostname failures should be exceedingly rare, however some systems
// configure SELinux to deny read access to /proc/sys/kernel/hostname.
// Redhat's OpenShift platform for example. os.Hostname can also fail if
// some or all of /proc has been hidden via chroot(2) or manipulation of
// the current processes' filesystem namespace via the cgroups APIs.
// Docker is an example of a tool that can configure such an
// environment.
name, err := os.Hostname()
if err == nil {
return name, nil
}
var uts syscall.Utsname
if err2 := syscall.Uname(&uts); err2 != nil {
// The man page documents only one possible error for uname(2),
// suggesting that as long as the buffer given is valid, the
// call will never fail. Return the original error in the hope
// it provides more relevant information about why the hostname
// can't be retrieved.
return "", err
}
// Convert Nodename to a Go string.
buf := make([]byte, 0, len(uts.Nodename))
for _, c := range uts.Nodename {
if c == 0 {
break
}
buf = append(buf, byte(c))
}
return string(buf), nil
}
|