From 34da256d037d5adb071d93633017e985181b107a Mon Sep 17 00:00:00 2001 From: Codescribe Date: Wed, 11 Feb 2026 23:19:30 -0500 Subject: [PATCH] fix(darwin): use scutil for provisioning hostname (#485) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit macOS Sequoia with Private Wi-Fi Address enabled causes os.Hostname() to return generic names like "Mac.lan" from DHCP instead of the real computer name. The /utility provisioning endpoint sends this raw, resulting in devices named "Mac-lan" in the dashboard. Fallback chain: ComputerName → LocalHostName → os.Hostname() LocalHostName can also be affected by DHCP. ComputerName is the user-set display name from System Settings, fully immune to network state. --- internal/controld/config.go | 3 +-- internal/controld/hostname_darwin.go | 26 ++++++++++++++++++++++++++ internal/controld/hostname_others.go | 10 ++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 internal/controld/hostname_darwin.go create mode 100644 internal/controld/hostname_others.go diff --git a/internal/controld/config.go b/internal/controld/config.go index b833699..d2451eb 100644 --- a/internal/controld/config.go +++ b/internal/controld/config.go @@ -10,7 +10,6 @@ import ( "io" "net" "net/http" - "os" "runtime" "strings" "time" @@ -127,7 +126,7 @@ func FetchResolverUID(ctx context.Context, req *UtilityOrgRequest, version strin hostname := req.Hostname if req.Hostname == "" { - hostname, _ = os.Hostname() + hostname, _ = preferredHostname() ctrld.Log(ctx, logger.Debug(), "Using system hostname: %s", hostname) req.Hostname = hostname } else { diff --git a/internal/controld/hostname_darwin.go b/internal/controld/hostname_darwin.go new file mode 100644 index 0000000..107b4cd --- /dev/null +++ b/internal/controld/hostname_darwin.go @@ -0,0 +1,26 @@ +package controld + +import ( + "os" + "os/exec" + "strings" +) + +// preferredHostname returns the best available hostname on macOS. +// It prefers scutil --get ComputerName which is the user-configured name +// from System Settings → General → About → Name. This is immune to +// DHCP/network state that can cause os.Hostname() and even LocalHostName +// to return generic names like "Mac.lan" on Sequoia with Private Wi-Fi +// Address enabled. +// +// Fallback chain: ComputerName → LocalHostName → os.Hostname() +func preferredHostname() (string, error) { + for _, key := range []string{"ComputerName", "LocalHostName"} { + if out, err := exec.Command("scutil", "--get", key).Output(); err == nil { + if name := strings.TrimSpace(string(out)); name != "" { + return name, nil + } + } + } + return os.Hostname() +} diff --git a/internal/controld/hostname_others.go b/internal/controld/hostname_others.go new file mode 100644 index 0000000..9ae1026 --- /dev/null +++ b/internal/controld/hostname_others.go @@ -0,0 +1,10 @@ +//go:build !darwin + +package controld + +import "os" + +// preferredHostname returns the system hostname on non-Darwin platforms. +func preferredHostname() (string, error) { + return os.Hostname() +}