Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions daemon/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,15 @@ func (daemon *Daemon) StartExec(stdin io.ReadCloser, stdout io.WriteCloser, cont
glog.V(1).Infof("Start Exec for container %s", containerId)
return p.StartExec(stdin, stdout, id, execId)
}

func (daemon *Daemon) KillExec(containerId string, execId string, signal int64) error {
p, _, ok := daemon.PodList.GetByContainerIdOrName(containerId)
if !ok {
err := fmt.Errorf("cannot find container %s", containerId)
glog.Error(err)
return err
}

glog.V(1).Infof("Kill Exec for container %s", containerId)
return p.KillExec(execId, signal)
}
20 changes: 20 additions & 0 deletions daemon/pod/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"io"
"syscall"
"time"

"github.com/docker/docker/pkg/stdcopy"
Expand Down Expand Up @@ -173,6 +174,25 @@ func (p *XPod) GetExecExitCode(containerId, execId string) (uint8, error) {
return es.ExitCode, nil
}

func (p *XPod) KillExec(execId string, sig int64) error {
p.statusLock.RLock()
es, ok := p.execs[execId]
p.statusLock.RUnlock()

if !ok {
err := fmt.Errorf("no exec %s exists for pod %s", execId, p.Id)
p.Log(ERROR, err)
return err
}

return p.protectedSandboxOperation(
func(sb *hypervisor.Vm) error {
return sb.SignalProcess(es.Container, es.Id, syscall.Signal(sig))
},
time.Second*5,
fmt.Sprintf("Kill process %s with %d", es.Id, sig))
}

func (p *XPod) DeleteExec(containerId, execId string) {
p.statusLock.Lock()
delete(p.execs, execId)
Expand Down
15 changes: 15 additions & 0 deletions integration/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,21 @@ func (c *HyperClient) RemovePod(podID string) error {
return nil
}

// ContainerExecSignal sends signal to specified exec of specified container
func (c *HyperClient) ContainerExecSignal(container, execID string, sig int64) error {
req := types.ExecSignalRequest{
ContainerID: container,
ExecID: execID,
Signal: sig,
}
_, err := c.client.ExecSignal(c.ctx, &req)
if err != nil {
return err
}

return nil
}

// ContainerExecCreate creates exec in a container
func (c *HyperClient) ContainerExecCreate(container string, command []string, tty bool) (string, error) {
req := types.ExecCreateRequest{
Expand Down
63 changes: 63 additions & 0 deletions integration/hyper_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package integration

import (
"io"
"testing"

"github.com/hyperhq/hyperd/lib/promise"
"github.com/hyperhq/hyperd/types"
. "gopkg.in/check.v1"
)
Expand Down Expand Up @@ -529,3 +531,64 @@ func (s *TestSuite) TestSendContainerSignal(c *C) {
c.Assert(err, IsNil)
c.Assert(containerInfo.Status.Phase, Equals, "failed")
}

func (s *TestSuite) TestSendExecSignal(c *C) {
sigKill := int64(9)
cName := "test-exec-signal"
spec := types.UserPod{
Id: "busybox",
Containers: []*types.UserContainer{
{
Name: cName,
Image: "busybox",
},
},
}
podID, err := s.client.CreatePod(&spec)
c.Assert(err, IsNil)

defer func() {
err = s.client.RemovePod(podID)
c.Assert(err, IsNil)
}()

err = s.client.StartPod(podID)
c.Assert(err, IsNil)

execId, err := s.client.ContainerExecCreate(cName, []string{"sh", "-c", "top"}, false)
c.Assert(err, IsNil)

outReader, outWriter := io.Pipe()
errC := promise.Go(func() error {
return s.client.ContainerExecStart(cName, execId, nil, outWriter, nil, false)
})

// make sure process has been started.
readC := make(chan struct{})
go func() {
buf := make([]byte, 32)
for {
n, err := outReader.Read(buf)
if err == nil && n > 0 {
readC <- struct{}{}
break
} else if err != nil && err != io.EOF {
errC <- err
break
}
}
}()

select {
case err = <-errC:
c.Assert(err, IsNil)
case <-readC:
}

err = s.client.ContainerExecSignal(cName, execId, sigKill)
c.Assert(err, IsNil)

exitCode, err := s.client.Wait(cName, execId, false)
c.Assert(err, IsNil)
c.Assert(exitCode, Equals, int32(0))
}
13 changes: 13 additions & 0 deletions serverrpc/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,16 @@ func (s *ServerRPC) Wait(c context.Context, req *types.WaitRequest) (*types.Wait
ExitCode: int32(code),
}, nil
}

// ExecSignal sends a singal to specified exec of specified container
func (s *ServerRPC) ExecSignal(ctx context.Context, req *types.ExecSignalRequest) (*types.ExecSignalResponse, error) {
glog.V(3).Infof("ExecSignal with request %v", req.String())

err := s.daemon.KillExec(req.ContainerID, req.ExecID, req.Signal)
if err != nil {
glog.Errorf("Kill Process %s of container %s with signal %d failed: %v", req.ExecID, req.ContainerID, req.Signal, err)
return nil, err
}

return &types.ExecSignalResponse{}, nil
}
50 changes: 50 additions & 0 deletions types/types.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,14 @@ message ExecStartResponse{
bytes stdout = 1;
}

message ExecSignalRequest{
string containerID = 1;
string execID = 2;
int64 signal = 3;
}

message ExecSignalResponse{}

message PodStartRequest {
string podID = 1;
}
Expand Down Expand Up @@ -819,6 +827,8 @@ service PublicAPI {
rpc ExecCreate(ExecCreateRequest) returns (ExecCreateResponse) {}
// ExecStart starts exec
rpc ExecStart(stream ExecStartRequest) returns (stream ExecStartResponse) {}
// ExecSignal sends a signal to specified exec in specified container
rpc ExecSignal(ExecSignalRequest) returns (ExecSignalResponse) {}
// Attach attaches to the specified container
rpc Attach(stream AttachMessage) returns (stream AttachMessage) {}
// Wait gets the exit code of the specified container
Expand Down