Skip to content

Commit

Permalink
swctl: option of continuous printing of commands to stdout/err (#139)
Browse files Browse the repository at this point in the history
swctl: adding option for continuous printing of std outputs from cli.Exec()

Signed-off-by: Daniel Béreš <[email protected]>
  • Loading branch information
Giluerre committed Oct 12, 2023
1 parent fbc4611 commit 19b0e5c
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 34 deletions.
7 changes: 4 additions & 3 deletions cmd/swctl/app/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type Cli interface {
Client() client.API
Entities() []Entity
GlobalOptions() *GlobalOptions
Exec(cmd string, args []string) (stdout string, stderr string, err error)
Exec(cmd string, args []string, liveOutput bool) (stdout string, stderr string, err error)
AppName() string

Out() *streams.Out
Expand Down Expand Up @@ -136,7 +136,7 @@ func (cli *CLI) GlobalOptions() *GlobalOptions {
return cli.globalOptions
}

func (cli *CLI) Exec(cmd string, args []string) (string, string, error) {
func (cli *CLI) Exec(cmd string, args []string, liveOutput bool) (string, string, error) {
if cmd == "" {
return "", "", errors.New("cannot execute empty command")
}
Expand All @@ -145,7 +145,8 @@ func (cli *CLI) Exec(cmd string, args []string) (string, string, error) {
args = append(cmdParts[1:], args...)
}
ecmd := newExternalCmd(externalExe(cmdParts[0]), args, cli)
res, err := ecmd.exec()

res, err := ecmd.exec(liveOutput)
if err != nil {
return "", "", err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/swctl/app/cmd_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func runConfigCmd(cli Cli, opts ConfigCmdOptions) error {
args = append(args, hideInternalFlag)
}

stdout, stderr, err := cli.Exec("agentctl config", args)
stdout, stderr, err := cli.Exec("agentctl config", args, false)
if err != nil {
return err
}
Expand Down
18 changes: 9 additions & 9 deletions cmd/swctl/app/cmd_dependency.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,15 @@ func linkSetUpDown(cli Cli) *cobra.Command {
}
} else if args[len(args)-1] == "down" {
//link down interface, only assigned network devices have /net directory which is name of interface
stdout, stderr, err := cli.Exec("ls", []string{"/sys/bus/pci/devices/" + physicalInterfaces[matchId].Pci + "/net"})
stdout, stderr, err := cli.Exec("ls", []string{"/sys/bus/pci/devices/" + physicalInterfaces[matchId].Pci + "/net"}, false)
if stderr != "" {
return errors.New(stderr)
}
if err != err {
return err
}
if stdout != "" {
_, _, err = cli.Exec("sudo ip link set "+stdout+" down", nil)
_, _, err = cli.Exec("sudo ip link set "+stdout+" down", nil, false)
if err != err {
return err
}
Expand All @@ -269,7 +269,7 @@ func linkSetUpDown(cli Cli) *cobra.Command {
}

func IsDockerAvailable(cli Cli) (bool, error) {
out, _, err := cli.Exec("whereis docker", nil)
out, _, err := cli.Exec("whereis docker", nil, false)
if err != nil {
return false, err
}
Expand All @@ -280,7 +280,7 @@ func IsDockerAvailable(cli Cli) (bool, error) {
}

func AllocatedHugePages(cli Cli) (int, error) {
out, _, err := cli.Exec("sysctl vm.nr_hugepages -n", nil)
out, _, err := cli.Exec("sysctl vm.nr_hugepages -n", nil, false)
if err != nil {
return 0, err
}
Expand All @@ -300,7 +300,7 @@ func ResizeHugePages(cli Cli, size uint) error {
fmt.Fprintln(cli.Out(), "Skipping hugepages")
return nil
}
_, _, err := cli.Exec(fmt.Sprintf("sudo sysctl -w vm.nr_hugepages=%d", size), nil)
_, _, err := cli.Exec(fmt.Sprintf("sudo sysctl -w vm.nr_hugepages=%d", size), nil, false)
if err != nil {
return err
}
Expand Down Expand Up @@ -341,7 +341,7 @@ func InstallDocker(cli Cli, dockerVersion string) error {
}

for _, command := range commands {
out, stderr, err := cli.Exec("bash -c", []string{command})
out, stderr, err := cli.Exec("bash -c", []string{command}, false)
if stderr != "" {
return errors.New(command + ": " + stderr)
}
Expand Down Expand Up @@ -433,7 +433,7 @@ func unbindDevice(cli Cli, pci string, driver string) error {
//Mostly
path := fmt.Sprintf("/sys/bus/pci/drivers/%s/unbind", driver)

_, stderr, err := cli.Exec("sudo bash -c", []string{"echo \"" + pci + "\" > " + path})
_, stderr, err := cli.Exec("sudo bash -c", []string{"echo \"" + pci + "\" > " + path}, false)
if stderr != "" {
return errors.New(stderr)
}
Expand All @@ -446,7 +446,7 @@ func bindDevice(cli Cli, pci string, driver string) error {

path := fmt.Sprintf("/sys/bus/pci/drivers/%s/bind", driver)

_, stderr, err := cli.Exec("sudo bash -c", []string{"echo \"" + pci + "\" > " + path})
_, stderr, err := cli.Exec("sudo bash -c", []string{"echo \"" + pci + "\" > " + path}, false)
if stderr != "" {
return errors.New(stderr)
}
Expand All @@ -459,7 +459,7 @@ func bindDevice(cli Cli, pci string, driver string) error {
func DumpDevices(cli Cli) ([]NetworkInterface, error) {
var nics []NetworkInterface

stdout, _, err := cli.Exec("lspci", []string{"-Dvmmnnk"})
stdout, _, err := cli.Exec("lspci", []string{"-Dvmmnnk"}, false)
if err != nil {
return nil, err
}
Expand Down
16 changes: 6 additions & 10 deletions cmd/swctl/app/cmd_deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,10 @@ func newDeploymentUp(cli Cli) *cobra.Command {
Args: cobra.ArbitraryArgs,
DisableFlagParsing: true,
RunE: func(cmd *cobra.Command, args []string) error {
stdout, stderr, err := cli.Exec("docker compose up", args)
_, _, err := cli.Exec("docker compose up", args, true)
if err != nil {
return err
}
fmt.Fprintln(cli.Out(), stdout)
fmt.Fprintln(cli.Err(), stderr)
return nil
},
}
Expand All @@ -78,12 +76,10 @@ func newDeploymentDown(cli Cli) *cobra.Command {
Args: cobra.ArbitraryArgs,
DisableFlagParsing: true,
RunE: func(cmd *cobra.Command, args []string) error {
stdout, stderr, err := cli.Exec("docker compose down", args)
_, _, err := cli.Exec("docker compose down", args, true)
if err != nil {
return err
}
fmt.Fprintln(cli.Out(), stdout)
fmt.Fprintln(cli.Err(), stderr)
return nil
},
}
Expand All @@ -97,7 +93,7 @@ func newDeploymentConfig(cli Cli) *cobra.Command {
Args: cobra.ArbitraryArgs,
DisableFlagParsing: true,
RunE: func(cmd *cobra.Command, args []string) error {
stdout, stderr, err := cli.Exec("docker compose convert", args)
stdout, stderr, err := cli.Exec("docker compose convert", args, false)
if err != nil {
return err
}
Expand All @@ -116,7 +112,7 @@ func newDeploymentInfo(cli Cli) *cobra.Command {
Args: cobra.ArbitraryArgs,
DisableFlagParsing: true,
RunE: func(cmd *cobra.Command, args []string) error {
stdout, stderr, err := cli.Exec("docker compose ps", args)
stdout, stderr, err := cli.Exec("docker compose ps", args, false)
if err != nil {
return err
}
Expand All @@ -135,7 +131,7 @@ func newDeploymentImages(cli Cli) *cobra.Command {
Args: cobra.ArbitraryArgs,
DisableFlagParsing: true,
RunE: func(cmd *cobra.Command, args []string) error {
stdout, stderr, err := cli.Exec("docker compose images", args)
stdout, stderr, err := cli.Exec("docker compose images", args, false)
if err != nil {
return err
}
Expand All @@ -154,7 +150,7 @@ func newDeploymentServices(cli Cli) *cobra.Command {
Args: cobra.ArbitraryArgs,
DisableFlagParsing: true,
RunE: func(cmd *cobra.Command, args []string) error {
stdout, stderr, err := cli.Exec("docker compose ps --services", args)
stdout, stderr, err := cli.Exec("docker compose ps --services", args, false)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/swctl/app/cmd_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func runStatusCmd(cli Cli, opts StatusOptions) error {
if sn, ok := compo.GetMetadata()["containerServiceName"]; ok {
cmd := fmt.Sprintf("vpp-probe --env=%s --query label=%s=%s discover", defaultVppProbeEnv, compose.ServiceLabel, sn)
formatArg := fmt.Sprintf("--format=%s", opts.Format)
stdout, stderr, err := cli.Exec(cmd, []string{formatArg})
stdout, stderr, err := cli.Exec(cmd, []string{formatArg}, false)
if err != nil {
if ee, ok := err.(*exec.ExitError); ok {
logrus.Tracef("vpp-probe discover failed for service %s with error: %v: %s", sn, ee.String(), ee.Stderr)
Expand Down
12 changes: 6 additions & 6 deletions cmd/swctl/app/cmd_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ func writeInterfaces(cli Cli, w io.Writer, components []client.Component, otherA
for _, compo := range components {
if sn, ok := compo.GetMetadata()["containerServiceName"]; ok {
cmd := fmt.Sprintf("vpp-probe --color never --env=%s --query label=%s=%s discover", defaultVppProbeEnv, compose.ServiceLabel, sn)
stdout, _, err := cli.Exec(cmd, []string{})
stdout, _, err := cli.Exec(cmd, []string{}, false)
if err != nil {
if ee, ok := err.(*exec.ExitError); ok {
logrus.Tracef("vpp-probe discover failed for service %s with error: %v: %s", sn, ee.String(), ee.Stderr)
Expand Down Expand Up @@ -258,7 +258,7 @@ func writeStatusAsJson(cli Cli, w io.Writer, components []client.Component, othe

func writeDockerComposeConfig(cli Cli, w io.Writer, components []client.Component, otherArgs ...interface{}) error {
cmd := "docker compose config"
stdout, stderr, err := cli.Exec(cmd, []string{})
stdout, stderr, err := cli.Exec(cmd, []string{}, false)
if err != nil {
return err
}
Expand All @@ -271,7 +271,7 @@ func writeDockerComposeConfig(cli Cli, w io.Writer, components []client.Componen

func writeDockerContainers(cli Cli, w io.Writer, components []client.Component, otherArgs ...interface{}) error {
cmd := "docker compose ps --all"
stdout, stderr, err := cli.Exec(cmd, []string{})
stdout, stderr, err := cli.Exec(cmd, []string{}, false)
if err != nil {
return err
}
Expand All @@ -284,7 +284,7 @@ func writeDockerContainers(cli Cli, w io.Writer, components []client.Component,

func writeDockerInspect(cli Cli, w io.Writer, components []client.Component, otherArgs ...interface{}) error {
cmd := fmt.Sprintf("docker inspect %s", fmt.Sprintf("%s", otherArgs[0]))
stdout, _, err := cli.Exec(cmd, []string{})
stdout, _, err := cli.Exec(cmd, []string{}, false)
if err != nil {
return err
}
Expand All @@ -305,7 +305,7 @@ func writeAgentCtlInfo(cli Cli, w io.Writer, components []client.Component, args

cmd := fmt.Sprintf("agentctl --host %s --http-port %d --grpc-port=%d report -i -o %s",
host, httpPort, grpcPort, tempDirName)
_, _, err = cli.Exec(cmd, []string{})
_, _, err = cli.Exec(cmd, []string{}, false)
if err != nil {
return err
}
Expand Down Expand Up @@ -341,7 +341,7 @@ func writeAgentCtlInfo(cli Cli, w io.Writer, components []client.Component, args
func writeDockerLogs(cli Cli, w io.Writer, components []client.Component, args ...interface{}) error {
serviceName := args[0]
cmd := fmt.Sprintf("docker compose logs --no-color -n 10000 %s", serviceName)
stdout, stderr, err := cli.Exec(cmd, []string{})
stdout, stderr, err := cli.Exec(cmd, []string{}, false)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/swctl/app/cmd_trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func runTraceCmd(cli Cli, opts TraceCmdOptions) error {
// - consider selecting IP and source network namespace automatically
// - consider allowing users to simply select component names for ping src/dst

stdout, stderr, err := cli.Exec(fmt.Sprintf("vpp-probe --env=%s trace", defaultVppProbeEnv), args)
stdout, stderr, err := cli.Exec(fmt.Sprintf("vpp-probe --env=%s trace", defaultVppProbeEnv), args, false)
if err != nil {
return err
}
Expand Down
15 changes: 12 additions & 3 deletions cmd/swctl/app/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package app
import (
"bytes"
"fmt"
"io"
"os/exec"
"strings"
"syscall"
Expand Down Expand Up @@ -106,12 +107,20 @@ type ExecResult struct {
Stderr string
}

func (ec *externalCmd) exec() (*ExecResult, error) {
func (ec *externalCmd) exec(liveOutput bool) (*ExecResult, error) {
var stdout, stderr bytes.Buffer
cmd := exec.Command(ec.name, ec.args...)
if liveOutput {
stdoutMultiWriter := io.MultiWriter(&stdout, ec.cli.out)
stderrMultiWriter := io.MultiWriter(&stderr, ec.cli.err)
cmd.Stdout = stdoutMultiWriter
cmd.Stderr = stderrMultiWriter
} else {
cmd.Stdout = &stdout
cmd.Stderr = &stderr
}

cmd.Env = ec.env
cmd.Stdout = &stdout
cmd.Stderr = &stderr

now := time.Now()
logrus.Tracef("[%s] %q", color.Gray.Sprint("EXEC"), cmd.String())
Expand Down

0 comments on commit 19b0e5c

Please sign in to comment.