1package cmd 2 3import ( 4 "context" 5 "errors" 6 "os/exec" 7 8 "github.com/Microsoft/hcsshim/internal/log" 9 "github.com/Microsoft/hcsshim/internal/logfields" 10 "github.com/Microsoft/hcsshim/internal/shimdiag" 11 "github.com/Microsoft/hcsshim/internal/uvm" 12 errorspkg "github.com/pkg/errors" 13) 14 15// ExecInUvm is a helper function used to execute commands specified in `req` inside the given UVM. 16func ExecInUvm(ctx context.Context, vm *uvm.UtilityVM, req *shimdiag.ExecProcessRequest) (int, error) { 17 if len(req.Args) == 0 { 18 return 0, errors.New("missing command") 19 } 20 np, err := NewNpipeIO(ctx, req.Stdin, req.Stdout, req.Stderr, req.Terminal) 21 if err != nil { 22 return 0, err 23 } 24 defer np.Close(ctx) 25 cmd := CommandContext(ctx, vm, req.Args[0], req.Args[1:]...) 26 if req.Workdir != "" { 27 cmd.Spec.Cwd = req.Workdir 28 } 29 if vm.OS() == "windows" { 30 cmd.Spec.User.Username = `NT AUTHORITY\SYSTEM` 31 } 32 cmd.Spec.Terminal = req.Terminal 33 cmd.Stdin = np.Stdin() 34 cmd.Stdout = np.Stdout() 35 cmd.Stderr = np.Stderr() 36 cmd.Log = log.G(ctx).WithField(logfields.UVMID, vm.ID()) 37 err = cmd.Run() 38 return cmd.ExitState.ExitCode(), err 39} 40 41// ExecInShimHost is a helper function used to execute commands specified in `req` in the shim's 42// hosting system. 43func ExecInShimHost(ctx context.Context, req *shimdiag.ExecProcessRequest) (int, error) { 44 if len(req.Args) == 0 { 45 return 0, errors.New("missing command") 46 } 47 cmdArgsWithoutName := []string{""} 48 if len(req.Args) > 1 { 49 cmdArgsWithoutName = req.Args[1:] 50 } 51 cmd := exec.Command(req.Args[0], cmdArgsWithoutName...) 52 output, err := cmd.CombinedOutput() 53 if err != nil { 54 if exiterr, ok := err.(*exec.ExitError); ok { 55 return exiterr.ExitCode(), errorspkg.Wrapf(exiterr, "command output: %v", string(output)) 56 } 57 return -1, errorspkg.Wrapf(err, "command output: %v", string(output)) 58 } 59 return 0, nil 60} 61