...

Source file src/github.com/Microsoft/hcsshim/pkg/go-runhcs/runhcs_exec.go

Documentation: github.com/Microsoft/hcsshim/pkg/go-runhcs

     1  //go:build windows
     2  
     3  package runhcs
     4  
     5  import (
     6  	"context"
     7  	"fmt"
     8  	"path/filepath"
     9  	"strings"
    10  
    11  	irunhcs "github.com/Microsoft/hcsshim/internal/runhcs"
    12  	"github.com/containerd/go-runc"
    13  )
    14  
    15  // ExecOpts is set of options that can be used with the Exec command.
    16  type ExecOpts struct {
    17  	runc.IO
    18  	// Detach from the container's process.
    19  	Detach bool
    20  	// PidFile is the path to the file to write the process id to.
    21  	PidFile string
    22  	// ShimLog is the path to the log file or named pipe (e.g. \\.\pipe\ProtectedPrefix\Administrators\runhcs-<container-id>-<exec-id>-log) for the launched shim process.
    23  	ShimLog string
    24  }
    25  
    26  func (opt *ExecOpts) args() ([]string, error) {
    27  	var out []string
    28  	if opt.Detach {
    29  		out = append(out, "--detach")
    30  	}
    31  	if opt.PidFile != "" {
    32  		abs, err := filepath.Abs(opt.PidFile)
    33  		if err != nil {
    34  			return nil, err
    35  		}
    36  		out = append(out, "--pid-file", abs)
    37  	}
    38  	if opt.ShimLog != "" {
    39  		if strings.HasPrefix(opt.ShimLog, irunhcs.SafePipePrefix) {
    40  			out = append(out, "--shim-log", opt.ShimLog)
    41  		} else {
    42  			abs, err := filepath.Abs(opt.ShimLog)
    43  			if err != nil {
    44  				return nil, err
    45  			}
    46  			out = append(out, "--shim-log", abs)
    47  		}
    48  	}
    49  	return out, nil
    50  }
    51  
    52  // Exec executes an additional process inside the container based on the
    53  // oci.Process spec found at processFile.
    54  func (r *Runhcs) Exec(context context.Context, id, processFile string, opts *ExecOpts) error {
    55  	args := []string{"exec", "--process", processFile}
    56  	if opts != nil {
    57  		oargs, err := opts.args()
    58  		if err != nil {
    59  			return err
    60  		}
    61  		args = append(args, oargs...)
    62  	}
    63  	cmd := r.command(context, append(args, id)...)
    64  	if opts != nil && opts.IO != nil {
    65  		opts.Set(cmd)
    66  	}
    67  	if cmd.Stdout == nil && cmd.Stderr == nil {
    68  		data, err := cmdOutput(cmd, true)
    69  		if err != nil {
    70  			return fmt.Errorf("%s: %s", err, data)
    71  		}
    72  		return nil
    73  	}
    74  	ec, err := runc.Monitor.Start(cmd)
    75  	if err != nil {
    76  		return err
    77  	}
    78  	if opts != nil && opts.IO != nil {
    79  		if c, ok := opts.IO.(runc.StartCloser); ok {
    80  			if err := c.CloseAfterStart(); err != nil {
    81  				return err
    82  			}
    83  		}
    84  	}
    85  	status, err := runc.Monitor.Wait(cmd, ec)
    86  	if err == nil && status != 0 {
    87  		err = fmt.Errorf("%s did not terminate successfully", cmd.Args[0])
    88  	}
    89  	return err
    90  }
    91  

View as plain text