add support to kill container process by pid

This adds support for signalling a container process by pid.

Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>

make Ps more extensible

Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>

ps: windows support

Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
This commit is contained in:
Evan Hazlett
2017-05-09 15:50:02 -04:00
parent fae11b6673
commit ef158f8b5e
14 changed files with 1523 additions and 145 deletions

View File

@@ -83,9 +83,10 @@ func (c *Container) Resume(ctx context.Context) error {
return err
}
func (c *Container) Kill(ctx context.Context, signal uint32, all bool) error {
func (c *Container) Kill(ctx context.Context, signal uint32, pid uint32, all bool) error {
_, err := c.shim.Kill(ctx, &shim.KillRequest{
Signal: signal,
Pid: pid,
All: all,
})
return err
@@ -105,12 +106,32 @@ func (c *Container) Exec(ctx context.Context, opts plugin.ExecOpts) (plugin.Proc
resp, err := c.shim.Exec(ctx, request)
if err != nil {
return nil, err
}
return &Process{
pid: int(resp.Pid),
c: c,
}, nil
}
func (c *Container) Ps(ctx context.Context) ([]uint32, error) {
resp, err := c.shim.Ps(ctx, &shim.PsRequest{
ID: c.id,
})
if err != nil {
return nil, err
}
pids := make([]uint32, 0, len(resp.Ps))
for _, ps := range resp.Ps {
pids = append(pids, ps.Pid)
}
return pids, nil
}
func (c *Container) Pty(ctx context.Context, pid uint32, size plugin.ConsoleSize) error {
_, err := c.shim.Pty(ctx, &shim.PtyRequest{
Pid: pid,

View File

@@ -82,6 +82,10 @@ func (c *client) Kill(ctx context.Context, in *shimapi.KillRequest, opts ...grpc
return c.s.Kill(ctx, in)
}
func (c *client) Ps(ctx context.Context, in *shimapi.PsRequest, opts ...grpc.CallOption) (*shimapi.PsResponse, error) {
return c.s.Ps(ctx, in)
}
func (c *client) Exit(ctx context.Context, in *shimapi.ExitRequest, opts ...grpc.CallOption) (*google_protobuf.Empty, error) {
// don't exit the calling process for the client
// but make sure we unmount the containers rootfs for this client

View File

@@ -225,16 +225,51 @@ func (s *Service) Kill(ctx context.Context, r *shimapi.KillRequest) (*google_pro
}
return empty, nil
}
proc, ok := s.processes[int(r.Pid)]
if !ok {
return nil, fmt.Errorf("process does not exist %d", r.Pid)
}
if err := proc.Signal(int(r.Signal)); err != nil {
pids, err := s.getContainerPids(ctx, s.initProcess.id)
if err != nil {
return nil, err
}
valid := false
for _, p := range pids {
if r.Pid == p {
valid = true
break
}
}
if !valid {
return nil, errors.Errorf("process %d does not exist in container", r.Pid)
}
if err := unix.Kill(int(r.Pid), syscall.Signal(r.Signal)); err != nil {
return nil, err
}
return empty, nil
}
func (s *Service) Ps(ctx context.Context, r *shimapi.PsRequest) (*shimapi.PsResponse, error) {
pids, err := s.getContainerPids(ctx, r.ID)
if err != nil {
return nil, err
}
ps := []*shimapi.Ps{}
for _, pid := range pids {
ps = append(ps, &shimapi.Ps{
Pid: pid,
})
}
resp := &shimapi.PsResponse{
Ps: ps,
}
return resp, nil
}
func (s *Service) CloseStdin(ctx context.Context, r *shimapi.CloseStdinRequest) (*google_protobuf.Empty, error) {
p, ok := s.processes[int(r.Pid)]
if !ok {
@@ -257,3 +292,17 @@ func (s *Service) waitExit(p process, pid int, cmd *reaper.Cmd) {
ExitedAt: p.ExitedAt(),
}
}
func (s *Service) getContainerPids(ctx context.Context, id string) ([]uint32, error) {
p, err := s.initProcess.runc.Ps(ctx, id)
if err != nil {
return nil, err
}
pids := make([]uint32, 0, len(p))
for _, pid := range p {
pids = append(pids, uint32(pid))
}
return pids, nil
}