diff --git a/server/container_stop.go b/server/container_stop.go index 762c3d9a..1aba8801 100644 --- a/server/container_stop.go +++ b/server/container_stop.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/Sirupsen/logrus" + "github.com/kubernetes-incubator/cri-o/oci" "golang.org/x/net/context" pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" ) @@ -16,8 +17,14 @@ func (s *Server) StopContainer(ctx context.Context, req *pb.StopContainerRequest return nil, err } - if err := s.runtime.StopContainer(c); err != nil { - return nil, fmt.Errorf("failed to stop container %s: %v", c.ID(), err) + if err := s.runtime.UpdateStatus(c); err != nil { + return nil, err + } + cStatus := s.runtime.ContainerStatus(c) + if cStatus.Status != oci.ContainerStateStopped { + if err := s.runtime.StopContainer(c); err != nil { + return nil, fmt.Errorf("failed to stop container %s: %v", c.ID(), err) + } } resp := &pb.StopContainerResponse{} diff --git a/server/sandbox_stop.go b/server/sandbox_stop.go index 42dac4ca..9853b17c 100644 --- a/server/sandbox_stop.go +++ b/server/sandbox_stop.go @@ -34,6 +34,9 @@ func (s *Server) StopPodSandbox(ctx context.Context, req *pb.StopPodSandboxReque containers = append(containers, podInfraContainer) for _, c := range containers { + if err := s.runtime.UpdateStatus(c); err != nil { + return nil, err + } cStatus := s.runtime.ContainerStatus(c) if cStatus.Status != oci.ContainerStateStopped { if err := s.runtime.StopContainer(c); err != nil { diff --git a/test/ctr.bats b/test/ctr.bats index 51d17292..aa73da41 100644 --- a/test/ctr.bats +++ b/test/ctr.bats @@ -393,3 +393,33 @@ function teardown() { cleanup_pods stop_ocid } + +@test "ctr stop idempotent" { + # this test requires docker, thus it can't yet be run in a container + if [ "$TRAVIS" = "true" ]; then # instead of $TRAVIS, add a function is_containerized to skip here + skip "cannot yet run this test in a container, use sudo make localintegration" + fi + + start_ocid + run ocic pod create --config "$TESTDATA"/sandbox_config.json + echo "$output" + [ "$status" -eq 0 ] + pod_id="$output" + run ocic ctr create --config "$TESTDATA"/container_redis.json --pod "$pod_id" + echo "$output" + [ "$status" -eq 0 ] + ctr_id="$output" + run ocic ctr start --id "$ctr_id" + echo "$output" + [ "$status" -eq 0 ] + run ocic ctr stop --id "$ctr_id" + echo "$output" + [ "$status" -eq 0 ] + run ocic ctr stop --id "$ctr_id" + echo "$output" + [ "$status" -eq 0 ] + + cleanup_ctrs + cleanup_pods + stop_ocid +} diff --git a/test/pod.bats b/test/pod.bats index 56cfcc22..fc70b2aa 100644 --- a/test/pod.bats +++ b/test/pod.bats @@ -233,3 +233,53 @@ function teardown() { cleanup_pods stop_ocid } + +@test "pod stop idempotent" { + # this test requires docker, thus it can't yet be run in a container + if [ "$TRAVIS" = "true" ]; then # instead of $TRAVIS, add a function is_containerized to skip here + skip "cannot yet run this test in a container, use sudo make localintegration" + fi + + start_ocid + run ocic pod create --config "$TESTDATA"/sandbox_config.json + echo "$output" + [ "$status" -eq 0 ] + pod_id="$output" + run ocic pod stop --id "$pod_id" + echo "$output" + [ "$status" -eq 0 ] + run ocic pod stop --id "$pod_id" + echo "$output" + [ "$status" -eq 0 ] + + cleanup_ctrs + cleanup_pods + stop_ocid +} + +@test "pod stop idempotent with ctrs already stopped" { + # this test requires docker, thus it can't yet be run in a container + if [ "$TRAVIS" = "true" ]; then # instead of $TRAVIS, add a function is_containerized to skip here + skip "cannot yet run this test in a container, use sudo make localintegration" + fi + + start_ocid + run ocic pod create --config "$TESTDATA"/sandbox_config.json + echo "$output" + [ "$status" -eq 0 ] + pod_id="$output" + run ocic ctr create --config "$TESTDATA"/container_config.json --pod "$pod_id" + echo "$output" + [ "$status" -eq 0 ] + ctr_id="$output" + run ocic ctr start --id "$ctr_id" + echo "$output" + [ "$status" -eq 0 ] + run ocic pod stop --id "$pod_id" + echo "$output" + [ "$status" -eq 0 ] + + cleanup_ctrs + cleanup_pods + stop_ocid +}