monitor: add shell escape feature

Debuggers like GDB support prefixing a command with an exclamation mark
"!" to pass the rest of the command to the shell. We can mimic this
functionality.

Additionally, we can enable shlex parsing easily by using the
google/shlex utility.

Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
Justin Chadwell
2023-01-31 15:04:20 +00:00
parent cb94298a02
commit 9952a12625

View File

@@ -2,8 +2,11 @@ package monitor
import (
"context"
"errors"
"fmt"
"io"
"os/exec"
"runtime"
"sort"
"strings"
"sync"
@@ -12,6 +15,7 @@ import (
"github.com/containerd/console"
controllerapi "github.com/docker/buildx/commands/controller/pb"
"github.com/docker/buildx/util/ioset"
"github.com/google/shlex"
"github.com/sirupsen/logrus"
"golang.org/x/term"
)
@@ -116,13 +120,30 @@ func RunMonitor(ctx context.Context, curRef string, options controllerapi.BuildO
}
return
}
args := strings.Fields(l) // TODO: use shlex
if strings.HasPrefix(l, "!") {
raw := defaultShell(runtime.GOOS)
raw = append(raw, l[1:])
cmd := exec.Command(raw[0], raw[1:]...)
// cmd.Stdin = stdin // TODO: support stdin
cmd.Stdout = stdout
cmd.Stderr = stderr
if err := cmd.Run(); err != nil && !errors.Is(err, &exec.ExitError{}) {
fmt.Fprintf(stdout, "command failed: %v\n", err)
}
continue
}
args, err := shlex.Split(l)
if err != nil {
fmt.Fprintf(stdout, "failed to parse command: %v", err)
continue
}
if len(args) == 0 {
continue
}
switch args[0] {
case "":
// nop
case "reload":
if curRef != "" {
if err := c.Disconnect(ctx, curRef); err != nil {
@@ -255,3 +276,10 @@ type nopCloser struct {
}
func (c nopCloser) Close() error { return nil }
func defaultShell(os string) []string {
if os == "windows" {
return []string{"cmd", "/S", "/C"}
}
return []string{"/bin/sh", "-c"}
}