From aa41b49246d84b605a76d169f0c861ba0691a4fb Mon Sep 17 00:00:00 2001 From: Ritu Sood Date: Tue, 30 Jul 2019 15:40:55 -0700 Subject: Consolidate OVN related code under ovn dir This patch is a cleanup patch and doesn't introduce any fuctionality changes. Includes removing of unused code and rearranging code. Change-Id: Idf4a36e09a6d5c200cf191c995184076ffa0326d Signed-off-by: Ritu Sood --- internal/pkg/ovn/utils.go | 120 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 internal/pkg/ovn/utils.go (limited to 'internal/pkg/ovn/utils.go') diff --git a/internal/pkg/ovn/utils.go b/internal/pkg/ovn/utils.go new file mode 100644 index 0000000..1700bf8 --- /dev/null +++ b/internal/pkg/ovn/utils.go @@ -0,0 +1,120 @@ +package ovn + +import ( + "bytes" + "fmt" + "strings" + "time" + "unicode" + + "github.com/sirupsen/logrus" + kexec "k8s.io/utils/exec" +) + +const ( + ovsCommandTimeout = 15 + ovsVsctlCommand = "ovs-vsctl" + ovsOfctlCommand = "ovs-ofctl" + ovnNbctlCommand = "ovn-nbctl" + ipCommand = "ip" +) + +// Exec runs various OVN and OVS utilities +type execHelper struct { + exec kexec.Interface + ofctlPath string + vsctlPath string + nbctlPath string + ipPath string +} + +var runner *execHelper + +// SetExec validates executable paths and saves the given exec interface +// to be used for running various OVS and OVN utilites +func SetExec(exec kexec.Interface) error { + var err error + + runner = &execHelper{exec: exec} + runner.ofctlPath, err = exec.LookPath(ovsOfctlCommand) + if err != nil { + return err + } + runner.vsctlPath, err = exec.LookPath(ovsVsctlCommand) + if err != nil { + return err + } + runner.nbctlPath, err = exec.LookPath(ovnNbctlCommand) + if err != nil { + return err + } + runner.ipPath, err = exec.LookPath(ipCommand) + if err != nil { + return err + } + return nil +} + +// Run the ovn-ctl command and retry if "Connection refused" +// poll waitng for service to become available +func runOVNretry(cmdPath string, args ...string) (*bytes.Buffer, *bytes.Buffer, error) { + + retriesLeft := 200 + for { + stdout, stderr, err := run(cmdPath, args...) + if err == nil { + return stdout, stderr, err + } + + // Connection refused + // Master may not be up so keep trying + if strings.Contains(stderr.String(), "Connection refused") { + if retriesLeft == 0 { + return stdout, stderr, err + } + retriesLeft-- + time.Sleep(2 * time.Second) + } else { + // Some other problem for caller to handle + return stdout, stderr, err + } + } +} + +func run(cmdPath string, args ...string) (*bytes.Buffer, *bytes.Buffer, error) { + stdout := &bytes.Buffer{} + stderr := &bytes.Buffer{} + cmd := runner.exec.Command(cmdPath, args...) + cmd.SetStdout(stdout) + cmd.SetStderr(stderr) + logrus.Debugf("exec: %s %s", cmdPath, strings.Join(args, " ")) + err := cmd.Run() + if err != nil { + logrus.Debugf("exec: %s %s => %v", cmdPath, strings.Join(args, " "), err) + } + return stdout, stderr, err +} + +// RunOVSVsctl runs a command via ovs-vsctl. +func RunOVSVsctlUnix(args ...string) (string, string, error) { + cmdArgs := []string{fmt.Sprintf("--timeout=%d", ovsCommandTimeout)} + cmdArgs = append(cmdArgs, args...) + stdout, stderr, err := run(runner.vsctlPath, cmdArgs...) + return strings.Trim(strings.TrimSpace(stdout.String()), "\""), stderr.String(), err +} + +// RunOVNNbctlUnix runs command via ovn-nbctl, with ovn-nbctl using the unix +// domain sockets to connect to the ovsdb-server backing the OVN NB database. +func RunOVNNbctlUnix(args ...string) (string, string, error) { + cmdArgs := []string{fmt.Sprintf("--timeout=%d", ovsCommandTimeout)} + cmdArgs = append(cmdArgs, args...) + stdout, stderr, err := runOVNretry(runner.nbctlPath, cmdArgs...) + return strings.Trim(strings.TrimFunc(stdout.String(), unicode.IsSpace), "\""), + stderr.String(), err +} + +// RunIP runs a command via the iproute2 "ip" utility +func RunIP(args ...string) (string, string, error) { + stdout, stderr, err := run(runner.ipPath, args...) + return strings.TrimSpace(stdout.String()), stderr.String(), err +} -- cgit 1.2.3-korg