6 kexec "k8s.io/utils/exec"
14 ovsCommandTimeout = 15
15 ovnNbctlCommand = "ovn-nbctl"
16 ovsVsctlCommand = "ovs-vsctl"
20 // Exec runs various OVN and OVS utilities
21 type execHelper struct {
30 var runner *execHelper
32 // SetupOvnUtils does internal OVN initialization
33 var SetupOvnUtils = func() error {
34 // Setup Distributed Router
35 err := setupDistributedRouter(ovn4nfvRouterName)
37 log.Error(err, "Failed to initialize OVN Distributed Router")
41 log.Info("OVN Network", "OVN Default NW", Ovn4nfvDefaultNw, "OVN Subnet", ovnConf.Subnet, "OVN Gateway IP", ovnConf.GatewayIP, "OVN ExcludeIPs", ovnConf.ExcludeIPs)
42 _, err = createOvnLS(Ovn4nfvDefaultNw, ovnConf.Subnet, ovnConf.GatewayIP, ovnConf.ExcludeIPs)
43 if err != nil && !reflect.DeepEqual(err, fmt.Errorf("LS exists")) {
44 log.Error(err, "Failed to create ovn4nfvk8s default nw")
50 // SetExec validates executable paths and saves the given exec interface
51 // to be used for running various OVS and OVN utilites
52 func SetExec(exec kexec.Interface) error {
55 runner = &execHelper{exec: exec}
56 runner.nbctlPath, err = exec.LookPath(ovnNbctlCommand)
60 runner.vsctlPath, err = exec.LookPath(ovsVsctlCommand)
64 runner.ipPath, err = exec.LookPath(ipCommand)
68 runner.hostIP = os.Getenv("HOST_IP")
70 runner.hostPort = "6641"
71 log.Info("Host Port", "IP", runner.hostIP, "Port", runner.hostPort)
76 // Run the ovn-ctl command and retry if "Connection refused"
77 // poll waitng for service to become available
78 func runOVNretry(cmdPath string, args ...string) (*bytes.Buffer, *bytes.Buffer, error) {
82 stdout, stderr, err := run(cmdPath, args...)
84 return stdout, stderr, err
87 // Master may not be up so keep trying
88 if strings.Contains(stderr.String(), "Connection refused") {
90 return stdout, stderr, err
93 time.Sleep(2 * time.Second)
95 // Some other problem for caller to handle
96 return stdout, stderr, err
101 func run(cmdPath string, args ...string) (*bytes.Buffer, *bytes.Buffer, error) {
102 stdout := &bytes.Buffer{}
103 stderr := &bytes.Buffer{}
104 cmd := runner.exec.Command(cmdPath, args...)
105 cmd.SetStdout(stdout)
106 cmd.SetStderr(stderr)
107 log.V(1).Info("exec:", "cmdPath", cmdPath, "args", strings.Join(args, " "))
110 log.Info("ovs", "Error:", err, "cmdPath", cmdPath, "args", strings.Join(args, " "), "stdout", stdout, "stderr", stderr)
112 log.V(1).Info("output:", "stdout", stdout)
114 return stdout, stderr, err
117 // RunOVNNbctlWithTimeout runs command via ovn-nbctl with a specific timeout
118 func RunOVNNbctlWithTimeout(timeout int, args ...string) (string, string, error) {
120 if len(runner.hostIP) > 0 {
122 fmt.Sprintf("--db=tcp:%s:%s", runner.hostIP, runner.hostPort),
125 cmdArgs = append(cmdArgs, fmt.Sprintf("--timeout=%d", timeout))
126 cmdArgs = append(cmdArgs, args...)
127 stdout, stderr, err := runOVNretry(runner.nbctlPath, cmdArgs...)
128 return strings.Trim(strings.TrimSpace(stdout.String()), "\""), stderr.String(), err
131 // RunOVNNbctl runs a command via ovn-nbctl.
132 func RunOVNNbctl(args ...string) (string, string, error) {
133 return RunOVNNbctlWithTimeout(ovsCommandTimeout, args...)
136 // RunIP runs a command via the iproute2 "ip" utility
137 func RunIP(args ...string) (string, string, error) {
138 stdout, stderr, err := run(runner.ipPath, args...)
139 return strings.TrimSpace(stdout.String()), stderr.String(), err
142 // RunOVSVsctl runs a command via ovs-vsctl.
143 func RunOVSVsctl(args ...string) (string, string, error) {
144 cmdArgs := []string{fmt.Sprintf("--timeout=%d", ovsCommandTimeout)}
145 cmdArgs = append(cmdArgs, args...)
146 stdout, stderr, err := run(runner.vsctlPath, cmdArgs...)
147 return strings.Trim(strings.TrimSpace(stdout.String()), "\""), stderr.String(), err