From ac97f357d750bce802a59b4240e1bc3121fa8d57 Mon Sep 17 00:00:00 2001 From: Siyuan Miao Date: Fri, 28 Nov 2025 10:05:08 +0000 Subject: [PATCH 1/3] fix(ui): custom domain not being shown in the form --- ui/src/routes/devices.$id.settings.network.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ui/src/routes/devices.$id.settings.network.tsx b/ui/src/routes/devices.$id.settings.network.tsx index 8fdece8b5..e34011ac3 100644 --- a/ui/src/routes/devices.$id.settings.network.tsx +++ b/ui/src/routes/devices.$id.settings.network.tsx @@ -77,6 +77,8 @@ export function LifeTimeLabel({ lifetime }: Readonly<{ lifetime: string }>) { ); } +const NonCustomDomainOptions = ["dhcp", "local"]; + export default function SettingsNetworkRoute() { const { send } = useJsonRpc(); @@ -128,13 +130,18 @@ export default function SettingsNetworkRoute() { }, }; + if (!NonCustomDomainOptions.includes(settingsWithDefaults.domain)) { + setCustomDomain(settingsWithDefaults.domain); + settingsWithDefaults.domain = "custom"; + } + initialSettingsRef.current = settingsWithDefaults; return { settings: settingsWithDefaults, state }; } catch (err) { notifications.error(m.network_settings_load_error({ error: err instanceof Error ? err.message : m.unknown_error() })); throw err; } - }, [setNetworkState]); + }, [setNetworkState, setCustomDomain]); const formMethods = useForm({ mode: "onBlur", @@ -406,6 +413,7 @@ export default function SettingsNetworkRoute() { type="text" label={m.network_custom_domain()} placeholder="home.example.com" + value={customDomain} onChange={e => { setCustomDomain(e.target.value); }} From c59ff4a3f43bbd9f5694e1911640c6f126bd3066 Mon Sep 17 00:00:00 2001 From: Siyuan Miao Date: Fri, 28 Nov 2025 10:28:09 +0000 Subject: [PATCH 2/3] wip: add domain to DHCP lease --- pkg/nmlite/interface.go | 1 + pkg/nmlite/resolvconf.go | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/pkg/nmlite/interface.go b/pkg/nmlite/interface.go index 58bd73537..a9111a645 100644 --- a/pkg/nmlite/interface.go +++ b/pkg/nmlite/interface.go @@ -787,6 +787,7 @@ func (im *InterfaceManager) updateStateFromDHCPLease(lease *types.DHCPLease) { NameServers: lease.DNS, SearchList: lease.SearchList, Source: "dhcp", + Domain: lease.Domain, }); err != nil { im.logger.Warn().Err(err).Msg("failed to update resolv.conf") } diff --git a/pkg/nmlite/resolvconf.go b/pkg/nmlite/resolvconf.go index 1bacee7a9..0409bc53b 100644 --- a/pkg/nmlite/resolvconf.go +++ b/pkg/nmlite/resolvconf.go @@ -147,9 +147,10 @@ func (rcm *ResolvConfManager) update() error { type configMap map[string][]string -func mergeConfig(nameservers *configMap, searchList *configMap, config *types.InterfaceResolvConfMap) { +func mergeConfig(nameservers *configMap, searchList *configMap, domains *configMap, config *types.InterfaceResolvConfMap) { localNameservers := *nameservers localSearchList := *searchList + localDomains := *domains for ifname, iface := range *config { comment := ifname @@ -172,10 +173,18 @@ func mergeConfig(nameservers *configMap, searchList *configMap, config *types.In } localSearchList[search] = append(localSearchList[search], comment) } + + if iface.Domain != "" { + if _, ok := localDomains[iface.Domain]; !ok { + localDomains[iface.Domain] = []string{} + } + localDomains[iface.Domain] = append(localDomains[iface.Domain], comment) + } } *nameservers = localNameservers *searchList = localSearchList + *domains = localDomains } // generateResolvConf generates resolv.conf content @@ -188,9 +197,16 @@ func (rcm *ResolvConfManager) generateResolvConf(conf *types.ResolvConf) ([]byte // merge the nameservers and searchList nameservers := configMap{} searchList := configMap{} + domains := configMap{} - mergeConfig(&nameservers, &searchList, &conf.ConfigIPv4) - mergeConfig(&nameservers, &searchList, &conf.ConfigIPv6) + mergeConfig(&nameservers, &searchList, &domains, &conf.ConfigIPv4) + mergeConfig(&nameservers, &searchList, &domains, &conf.ConfigIPv6) + + rcm.logger.Info(). + Interface("nameservers", nameservers). + Interface("searchList", searchList). + Interface("domains", domains). + Msg("merged config") flattenedSearchList := []string{} for search := range searchList { From fb165a34ecd1923c189983957432cc1dec17a0e0 Mon Sep 17 00:00:00 2001 From: Siyuan Date: Fri, 28 Nov 2025 11:00:06 +0000 Subject: [PATCH 3/3] fix: handle dhcp domain correctly --- pkg/nmlite/hostname.go | 2 +- pkg/nmlite/resolvconf.go | 18 ++++-------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/pkg/nmlite/hostname.go b/pkg/nmlite/hostname.go index 146aad0b6..88f35330c 100644 --- a/pkg/nmlite/hostname.go +++ b/pkg/nmlite/hostname.go @@ -67,7 +67,7 @@ func (hm *ResolvConfManager) getHostname() string { } func (hm *ResolvConfManager) getDomain() string { - if hm.domain != "" { + if hm.domain != "" && hm.domain != "dhcp" { return hm.domain } diff --git a/pkg/nmlite/resolvconf.go b/pkg/nmlite/resolvconf.go index 0409bc53b..b94f5c3db 100644 --- a/pkg/nmlite/resolvconf.go +++ b/pkg/nmlite/resolvconf.go @@ -147,10 +147,9 @@ func (rcm *ResolvConfManager) update() error { type configMap map[string][]string -func mergeConfig(nameservers *configMap, searchList *configMap, domains *configMap, config *types.InterfaceResolvConfMap) { +func mergeConfig(nameservers *configMap, searchList *configMap, config *types.InterfaceResolvConfMap) { localNameservers := *nameservers localSearchList := *searchList - localDomains := *domains for ifname, iface := range *config { comment := ifname @@ -173,18 +172,10 @@ func mergeConfig(nameservers *configMap, searchList *configMap, domains *configM } localSearchList[search] = append(localSearchList[search], comment) } - - if iface.Domain != "" { - if _, ok := localDomains[iface.Domain]; !ok { - localDomains[iface.Domain] = []string{} - } - localDomains[iface.Domain] = append(localDomains[iface.Domain], comment) - } } *nameservers = localNameservers *searchList = localSearchList - *domains = localDomains } // generateResolvConf generates resolv.conf content @@ -197,15 +188,13 @@ func (rcm *ResolvConfManager) generateResolvConf(conf *types.ResolvConf) ([]byte // merge the nameservers and searchList nameservers := configMap{} searchList := configMap{} - domains := configMap{} - mergeConfig(&nameservers, &searchList, &domains, &conf.ConfigIPv4) - mergeConfig(&nameservers, &searchList, &domains, &conf.ConfigIPv6) + mergeConfig(&nameservers, &searchList, &conf.ConfigIPv4) + mergeConfig(&nameservers, &searchList, &conf.ConfigIPv6) rcm.logger.Info(). Interface("nameservers", nameservers). Interface("searchList", searchList). - Interface("domains", domains). Msg("merged config") flattenedSearchList := []string{} @@ -215,6 +204,7 @@ func (rcm *ResolvConfManager) generateResolvConf(conf *types.ResolvConf) ([]byte var buf bytes.Buffer if err := tmpl.Execute(&buf, map[string]any{ + "domain": rcm.getDomain(), "nameservers": nameservers, "searchList": flattenedSearchList, }); err != nil {