package cli import ( "context" "os" "os/exec" "path/filepath" "time" "github.com/coreos/go-systemd/v22/dbus" ) const ( nmConfDir = "/etc/NetworkManager/conf.d" nmCtrldConfFilename = "99-ctrld.conf" nmCtrldConfContent = `[main] dns=none systemd-resolved=false ` nmSystemdUnitName = "NetworkManager.service" ) var networkManagerCtrldConfFile = filepath.Join(nmConfDir, nmCtrldConfFilename) // hasNetworkManager reports whether NetworkManager executable found. // hasNetworkManager checks if NetworkManager is available on the system func hasNetworkManager() bool { exe, _ := exec.LookPath("NetworkManager") return exe != "" } func (p *prog) setupNetworkManager() error { if !hasNetworkManager() { return nil } if content, _ := os.ReadFile(nmCtrldConfContent); string(content) == nmCtrldConfContent { p.Debug().Msg("NetworkManager already setup, nothing to do") return nil } err := os.WriteFile(networkManagerCtrldConfFile, []byte(nmCtrldConfContent), os.FileMode(0644)) if os.IsNotExist(err) { p.Debug().Msg("NetworkManager is not available") return nil } if err != nil { p.Debug().Err(err).Msg("Could not write NetworkManager ctrld config file") return err } p.reloadNetworkManager() p.Debug().Msg("Setup NetworkManager done") return nil } func (p *prog) restoreNetworkManager() error { if !hasNetworkManager() { return nil } err := os.Remove(networkManagerCtrldConfFile) if os.IsNotExist(err) { p.Debug().Msg("NetworkManager is not available") return nil } if err != nil { p.Debug().Err(err).Msg("Could not remove NetworkManager ctrld config file") return err } p.reloadNetworkManager() p.Debug().Msg("Restore NetworkManager done") return nil } func (p *prog) reloadNetworkManager() { ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) defer cancel() conn, err := dbus.NewSystemConnectionContext(ctx) if err != nil { p.Error().Err(err).Msg("Could not create new system connection") return } defer conn.Close() waitCh := make(chan string) if _, err := conn.ReloadUnitContext(ctx, nmSystemdUnitName, "ignore-dependencies", waitCh); err != nil { p.Debug().Err(err).Msg("Could not reload NetworkManager") return } <-waitCh }