github.com/opencontainers/runc@v1.2.0-rc.1.0.20240520010911-492dc558cdd6/libcontainer/process.go (about)

     1  package libcontainer
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	"math"
     7  	"os"
     8  
     9  	"github.com/opencontainers/runc/libcontainer/configs"
    10  )
    11  
    12  var errInvalidProcess = errors.New("invalid process")
    13  
    14  type processOperations interface {
    15  	wait() (*os.ProcessState, error)
    16  	signal(sig os.Signal) error
    17  	pid() int
    18  }
    19  
    20  // Process specifies the configuration and IO for a process inside
    21  // a container.
    22  type Process struct {
    23  	// The command to be run followed by any arguments.
    24  	Args []string
    25  
    26  	// Env specifies the environment variables for the process.
    27  	Env []string
    28  
    29  	// User will set the uid and gid of the executing process running inside the container
    30  	// local to the container's user and group configuration.
    31  	User string
    32  
    33  	// AdditionalGroups specifies the gids that should be added to supplementary groups
    34  	// in addition to those that the user belongs to.
    35  	AdditionalGroups []string
    36  
    37  	// Cwd will change the processes current working directory inside the container's rootfs.
    38  	Cwd string
    39  
    40  	// Stdin is a pointer to a reader which provides the standard input stream.
    41  	Stdin io.Reader
    42  
    43  	// Stdout is a pointer to a writer which receives the standard output stream.
    44  	Stdout io.Writer
    45  
    46  	// Stderr is a pointer to a writer which receives the standard error stream.
    47  	Stderr io.Writer
    48  
    49  	// ExtraFiles specifies additional open files to be inherited by the container
    50  	ExtraFiles []*os.File
    51  
    52  	// open handles to cloned binaries -- see dmz.ClonedBinary for more details
    53  	clonedExes []*os.File
    54  
    55  	// Initial sizings for the console
    56  	ConsoleWidth  uint16
    57  	ConsoleHeight uint16
    58  
    59  	// Capabilities specify the capabilities to keep when executing the process inside the container
    60  	// All capabilities not specified will be dropped from the processes capability mask
    61  	Capabilities *configs.Capabilities
    62  
    63  	// AppArmorProfile specifies the profile to apply to the process and is
    64  	// changed at the time the process is execed
    65  	AppArmorProfile string
    66  
    67  	// Label specifies the label to apply to the process.  It is commonly used by selinux
    68  	Label string
    69  
    70  	// NoNewPrivileges controls whether processes can gain additional privileges.
    71  	NoNewPrivileges *bool
    72  
    73  	// Rlimits specifies the resource limits, such as max open files, to set in the container
    74  	// If Rlimits are not set, the container will inherit rlimits from the parent process
    75  	Rlimits []configs.Rlimit
    76  
    77  	// ConsoleSocket provides the masterfd console.
    78  	ConsoleSocket *os.File
    79  
    80  	// PidfdSocket provides process file descriptor of it own.
    81  	PidfdSocket *os.File
    82  
    83  	// Init specifies whether the process is the first process in the container.
    84  	Init bool
    85  
    86  	ops processOperations
    87  
    88  	// LogLevel is a string containing a numeric representation of the current
    89  	// log level (i.e. "4", but never "info"). It is passed on to runc init as
    90  	// _LIBCONTAINER_LOGLEVEL environment variable.
    91  	LogLevel string
    92  
    93  	// SubCgroupPaths specifies sub-cgroups to run the process in.
    94  	// Map keys are controller names, map values are paths (relative to
    95  	// container's top-level cgroup).
    96  	//
    97  	// If empty, the default top-level container's cgroup is used.
    98  	//
    99  	// For cgroup v2, the only key allowed is "".
   100  	SubCgroupPaths map[string]string
   101  
   102  	Scheduler *configs.Scheduler
   103  
   104  	IOPriority *configs.IOPriority
   105  }
   106  
   107  // Wait waits for the process to exit.
   108  // Wait releases any resources associated with the Process
   109  func (p Process) Wait() (*os.ProcessState, error) {
   110  	if p.ops == nil {
   111  		return nil, errInvalidProcess
   112  	}
   113  	return p.ops.wait()
   114  }
   115  
   116  // Pid returns the process ID
   117  func (p Process) Pid() (int, error) {
   118  	// math.MinInt32 is returned here, because it's invalid value
   119  	// for the kill() system call.
   120  	if p.ops == nil {
   121  		return math.MinInt32, errInvalidProcess
   122  	}
   123  	return p.ops.pid(), nil
   124  }
   125  
   126  // Signal sends a signal to the Process.
   127  func (p Process) Signal(sig os.Signal) error {
   128  	if p.ops == nil {
   129  		return errInvalidProcess
   130  	}
   131  	return p.ops.signal(sig)
   132  }
   133  
   134  // closeClonedExes cleans up any existing cloned binaries associated with the
   135  // Process.
   136  func (p *Process) closeClonedExes() {
   137  	for _, exe := range p.clonedExes {
   138  		_ = exe.Close()
   139  	}
   140  	p.clonedExes = nil
   141  }
   142  
   143  // IO holds the process's STDIO
   144  type IO struct {
   145  	Stdin  io.WriteCloser
   146  	Stdout io.ReadCloser
   147  	Stderr io.ReadCloser
   148  }