server: honor container stop timeout from CRI
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
parent
20e9aeb16f
commit
b3683ab184
6 changed files with 29 additions and 21 deletions
|
@ -148,7 +148,7 @@ var stopContainerCommand = cli.Command{
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
client := pb.NewRuntimeServiceClient(conn)
|
client := pb.NewRuntimeServiceClient(conn)
|
||||||
|
|
||||||
err = StopContainer(client, context.String("id"))
|
err = StopContainer(client, context.String("id"), -1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Stopping the container failed: %v", err)
|
return fmt.Errorf("Stopping the container failed: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -402,12 +402,13 @@ func StartContainer(client pb.RuntimeServiceClient, ID string) error {
|
||||||
|
|
||||||
// StopContainer sends a StopContainerRequest to the server, and parses
|
// StopContainer sends a StopContainerRequest to the server, and parses
|
||||||
// the returned StopContainerResponse.
|
// the returned StopContainerResponse.
|
||||||
func StopContainer(client pb.RuntimeServiceClient, ID string) error {
|
func StopContainer(client pb.RuntimeServiceClient, ID string, timeout int64) error {
|
||||||
if ID == "" {
|
if ID == "" {
|
||||||
return fmt.Errorf("ID cannot be empty")
|
return fmt.Errorf("ID cannot be empty")
|
||||||
}
|
}
|
||||||
_, err := client.StopContainer(context.Background(), &pb.StopContainerRequest{
|
_, err := client.StopContainer(context.Background(), &pb.StopContainerRequest{
|
||||||
ContainerId: ID,
|
ContainerId: ID,
|
||||||
|
Timeout: timeout,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
37
oci/oci.go
37
oci/oci.go
|
@ -435,29 +435,36 @@ func (r *Runtime) ExecSync(c *Container, command []string, timeout int64) (resp
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// StopContainer stops a container.
|
// StopContainer stops a container. Timeout is given in seconds.
|
||||||
func (r *Runtime) StopContainer(c *Container) error {
|
func (r *Runtime) StopContainer(c *Container, timeout int64) error {
|
||||||
c.opLock.Lock()
|
c.opLock.Lock()
|
||||||
defer c.opLock.Unlock()
|
defer c.opLock.Unlock()
|
||||||
if err := utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, r.Path(c), "kill", c.name, "TERM"); err != nil {
|
if err := utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, r.Path(c), "kill", c.name, "TERM"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
i := 0
|
if timeout == -1 {
|
||||||
for {
|
// default 10 seconds delay
|
||||||
if i == 1000 {
|
timeout = 10
|
||||||
err := unix.Kill(c.state.Pid, syscall.SIGKILL)
|
}
|
||||||
if err != nil && err != syscall.ESRCH {
|
done := make(chan struct{})
|
||||||
return fmt.Errorf("failed to kill process: %v", err)
|
go func() {
|
||||||
|
for {
|
||||||
|
// Check if the process is still around
|
||||||
|
err := unix.Kill(c.state.Pid, 0)
|
||||||
|
if err == syscall.ESRCH {
|
||||||
|
close(done)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
break
|
|
||||||
}
|
}
|
||||||
// Check if the process is still around
|
}()
|
||||||
err := unix.Kill(c.state.Pid, 0)
|
select {
|
||||||
if err == syscall.ESRCH {
|
case <-done:
|
||||||
break
|
return nil
|
||||||
|
case <-time.After(time.Duration(timeout) * time.Second):
|
||||||
|
err := unix.Kill(c.state.Pid, syscall.SIGKILL)
|
||||||
|
if err != nil && err != syscall.ESRCH {
|
||||||
|
return fmt.Errorf("failed to kill process: %v", err)
|
||||||
}
|
}
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -24,7 +24,7 @@ func (s *Server) RemoveContainer(ctx context.Context, req *pb.RemoveContainerReq
|
||||||
|
|
||||||
cState := s.runtime.ContainerStatus(c)
|
cState := s.runtime.ContainerStatus(c)
|
||||||
if cState.Status == oci.ContainerStateCreated || cState.Status == oci.ContainerStateRunning {
|
if cState.Status == oci.ContainerStateCreated || cState.Status == oci.ContainerStateRunning {
|
||||||
if err := s.runtime.StopContainer(c); err != nil {
|
if err := s.runtime.StopContainer(c, -1); err != nil {
|
||||||
return nil, fmt.Errorf("failed to stop container %s: %v", c.ID(), err)
|
return nil, fmt.Errorf("failed to stop container %s: %v", c.ID(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ func (s *Server) StopContainer(ctx context.Context, req *pb.StopContainerRequest
|
||||||
}
|
}
|
||||||
cStatus := s.runtime.ContainerStatus(c)
|
cStatus := s.runtime.ContainerStatus(c)
|
||||||
if cStatus.Status != oci.ContainerStateStopped {
|
if cStatus.Status != oci.ContainerStateStopped {
|
||||||
if err := s.runtime.StopContainer(c); err != nil {
|
if err := s.runtime.StopContainer(c, req.Timeout); err != nil {
|
||||||
return nil, fmt.Errorf("failed to stop container %s: %v", c.ID(), err)
|
return nil, fmt.Errorf("failed to stop container %s: %v", c.ID(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ func (s *Server) RemovePodSandbox(ctx context.Context, req *pb.RemovePodSandboxR
|
||||||
|
|
||||||
cState := s.runtime.ContainerStatus(c)
|
cState := s.runtime.ContainerStatus(c)
|
||||||
if cState.Status == oci.ContainerStateCreated || cState.Status == oci.ContainerStateRunning {
|
if cState.Status == oci.ContainerStateCreated || cState.Status == oci.ContainerStateRunning {
|
||||||
if err := s.runtime.StopContainer(c); err != nil {
|
if err := s.runtime.StopContainer(c, -1); err != nil {
|
||||||
// Assume container is already stopped
|
// Assume container is already stopped
|
||||||
logrus.Warnf("failed to stop container %s: %v", c.Name(), err)
|
logrus.Warnf("failed to stop container %s: %v", c.Name(), err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func (s *Server) StopPodSandbox(ctx context.Context, req *pb.StopPodSandboxReque
|
||||||
}
|
}
|
||||||
cStatus := s.runtime.ContainerStatus(c)
|
cStatus := s.runtime.ContainerStatus(c)
|
||||||
if cStatus.Status != oci.ContainerStateStopped {
|
if cStatus.Status != oci.ContainerStateStopped {
|
||||||
if err := s.runtime.StopContainer(c); err != nil {
|
if err := s.runtime.StopContainer(c, -1); err != nil {
|
||||||
return nil, fmt.Errorf("failed to stop container %s in pod sandbox %s: %v", c.Name(), sb.id, err)
|
return nil, fmt.Errorf("failed to stop container %s in pod sandbox %s: %v", c.Name(), sb.id, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue