Add shim for reattach of processes
Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Remove runtime files from containerd Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Update supervisor for orphaned containers Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Remove ctr/container.go back to rpc calls Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Add attach to loaded container Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Add monitor based on epoll for process exits Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Convert pids in containerd to string This is so that we no longer care about linux or system level pids and processes in containerd have user defined process id(pid) kinda like the exec process ids that docker has today. Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Add reaper back to containerd Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Implement list containers with new process model Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Implement restore of processes Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Add NONBLOCK to exit fifo open Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Implement tty reattach Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Fix race in exit pipe creation Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Add delete to shim Signed-off-by: Michael Crosby <crosbymichael@gmail.com> Update shim to use pid-file and not stdout Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
8d1f71c3d7
commit
fe38efda50
33 changed files with 1210 additions and 1836 deletions
141
runtime/process.go
Normal file
141
runtime/process.go
Normal file
|
@ -0,0 +1,141 @@
|
|||
package runtime
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"syscall"
|
||||
|
||||
"github.com/opencontainers/specs"
|
||||
)
|
||||
|
||||
func newProcess(root, id string, c *container, s specs.Process) (*process, error) {
|
||||
p := &process{
|
||||
root: root,
|
||||
id: id,
|
||||
container: c,
|
||||
spec: s,
|
||||
}
|
||||
// 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
|
||||
}
|
||||
p.exitPipe = exit
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func loadProcess(root, id string, c *container, s specs.Process) (*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"),
|
||||
}
|
||||
if _, err := p.ExitStatus(); err != nil {
|
||||
if err == ErrProcessNotExited {
|
||||
exit, err := getExitPipe(filepath.Join(root, ExitFile))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.exitPipe = exit
|
||||
return p, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return nil, ErrProcessExited
|
||||
}
|
||||
|
||||
func getExitPipe(path string) (*os.File, error) {
|
||||
if err := syscall.Mkfifo(path, 0755); err != nil && !os.IsExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
// add NONBLOCK in case the other side has already closed or else
|
||||
// this function would never return
|
||||
return os.OpenFile(path, syscall.O_RDONLY|syscall.O_NONBLOCK, 0)
|
||||
}
|
||||
|
||||
type process struct {
|
||||
root string
|
||||
id string
|
||||
// stdio fifos
|
||||
stdin string
|
||||
stdout string
|
||||
stderr string
|
||||
|
||||
exitPipe *os.File
|
||||
container *container
|
||||
spec specs.Process
|
||||
}
|
||||
|
||||
func (p *process) ID() string {
|
||||
return p.id
|
||||
}
|
||||
|
||||
func (p *process) Container() Container {
|
||||
return p.container
|
||||
}
|
||||
|
||||
// ExitFD returns the fd of the exit pipe
|
||||
func (p *process) ExitFD() int {
|
||||
return int(p.exitPipe.Fd())
|
||||
}
|
||||
|
||||
func (p *process) ExitStatus() (int, error) {
|
||||
data, err := ioutil.ReadFile(filepath.Join(p.root, ExitStatusFile))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return -1, ErrProcessNotExited
|
||||
}
|
||||
return -1, err
|
||||
}
|
||||
if len(data) == 0 {
|
||||
return -1, ErrProcessNotExited
|
||||
}
|
||||
i, err := strconv.Atoi(string(data))
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// Signal sends the provided signal to the process
|
||||
func (p *process) Signal(s os.Signal) error {
|
||||
return errNotImplemented
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue