fix(cli): skip DNS restoration quietly when the interface is gone

Keep missing interfaces as debug skips while preserving enumeration
causes and error-level failures restoring DNS on existing interfaces.
Adapt the logger and NetworkManager method to master. Stub saved DNS
lookup in tests because master stores it through ctrld rather than the
CLI homedir; tests must not touch the service's saved DNS files.
This commit is contained in:
Cuong Manh Le committed 2026-09-22 21:08:04 +07:00
1 parent 37b835c791
commit 4879574605
3 files changed
+367 -9

No files matched your search

+18 -3
View File
@@ -1216,24 +1216,39 @@ func processLogAndCacheFlags(v *viper.Viper, cfg *ctrld.Config) {
mainLog.Load().Debug().Msg("Log and cache flags processed successfully")
}
// errInterfaceNotFound reports that the named interface does not exist on the
// host. Callers use errors.Is to tell this apart from a lookup that failed for
// another reason, because an interface that is simply gone (an unplugged
// adapter, a torn down tether) is an expected outcome rather than a failure.
var errInterfaceNotFound = errors.New("interface not found")
// foreachInterface enumerates the host network interfaces. It is a variable so
// tests can make enumeration fail without depending on the host.
var foreachInterface = netmon.ForeachInterface
// netInterface returns the network interface by name
func netInterface(ifaceName string) (*net.Interface, error) {
if ifaceName == autoIface {
ifaceName = defaultIfaceName()
}
var iface *net.Interface
err := netmon.ForeachInterface(func(i netmon.Interface, prefixes []netip.Prefix) {
err := foreachInterface(func(i netmon.Interface, prefixes []netip.Prefix) {
if i.Name == ifaceName {
iface = i.Interface
}
})
if err != nil {
// Enumeration itself failed, so the interface cannot be reported as
// missing: nothing was positively established about it.
return nil, err
}
if iface == nil {
return nil, errors.New("interface not found")
return nil, errInterfaceNotFound
}
if _, err := patchNetIfaceName(iface); err != nil {
return nil, err
}
return iface, err
return iface, nil
}
// defaultIfaceName returns the default interface name