From 3ad0365f186491093e261d43c745fb63cb94c22d Mon Sep 17 00:00:00 2001 From: Dan Fuhry Date: Thu, 12 Sep 2024 20:17:37 -0400 Subject: [PATCH] utils/hostname: handle special case of domain name = "(none)" on linux Linux systems can return interesting values when the domain name is unset, like "(none)" or an empty string. To handle these, hostname.go is forked with special Hostname(), DomainName() and RegionName() implementations for Linux and the original implementations for other OSes. --- utils/hostname/hostname.go | 77 ++++---------------------- utils/hostname/hostname_generic.go | 10 ++++ utils/hostname/hostname_linux.go | 86 ++++++++++++++++++++++++++++++ utils/hostname/hostname_macos.go | 20 ------- utils/hostname/hostname_openbsd.go | 19 ------- 5 files changed, 107 insertions(+), 105 deletions(-) create mode 100644 utils/hostname/hostname_generic.go create mode 100644 utils/hostname/hostname_linux.go diff --git a/utils/hostname/hostname.go b/utils/hostname/hostname.go index 65431fb..a46c31e 100644 --- a/utils/hostname/hostname.go +++ b/utils/hostname/hostname.go @@ -1,83 +1,28 @@ -//go:build !darwin && !openbsd +//go:build !linux package hostname import ( - "fmt" "strings" - "sync" - "syscall" -) -type i8 = interface { - int8 | uint8 -} + "go.fuhry.dev/runtime/constants" +) -var utsname syscall.Utsname -var utsnameOnce sync.Once +var defaultDomainName = constants.DefaultHostDomain func Hostname() string { - return strings.Split(nodeName(), ".")[0] + fqdn := Fqdn() + return strings.Split(fqdn, ".")[0] } func DomainName() string { - uname := uname() - - domainName := int8ToString(uname.Domainname) - if domainName != "(none)" { - return domainName - } - - nodeName := int8ToString(uname.Nodename) - for i, chr := range []byte(nodeName) { - if chr == '.' { - return nodeName[i+1:] - } + fqdn := strings.Split(Fqdn(), ".") + if len(fqdn) > 1 { + return strings.Join(fqdn[1:], ".") } - - err := fmt.Errorf("could not determine domain name from (uname.Nodename=%v) (uname.Domainname=%v)", uname.Nodename, uname.Domainname) - panic(err) + return defaultDomainName } func RegionName() string { - domain := DomainName() - - if domain == "" { - panic("domain string is empty") - } - - return strings.Split(domain, ".")[0] -} - -func Fqdn() string { - return strings.Join([]string{Hostname(), DomainName()}, ".") -} - -func uname() syscall.Utsname { - utsnameOnce.Do(func() { - err := syscall.Uname(&utsname) - if err != nil { - panic(err) - } - }) - - return utsname -} - -func nodeName() string { - uname := uname() - - return int8ToString(uname.Nodename) -} - -func int8ToString[T i8](ba [65]T) string { - bytes := make([]byte, 0) - for _, b := range ba { - if b == T(0) { - break - } - bytes = append(bytes, byte(b)) - } - - return string(bytes) + return strings.Split(DomainName(), ".")[0] } diff --git a/utils/hostname/hostname_generic.go b/utils/hostname/hostname_generic.go new file mode 100644 index 0000000..e7fc315 --- /dev/null +++ b/utils/hostname/hostname_generic.go @@ -0,0 +1,10 @@ +//go:build !linux && !openbsd && !darwin + +package hostname + +import "runtime" + +func Fqdn() string { + panic("fqdn is not implemented on your platform (" + runtime.GOOS + ")") + return "" +} diff --git a/utils/hostname/hostname_linux.go b/utils/hostname/hostname_linux.go new file mode 100644 index 0000000..19aaee3 --- /dev/null +++ b/utils/hostname/hostname_linux.go @@ -0,0 +1,86 @@ +//go:build linux + +package hostname + +import ( + "fmt" + "strings" + "sync" + "syscall" +) + +type i8 = interface { + int8 | uint8 +} + +var utsname syscall.Utsname +var utsnameOnce sync.Once + +func Hostname() string { + return strings.Split(nodeName(), ".")[0] +} + +func DomainName() string { + uname := uname() + + domainName := int8ToString(uname.Domainname) + if domainName != "(none)" { + return domainName + } + + nodeName := int8ToString(uname.Nodename) + for i, chr := range []byte(nodeName) { + if chr == '.' { + return nodeName[i+1:] + } + } + + err := fmt.Errorf( + "could not determine domain name from (uname.Nodename=%v) (uname.Domainname=%v)", + int8ToString(uname.Nodename), + int8ToString(uname.Domainname)) + panic(err) +} + +func RegionName() string { + domain := DomainName() + + if domain == "" { + panic("domain string is empty") + } + + return strings.Split(domain, ".")[0] +} + +func Fqdn() string { + return strings.Join([]string{Hostname(), DomainName()}, ".") +} + +func uname() syscall.Utsname { + utsnameOnce.Do(func() { + err := syscall.Uname(&utsname) + if err != nil { + panic(err) + } + }) + + return utsname +} + +func nodeName() string { + uname := uname() + + return int8ToString(uname.Nodename) +} + +func int8ToString[T i8](ba [65]T) string { + bytes := make([]byte, 0) + for _, b := range ba { + if b == T(0) { + break + } + bytes = append(bytes, byte(b)) + } + + return string(bytes) +} diff --git a/utils/hostname/hostname_macos.go b/utils/hostname/hostname_macos.go index 73337bd..c261853 100644 --- a/utils/hostname/hostname_macos.go +++ b/utils/hostname/hostname_macos.go @@ -11,13 +11,10 @@ import ( "strings" "time" - "go.fuhry.dev/runtime/constants" "go.fuhry.dev/runtime/utils/log" "howett.net/plist" ) -var defaultDomainName = constants.DefaultHostDomain - const ( systemPreferencesPlist = "/Library/Preferences/SystemConfiguration/preferences.plist" ) @@ -44,23 +41,6 @@ type systemPrefs_System_System struct { ComputerNameEncoding int `plist:"ComputerNameEncoding"` } -func Hostname() string { - fqdn := Fqdn() - return strings.Split(fqdn, ".")[0] -} - -func DomainName() string { - fqdn := strings.Split(Fqdn(), ".") - if len(fqdn) > 1 { - return strings.Join(fqdn[1:], ".") - } - return defaultDomainName -} - -func RegionName() string { - return strings.Split(DomainName(), ".")[0] -} - func Fqdn() string { dnsFqdn, dnsErr := fqdnFromDns() if dnsErr == nil { diff --git a/utils/hostname/hostname_openbsd.go b/utils/hostname/hostname_openbsd.go index caf8ebe..3247639 100644 --- a/utils/hostname/hostname_openbsd.go +++ b/utils/hostname/hostname_openbsd.go @@ -11,30 +11,11 @@ import ( "strings" "time" - "go.fuhry.dev/runtime/constants" "go.fuhry.dev/runtime/utils/log" ) -var defaultDomainName = constants.DefaultHostDomain var cachedFqdn string -func Hostname() string { - fqdn := Fqdn() - return strings.Split(fqdn, ".")[0] -} - -func DomainName() string { - fqdn := strings.Split(Fqdn(), ".") - if len(fqdn) > 1 { - return strings.Join(fqdn[1:], ".") - } - return defaultDomainName -} - -func RegionName() string { - return strings.Split(DomainName(), ".")[0] -} - func Fqdn() string { if cachedFqdn != "" { return cachedFqdn -- 2.50.1