diff --git a/build-env b/build-env index 9fa387f3c..d74ed0d21 100755 --- a/build-env +++ b/build-env @@ -21,3 +21,4 @@ eval $(go env) export PATH="${GOROOT}/bin:${PATH}" export FLEETD_BIN="$(pwd)/bin/fleetd" export FLEETCTL_BIN="$(pwd)/bin/fleetctl" +export ETCDCTL_BIN="/usr/bin/etcdctl" diff --git a/functional/util/util.go b/functional/util/util.go index 5942c011a..501218d71 100644 --- a/functional/util/util.go +++ b/functional/util/util.go @@ -25,6 +25,7 @@ import ( ) var fleetctlBinPath string +var etcdctlBinPath string func init() { fleetctlBinPath = os.Getenv("FLEETCTL_BIN") @@ -36,6 +37,15 @@ func init() { os.Exit(1) } + etcdctlBinPath = os.Getenv("ETCDCTL_BIN") + if etcdctlBinPath == "" { + fmt.Println("ETCDCTL_BIN environment variable must be set") + os.Exit(1) + } else if _, err := os.Stat(etcdctlBinPath); err != nil { + fmt.Printf("%v\n", err) + os.Exit(1) + } + if os.Getenv("SSH_AUTH_SOCK") == "" { fmt.Println("SSH_AUTH_SOCK environment variable must be set") os.Exit(1) @@ -76,6 +86,38 @@ func RunFleetctlWithInput(input string, args ...string) (string, string, error) return stdoutBytes.String(), stderrBytes.String(), err } +func RunEtcdctl(args ...string) (string, string, error) { + log.Printf("%s %s", etcdctlBinPath, strings.Join(args, " ")) + var stdoutBytes, stderrBytes bytes.Buffer + cmd := exec.Command(etcdctlBinPath, args...) + cmd.Stdout = &stdoutBytes + cmd.Stderr = &stderrBytes + err := cmd.Run() + return stdoutBytes.String(), stderrBytes.String(), err +} + +func RunEtcdctlWithInput(input string, args ...string) (string, string, error) { + log.Printf("%s %s", etcdctlBinPath, strings.Join(args, " ")) + var stdoutBytes, stderrBytes bytes.Buffer + cmd := exec.Command(etcdctlBinPath, args...) + cmd.Stdout = &stdoutBytes + cmd.Stderr = &stderrBytes + stdin, err := cmd.StdinPipe() + if err != nil { + return "", "", err + } + + if err = cmd.Start(); err != nil { + return "", "", err + } + + stdin.Write([]byte(input)) + stdin.Close() + err = cmd.Wait() + + return stdoutBytes.String(), stderrBytes.String(), err +} + // ActiveToSingleStates takes a map of active states (such as that returned by // WaitForNActiveUnits) and ensures that each unit has at most a single active // state. It returns a mapping of unit name to a single UnitState.