Move fifo creation to client
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
f5fdc548e8
commit
36eb83cb99
14 changed files with 305 additions and 313 deletions
|
@ -19,9 +19,9 @@ type Container interface {
|
|||
// Path returns the path to the bundle
|
||||
Path() string
|
||||
// Start starts the init process of the container
|
||||
Start(checkpoint string) (Process, error)
|
||||
Start(checkpoint string, s Stdio) (Process, error)
|
||||
// Exec starts another process in an existing container
|
||||
Exec(string, specs.Process) (Process, error)
|
||||
Exec(string, specs.Process, Stdio) (Process, error)
|
||||
// Delete removes the container's state and any resources
|
||||
Delete() error
|
||||
// Processes returns all the containers processes that have been added
|
||||
|
@ -45,6 +45,12 @@ type Container interface {
|
|||
// OOM() (<-chan struct{}, error)
|
||||
}
|
||||
|
||||
type Stdio struct {
|
||||
Stdin string
|
||||
Stdout string
|
||||
Stderr string
|
||||
}
|
||||
|
||||
// New returns a new container
|
||||
func New(root, id, bundle string) (Container, error) {
|
||||
c := &container{
|
||||
|
@ -94,11 +100,11 @@ func Load(root, id string) (Container, error) {
|
|||
continue
|
||||
}
|
||||
pid := d.Name()
|
||||
s, err := readProcessSpec(filepath.Join(root, id, pid))
|
||||
s, err := readProcessState(filepath.Join(root, id, pid))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p, err := loadProcess(filepath.Join(root, id, pid), pid, c, *s)
|
||||
p, err := loadProcess(filepath.Join(root, id, pid), pid, c, s)
|
||||
if err != nil {
|
||||
logrus.WithField("id", id).WithField("pid", pid).Debug("containerd: error loading process %s", err)
|
||||
continue
|
||||
|
@ -108,13 +114,13 @@ func Load(root, id string) (Container, error) {
|
|||
return c, nil
|
||||
}
|
||||
|
||||
func readProcessSpec(dir string) (*specs.Process, error) {
|
||||
func readProcessState(dir string) (*ProcessState, error) {
|
||||
f, err := os.Open(filepath.Join(dir, "process.json"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
var s specs.Process
|
||||
var s ProcessState
|
||||
if err := json.NewDecoder(f).Decode(&s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -127,6 +133,7 @@ type container struct {
|
|||
id string
|
||||
bundle string
|
||||
processes map[string]*process
|
||||
stdio Stdio
|
||||
}
|
||||
|
||||
func (c *container) ID() string {
|
||||
|
@ -137,12 +144,15 @@ func (c *container) Path() string {
|
|||
return c.bundle
|
||||
}
|
||||
|
||||
func (c *container) Start(checkpoint string) (Process, error) {
|
||||
func (c *container) Start(checkpoint string, s Stdio) (Process, error) {
|
||||
processRoot := filepath.Join(c.root, c.id, InitProcessID)
|
||||
if err := os.MkdirAll(processRoot, 0755); err != nil {
|
||||
if err := os.Mkdir(processRoot, 0755); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := exec.Command("containerd-shim", "-checkpoint", checkpoint, c.id, c.bundle)
|
||||
cmd := exec.Command("containerd-shim",
|
||||
"-checkpoint", checkpoint,
|
||||
c.id, c.bundle,
|
||||
)
|
||||
cmd.Dir = processRoot
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
Setpgid: true,
|
||||
|
@ -151,7 +161,7 @@ func (c *container) Start(checkpoint string) (Process, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p, err := newProcess(processRoot, InitProcessID, c, spec.Process)
|
||||
p, err := newProcess(processRoot, InitProcessID, c, spec.Process, s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -165,17 +175,20 @@ func (c *container) Start(checkpoint string) (Process, error) {
|
|||
return p, nil
|
||||
}
|
||||
|
||||
func (c *container) Exec(pid string, spec specs.Process) (Process, error) {
|
||||
func (c *container) Exec(pid string, spec specs.Process, s Stdio) (Process, error) {
|
||||
processRoot := filepath.Join(c.root, c.id, pid)
|
||||
if err := os.MkdirAll(processRoot, 0755); err != nil {
|
||||
if err := os.Mkdir(processRoot, 0755); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := exec.Command("containerd-shim", "-exec", c.id, c.bundle)
|
||||
cmd := exec.Command("containerd-shim",
|
||||
"-exec",
|
||||
c.id, c.bundle,
|
||||
)
|
||||
cmd.Dir = processRoot
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
Setpgid: true,
|
||||
}
|
||||
p, err := newProcess(processRoot, pid, c, spec)
|
||||
p, err := newProcess(processRoot, pid, c, spec, s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -228,7 +241,7 @@ func (c *container) Processes() ([]Process, error) {
|
|||
|
||||
func (c *container) RemoveProcess(pid string) error {
|
||||
delete(c.processes, pid)
|
||||
return nil
|
||||
return os.RemoveAll(filepath.Join(c.root, c.id, pid))
|
||||
}
|
||||
|
||||
func (c *container) Checkpoints() ([]Checkpoint, error) {
|
||||
|
|
|
@ -21,19 +21,14 @@ type Process interface {
|
|||
// This is either "init" when it is the container's init process or
|
||||
// it is a user provided id for the process similar to the container id
|
||||
ID() string
|
||||
// Stdin returns the path the the processes stdin fifo
|
||||
Stdin() string
|
||||
CloseStdin() error
|
||||
Resize(int, int) error
|
||||
// Stdout returns the path the the processes stdout fifo
|
||||
Stdout() string
|
||||
// Stderr returns the path the the processes stderr fifo
|
||||
Stderr() string
|
||||
// ExitFD returns the fd the provides an event when the process exits
|
||||
ExitFD() int
|
||||
// ExitStatus returns the exit status of the process or an error if it
|
||||
// has not exited
|
||||
ExitStatus() (int, error)
|
||||
// Spec returns the process spec that created the process
|
||||
Spec() specs.Process
|
||||
// Signal sends the provided signal to the process
|
||||
Signal(os.Signal) error
|
||||
|
@ -41,33 +36,27 @@ type Process interface {
|
|||
Container() Container
|
||||
}
|
||||
|
||||
func newProcess(root, id string, c *container, s specs.Process) (*process, error) {
|
||||
func newProcess(root, id string, c *container, s specs.Process, stdio Stdio) (*process, error) {
|
||||
p := &process{
|
||||
root: root,
|
||||
id: id,
|
||||
container: c,
|
||||
spec: s,
|
||||
stdio: stdio,
|
||||
}
|
||||
f, err := os.Create(filepath.Join(root, "process.json"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
if err := json.NewEncoder(f).Encode(s); err != nil {
|
||||
if err := json.NewEncoder(f).Encode(ProcessState{
|
||||
Process: s,
|
||||
Stdin: stdio.Stdin,
|
||||
Stdout: stdio.Stdout,
|
||||
Stderr: stdio.Stderr,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// create fifo's for the process
|
||||
for name, fd := range map[string]*string{
|
||||
"stdin": &p.stdin,
|
||||
"stdout": &p.stdout,
|
||||
"stderr": &p.stderr,
|
||||
} {
|
||||
path := filepath.Join(root, name)
|
||||
if err := syscall.Mkfifo(path, 0755); err != nil && !os.IsExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
*fd = path
|
||||
}
|
||||
exit, err := getExitPipe(filepath.Join(root, ExitFile))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -81,15 +70,17 @@ func newProcess(root, id string, c *container, s specs.Process) (*process, error
|
|||
return p, nil
|
||||
}
|
||||
|
||||
func loadProcess(root, id string, c *container, s specs.Process) (*process, error) {
|
||||
func loadProcess(root, id string, c *container, s *ProcessState) (*process, error) {
|
||||
p := &process{
|
||||
root: root,
|
||||
id: id,
|
||||
container: c,
|
||||
spec: s,
|
||||
stdin: filepath.Join(root, "stdin"),
|
||||
stdout: filepath.Join(root, "stdout"),
|
||||
stderr: filepath.Join(root, "stderr"),
|
||||
spec: s.Process,
|
||||
stdio: Stdio{
|
||||
Stdin: s.Stdin,
|
||||
Stdout: s.Stdout,
|
||||
Stderr: s.Stderr,
|
||||
},
|
||||
}
|
||||
if _, err := p.ExitStatus(); err != nil {
|
||||
if err == ErrProcessNotExited {
|
||||
|
@ -122,18 +113,14 @@ func getControlPipe(path string) (*os.File, error) {
|
|||
}
|
||||
|
||||
type process struct {
|
||||
root string
|
||||
id string
|
||||
pid int
|
||||
// stdio fifos
|
||||
stdin string
|
||||
stdout string
|
||||
stderr string
|
||||
|
||||
root string
|
||||
id string
|
||||
pid int
|
||||
exitPipe *os.File
|
||||
controlPipe *os.File
|
||||
container *container
|
||||
spec specs.Process
|
||||
stdio Stdio
|
||||
}
|
||||
|
||||
func (p *process) ID() string {
|
||||
|
@ -182,18 +169,6 @@ func (p *process) Spec() specs.Process {
|
|||
return p.spec
|
||||
}
|
||||
|
||||
func (p *process) Stdin() string {
|
||||
return p.stdin
|
||||
}
|
||||
|
||||
func (p *process) Stdout() string {
|
||||
return p.stdout
|
||||
}
|
||||
|
||||
func (p *process) Stderr() string {
|
||||
return p.stderr
|
||||
}
|
||||
|
||||
// Close closes any open files and/or resouces on the process
|
||||
func (p *process) Close() error {
|
||||
return p.exitPipe.Close()
|
||||
|
|
|
@ -3,6 +3,8 @@ package runtime
|
|||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/opencontainers/specs"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -35,6 +37,16 @@ const (
|
|||
|
||||
type state struct {
|
||||
Bundle string `json:"bundle"`
|
||||
Stdin string `json:"stdin"`
|
||||
Stdout string `json:"stdout"`
|
||||
Stderr string `json:"stderr"`
|
||||
}
|
||||
|
||||
type ProcessState struct {
|
||||
specs.Process
|
||||
Stdin string `json:"containerdStdin"`
|
||||
Stdout string `json:"containerdStdout"`
|
||||
Stderr string `json:"containerdStderr"`
|
||||
}
|
||||
|
||||
type Stat struct {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue