cmd/cli: use better approach for detecting NetworkManager

Currently, ctrld assumes that NetworkManager is not available if writing
to /etc/NetworkManager/conf.d return directory not exist error. That
would work on most Linux distros. However, cloud provider may do some
hacks, causing ctrld confusion and think that NetworkManager is
available.

Fixing this by checking whether NetworkManager binary presents first.

While at it, also fixing a bug when restarting NetworkManager failed
causing ctrld hangs. The go-systemd library is not clear about this, but
the waitCh channel won't never be closed if error occurred, so we must
return immediately instead of receiving from it blindly.
This commit is contained in:
Cuong Manh Le authored and Cuong Manh Le committed 2023-09-22 18:42:21 +07:00
1 parent 80a88811cd
commit 2765487f10
1 file changed
+15 -2
+15 -2
View File
@@ -3,6 +3,7 @@ package cli
import ( import (
"context" "context"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"time" "time"
@@ -16,13 +17,21 @@ const (
dns=none dns=none
systemd-resolved=false systemd-resolved=false
` `
nmSystemdUnitName = "NetworkManager.service" nmSystemdUnitName = "NetworkManager.service"
systemdEnabledState = "enabled"
) )
var networkManagerCtrldConfFile = filepath.Join(nmConfDir, nmCtrldConfFilename) var networkManagerCtrldConfFile = filepath.Join(nmConfDir, nmCtrldConfFilename)
// hasNetworkManager reports whether NetworkManager executable found.
func hasNetworkManager() bool {
exe, _ := exec.LookPath("NetworkManager")
return exe != ""
}
func setupNetworkManager() error { func setupNetworkManager() error {
if !hasNetworkManager() {
return nil
}
if content, _ := os.ReadFile(nmCtrldConfContent); string(content) == nmCtrldConfContent { if content, _ := os.ReadFile(nmCtrldConfContent); string(content) == nmCtrldConfContent {
mainLog.Load().Debug().Msg("NetworkManager already setup, nothing to do") mainLog.Load().Debug().Msg("NetworkManager already setup, nothing to do")
return nil return nil
@@ -43,6 +52,9 @@ func setupNetworkManager() error {
} }
func restoreNetworkManager() error { func restoreNetworkManager() error {
if !hasNetworkManager() {
return nil
}
err := os.Remove(networkManagerCtrldConfFile) err := os.Remove(networkManagerCtrldConfFile)
if os.IsNotExist(err) { if os.IsNotExist(err) {
mainLog.Load().Debug().Msg("NetworkManager is not available") mainLog.Load().Debug().Msg("NetworkManager is not available")
@@ -71,6 +83,7 @@ func reloadNetworkManager() {
waitCh := make(chan string) waitCh := make(chan string)
if _, err := conn.ReloadUnitContext(ctx, nmSystemdUnitName, "ignore-dependencies", waitCh); err != nil { if _, err := conn.ReloadUnitContext(ctx, nmSystemdUnitName, "ignore-dependencies", waitCh); err != nil {
mainLog.Load().Debug().Err(err).Msg("could not reload NetworkManager") mainLog.Load().Debug().Err(err).Msg("could not reload NetworkManager")
return
} }
<-waitCh <-waitCh
} }