mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-08-10 13:20:33 +02:00
cmd/cli: fix systemd-networkd-wait-online blocks ctrld starts
The systemd-networkd-wait-online is only required if systemd-networkd is managing any interfaces. Otherwise, it will hang and block ctrld from starting. See: https://github.com/systemd/systemd/issues/23304
This commit is contained in:
+28
-1
@@ -1,7 +1,12 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/kardianos/service"
|
"github.com/kardianos/service"
|
||||||
|
|
||||||
@@ -24,12 +29,34 @@ func setDependencies(svc *service.Config) {
|
|||||||
"After=network-online.target",
|
"After=network-online.target",
|
||||||
"Wants=NetworkManager-wait-online.service",
|
"Wants=NetworkManager-wait-online.service",
|
||||||
"After=NetworkManager-wait-online.service",
|
"After=NetworkManager-wait-online.service",
|
||||||
"Wants=systemd-networkd-wait-online.service",
|
|
||||||
"Wants=nss-lookup.target",
|
"Wants=nss-lookup.target",
|
||||||
"After=nss-lookup.target",
|
"After=nss-lookup.target",
|
||||||
}
|
}
|
||||||
|
if out, _ := exec.Command("networkctl", "--no-pager").CombinedOutput(); len(out) > 0 {
|
||||||
|
if wantsSystemDNetworkdWaitOnline(bytes.NewReader(out)) {
|
||||||
|
svc.Dependencies = append(svc.Dependencies, "Wants=systemd-networkd-wait-online.service")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setWorkingDirectory(svc *service.Config, dir string) {
|
func setWorkingDirectory(svc *service.Config, dir string) {
|
||||||
svc.WorkingDirectory = dir
|
svc.WorkingDirectory = dir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wantsSystemDNetworkdWaitOnline reports whether "systemd-networkd-wait-online" service
|
||||||
|
// is required to be added to ctrld dependencies services.
|
||||||
|
// The input reader r is the output of "networkctl --no-pager" command.
|
||||||
|
func wantsSystemDNetworkdWaitOnline(r io.Reader) bool {
|
||||||
|
scanner := bufio.NewScanner(r)
|
||||||
|
// Skip header
|
||||||
|
scanner.Scan()
|
||||||
|
configured := false
|
||||||
|
for scanner.Scan() {
|
||||||
|
fields := strings.Fields(scanner.Text())
|
||||||
|
if len(fields) > 0 && fields[len(fields)-1] == "configured" {
|
||||||
|
configured = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return configured
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
networkctlUnmanagedOutput = `IDX LINK TYPE OPERATIONAL SETUP
|
||||||
|
1 lo loopback carrier unmanaged
|
||||||
|
2 wlp0s20f3 wlan routable unmanaged
|
||||||
|
3 tailscale0 none routable unmanaged
|
||||||
|
4 br-9ac33145e060 bridge no-carrier unmanaged
|
||||||
|
5 docker0 bridge no-carrier unmanaged
|
||||||
|
|
||||||
|
5 links listed.
|
||||||
|
`
|
||||||
|
networkctlManagedOutput = `IDX LINK TYPE OPERATIONAL SETUP
|
||||||
|
1 lo loopback carrier unmanaged
|
||||||
|
2 wlp0s20f3 wlan routable configured
|
||||||
|
3 tailscale0 none routable unmanaged
|
||||||
|
4 br-9ac33145e060 bridge no-carrier unmanaged
|
||||||
|
5 docker0 bridge no-carrier unmanaged
|
||||||
|
|
||||||
|
5 links listed.
|
||||||
|
`
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_wantsSystemDNetworkdWaitOnline(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
r io.Reader
|
||||||
|
required bool
|
||||||
|
}{
|
||||||
|
{"unmanaged", strings.NewReader(networkctlUnmanagedOutput), false},
|
||||||
|
{"managed", strings.NewReader(networkctlManagedOutput), true},
|
||||||
|
{"empty", strings.NewReader(""), false},
|
||||||
|
}
|
||||||
|
for _, tc := range tests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
if required := wantsSystemDNetworkdWaitOnline(tc.r); required != tc.required {
|
||||||
|
t.Errorf("wants %v got %v", tc.required, required)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user