Add state rpc to shim
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
ead53658cc
commit
f431bf4ad4
7 changed files with 856 additions and 189 deletions
29
shim/exec.go
29
shim/exec.go
|
@ -16,7 +16,7 @@ import (
|
|||
type execProcess struct {
|
||||
sync.WaitGroup
|
||||
|
||||
id string
|
||||
id int
|
||||
console console.Console
|
||||
io runc.IO
|
||||
status int
|
||||
|
@ -25,19 +25,19 @@ type execProcess struct {
|
|||
parent *initProcess
|
||||
}
|
||||
|
||||
func newExecProcess(context context.Context, r *apishim.ExecRequest, parent *initProcess) (process, error) {
|
||||
func newExecProcess(context context.Context, r *apishim.ExecRequest, parent *initProcess, id int) (process, error) {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
e := &execProcess{
|
||||
id: r.ID,
|
||||
id: id,
|
||||
parent: parent,
|
||||
}
|
||||
var (
|
||||
socket *runc.ConsoleSocket
|
||||
io runc.IO
|
||||
pidfile = filepath.Join(cwd, fmt.Sprintf("%s.pid", r.ID))
|
||||
pidfile = filepath.Join(cwd, fmt.Sprintf("%d.pid", id))
|
||||
)
|
||||
if r.Terminal {
|
||||
if socket, err = runc.NewConsoleSocket(filepath.Join(cwd, "pty.sock")); err != nil {
|
||||
|
@ -56,9 +56,8 @@ func newExecProcess(context context.Context, r *apishim.ExecRequest, parent *ini
|
|||
ConsoleSocket: socket,
|
||||
IO: io,
|
||||
Detach: true,
|
||||
Tty: socket != nil,
|
||||
}
|
||||
if err := parent.runc.Exec(context, r.ID, processFromRequest(r), opts); err != nil {
|
||||
if err := parent.runc.Exec(context, parent.id, processFromRequest(r), opts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pid, err := runc.ReadPidFile(opts.PidFile)
|
||||
|
@ -70,13 +69,15 @@ func newExecProcess(context context.Context, r *apishim.ExecRequest, parent *ini
|
|||
}
|
||||
|
||||
func processFromRequest(r *apishim.ExecRequest) specs.Process {
|
||||
var user specs.User
|
||||
if r.User != nil {
|
||||
user.UID = r.User.Uid
|
||||
user.GID = r.User.Gid
|
||||
user.AdditionalGids = r.User.AdditionalGids
|
||||
}
|
||||
return specs.Process{
|
||||
Terminal: r.Terminal,
|
||||
User: specs.User{
|
||||
UID: r.User.Uid,
|
||||
GID: r.User.Gid,
|
||||
AdditionalGids: r.User.AdditionalGids,
|
||||
},
|
||||
Terminal: r.Terminal,
|
||||
User: user,
|
||||
Rlimits: rlimits(r.Rlimits),
|
||||
Args: r.Args,
|
||||
Env: r.Env,
|
||||
|
@ -115,6 +116,10 @@ func (e *execProcess) Exited(status int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (e *execProcess) Delete(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *execProcess) Resize(ws console.WinSize) error {
|
||||
if e.console == nil {
|
||||
return nil
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package shim
|
||||
|
||||
import "github.com/crosbymichael/console"
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/crosbymichael/console"
|
||||
)
|
||||
|
||||
type process interface {
|
||||
// Pid returns the pid for the process
|
||||
|
@ -11,4 +15,5 @@ type process interface {
|
|||
Exited(status int)
|
||||
// Status returns the exit status
|
||||
Status() int
|
||||
Delete(context.Context) error
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package shim
|
|||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"github.com/crosbymichael/console"
|
||||
apishim "github.com/docker/containerd/api/shim"
|
||||
|
@ -27,6 +28,7 @@ type Service struct {
|
|||
mu sync.Mutex
|
||||
processes map[int]process
|
||||
events chan *apishim.Event
|
||||
execID int
|
||||
}
|
||||
|
||||
func (s *Service) Create(ctx context.Context, r *apishim.CreateRequest) (*apishim.CreateResponse, error) {
|
||||
|
@ -63,21 +65,28 @@ func (s *Service) Start(ctx context.Context, r *apishim.StartRequest) (*google_p
|
|||
}
|
||||
|
||||
func (s *Service) Delete(ctx context.Context, r *apishim.DeleteRequest) (*apishim.DeleteResponse, error) {
|
||||
if err := s.initProcess.Delete(ctx); err != nil {
|
||||
s.mu.Lock()
|
||||
p, ok := s.processes[int(r.Pid)]
|
||||
s.mu.Unlock()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("process does not exist %d", r.Pid)
|
||||
}
|
||||
if err := p.Delete(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.mu.Lock()
|
||||
delete(s.processes, s.initProcess.pid)
|
||||
delete(s.processes, p.Pid())
|
||||
s.mu.Unlock()
|
||||
return &apishim.DeleteResponse{
|
||||
ExitStatus: uint32(s.initProcess.Status()),
|
||||
ExitStatus: uint32(p.Status()),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Service) Exec(ctx context.Context, r *apishim.ExecRequest) (*apishim.ExecResponse, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
process, err := newExecProcess(ctx, r, s.initProcess)
|
||||
s.execID++
|
||||
process, err := newExecProcess(ctx, r, s.initProcess, s.execID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -122,6 +131,29 @@ func (s *Service) Events(r *apishim.EventsRequest, stream apishim.Shim_EventsSer
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) State(ctx context.Context, r *apishim.StateRequest) (*apishim.StateResponse, error) {
|
||||
o := &apishim.StateResponse{
|
||||
ID: s.id,
|
||||
Processes: []*apishim.Process{},
|
||||
}
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
for _, p := range s.processes {
|
||||
state := apishim.State_RUNNING
|
||||
if err := syscall.Kill(p.Pid(), 0); err != nil {
|
||||
if err != syscall.ESRCH {
|
||||
return nil, err
|
||||
}
|
||||
state = apishim.State_STOPPED
|
||||
}
|
||||
o.Processes = append(o.Processes, &apishim.Process{
|
||||
Pid: uint32(p.Pid()),
|
||||
State: state,
|
||||
})
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func (s *Service) ProcessExit(e utils.Exit) error {
|
||||
s.mu.Lock()
|
||||
if p, ok := s.processes[e.Pid]; ok {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue