2014-07-09 01:17:05 +08:00
|
|
|
package libcontainer
|
|
|
|
|
2015-02-23 17:26:43 +08:00
|
|
|
import (
|
2015-02-27 16:47:57 +08:00
|
|
|
"fmt"
|
2015-02-23 17:26:43 +08:00
|
|
|
"io"
|
2015-03-05 04:22:01 +08:00
|
|
|
"math"
|
2015-02-23 17:26:43 +08:00
|
|
|
"os"
|
|
|
|
)
|
|
|
|
|
|
|
|
type processOperations interface {
|
|
|
|
wait() (*os.ProcessState, error)
|
|
|
|
signal(sig os.Signal) error
|
|
|
|
pid() int
|
|
|
|
}
|
2014-07-09 01:17:05 +08:00
|
|
|
|
2015-02-04 09:44:58 +08:00
|
|
|
// Process specifies the configuration and IO for a process inside
|
|
|
|
// a container.
|
2015-02-01 12:51:12 +08:00
|
|
|
type Process struct {
|
2014-07-09 01:17:05 +08:00
|
|
|
// The command to be run followed by any arguments.
|
|
|
|
Args []string
|
2015-02-04 09:44:58 +08:00
|
|
|
|
2015-02-07 11:16:11 +08:00
|
|
|
// Env specifies the environment variables for the process.
|
|
|
|
Env []string
|
|
|
|
|
2015-02-10 05:11:57 +08:00
|
|
|
// User will set the uid and gid of the executing process running inside the container
|
2015-04-20 10:35:51 +08:00
|
|
|
// local to the container's user and group configuration.
|
2015-02-10 05:11:57 +08:00
|
|
|
User string
|
|
|
|
|
|
|
|
// Cwd will change the processes current working directory inside the container's rootfs.
|
|
|
|
Cwd string
|
|
|
|
|
2014-07-09 01:17:05 +08:00
|
|
|
// Stdin is a pointer to a reader which provides the standard input stream.
|
2015-02-04 09:44:58 +08:00
|
|
|
Stdin io.Reader
|
|
|
|
|
2014-07-09 01:17:05 +08:00
|
|
|
// Stdout is a pointer to a writer which receives the standard output stream.
|
2014-12-18 05:14:49 +08:00
|
|
|
Stdout io.Writer
|
2015-02-04 09:44:58 +08:00
|
|
|
|
|
|
|
// Stderr is a pointer to a writer which receives the standard error stream.
|
2014-12-18 05:14:49 +08:00
|
|
|
Stderr io.Writer
|
2015-02-23 17:26:43 +08:00
|
|
|
|
2015-04-01 05:40:05 +08:00
|
|
|
// ExtraFiles specifies additional open files to be inherited by the container
|
|
|
|
ExtraFiles []*os.File
|
|
|
|
|
2015-02-26 06:31:39 +08:00
|
|
|
// consolePath is the path to the console allocated to the container.
|
|
|
|
consolePath string
|
|
|
|
|
2015-03-26 03:39:34 +08:00
|
|
|
// Capabilities specify the capabilities to keep when executing the process inside the container
|
2015-04-20 10:35:51 +08:00
|
|
|
// All capabilities not specified will be dropped from the processes capability mask
|
2015-03-26 03:39:34 +08:00
|
|
|
Capabilities []string
|
|
|
|
|
2015-02-23 17:26:43 +08:00
|
|
|
ops processOperations
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait waits for the process to exit.
|
|
|
|
// Wait releases any resources associated with the Process
|
|
|
|
func (p Process) Wait() (*os.ProcessState, error) {
|
|
|
|
if p.ops == nil {
|
2016-01-21 01:16:12 +08:00
|
|
|
return nil, newGenericError(fmt.Errorf("invalid process"), NoProcessOps)
|
2015-02-23 17:26:43 +08:00
|
|
|
}
|
|
|
|
return p.ops.wait()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pid returns the process ID
|
|
|
|
func (p Process) Pid() (int, error) {
|
2015-03-05 04:22:01 +08:00
|
|
|
// math.MinInt32 is returned here, because it's invalid value
|
|
|
|
// for the kill() system call.
|
2015-02-23 17:26:43 +08:00
|
|
|
if p.ops == nil {
|
2016-01-21 01:16:12 +08:00
|
|
|
return math.MinInt32, newGenericError(fmt.Errorf("invalid process"), NoProcessOps)
|
2015-02-23 17:26:43 +08:00
|
|
|
}
|
|
|
|
return p.ops.pid(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Signal sends a signal to the Process.
|
|
|
|
func (p Process) Signal(sig os.Signal) error {
|
|
|
|
if p.ops == nil {
|
2016-01-21 01:16:12 +08:00
|
|
|
return newGenericError(fmt.Errorf("invalid process"), NoProcessOps)
|
2015-02-23 17:26:43 +08:00
|
|
|
}
|
|
|
|
return p.ops.signal(sig)
|
2014-07-09 01:17:05 +08:00
|
|
|
}
|
2015-02-26 06:31:39 +08:00
|
|
|
|
2015-12-11 07:46:26 +08:00
|
|
|
// IO holds the process's STDIO
|
|
|
|
type IO struct {
|
|
|
|
Stdin io.WriteCloser
|
|
|
|
Stdout io.ReadCloser
|
|
|
|
Stderr io.ReadCloser
|
|
|
|
}
|
|
|
|
|
2015-02-26 06:31:39 +08:00
|
|
|
// NewConsole creates new console for process and returns it
|
|
|
|
func (p *Process) NewConsole(rootuid int) (Console, error) {
|
2015-12-10 03:43:11 +08:00
|
|
|
console, err := NewConsole(rootuid, rootuid)
|
2015-02-26 06:31:39 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
p.consolePath = console.Path()
|
|
|
|
return console, nil
|
|
|
|
}
|
2015-12-10 03:43:11 +08:00
|
|
|
|
|
|
|
// ConsoleFromPath sets the process's console with the path provided
|
|
|
|
func (p *Process) ConsoleFromPath(path string) error {
|
|
|
|
if p.consolePath != "" {
|
|
|
|
return newGenericError(fmt.Errorf("console path already exists for process"), ConsoleExists)
|
|
|
|
}
|
|
|
|
p.consolePath = path
|
|
|
|
return nil
|
|
|
|
}
|