diff --git a/pkg/cri/sbserver/restart.go b/pkg/cri/sbserver/restart.go index 547dd1093..46d14d377 100644 --- a/pkg/cri/sbserver/restart.go +++ b/pkg/cri/sbserver/restart.go @@ -30,6 +30,7 @@ import ( "github.com/containerd/containerd/errdefs" containerdimages "github.com/containerd/containerd/images" "github.com/containerd/containerd/log" + criconfig "github.com/containerd/containerd/pkg/cri/config" "github.com/containerd/containerd/pkg/cri/sbserver/podsandbox" "github.com/containerd/containerd/platforms" "github.com/containerd/typeurl" @@ -92,14 +93,39 @@ func (c *criService) recover(ctx context.Context) error { if _, err := c.sandboxStore.Get(sbx.ID); err == nil { continue } + metadata := sandboxstore.Metadata{} err := sbx.GetExtension(podsandbox.MetadataKey, &metadata) if err != nil { return fmt.Errorf("failed to get metadata for stored sandbox %q: %w", sbx.ID, err) } - sb := sandboxstore.NewSandbox(metadata, sandboxstore.Status{State: sandboxstore.StateUnknown}) + + var ( + state = sandboxstore.StateUnknown + controller = c.sandboxControllers[criconfig.ModeShim] + ) + + status, err := controller.Status(ctx, sbx.ID, false) + if err != nil { + log.G(ctx).WithError(err).Error("failed to recover sandbox state") + if errdefs.IsNotFound(err) { + state = sandboxstore.StateNotReady + } + } else { + if code, ok := runtime.PodSandboxState_value[status.State]; ok { + if code == int32(runtime.PodSandboxState_SANDBOX_READY) { + state = sandboxstore.StateReady + } else if code == int32(runtime.PodSandboxState_SANDBOX_NOTREADY) { + state = sandboxstore.StateNotReady + } + } + } + + sb := sandboxstore.NewSandbox(metadata, sandboxstore.Status{State: state}) + // Load network namespace. sb.NetNS = getNetNS(&metadata) + if err := c.sandboxStore.Add(sb); err != nil { return fmt.Errorf("failed to add stored sandbox %q to store: %w", sbx.ID, err) } @@ -467,6 +493,9 @@ func getNetNS(meta *sandboxstore.Metadata) *netns.NetNS { if goruntime.GOOS == "windows" && meta.Config.GetWindows().GetSecurityContext().GetHostProcess() { return nil } + if goruntime.GOOS == "darwin" { + return nil + } return netns.LoadNetNS(meta.NetNSPath) } diff --git a/pkg/cri/sbserver/sandbox_remove.go b/pkg/cri/sbserver/sandbox_remove.go index 78c884f14..2635643a4 100644 --- a/pkg/cri/sbserver/sandbox_remove.go +++ b/pkg/cri/sbserver/sandbox_remove.go @@ -85,7 +85,8 @@ func (c *criService) RemovePodSandbox(ctx context.Context, r *runtime.RemovePodS if err != nil { return nil, fmt.Errorf("failed to get sandbox controller: %w", err) } - if _, err := controller.Delete(ctx, id); err != nil { + + if _, err := controller.Delete(ctx, id); err != nil && !errdefs.IsNotFound(err) { return nil, fmt.Errorf("failed to delete sandbox %q: %w", id, err) } diff --git a/pkg/cri/sbserver/sandbox_status.go b/pkg/cri/sbserver/sandbox_status.go index e56c4cf59..19ee5bf84 100644 --- a/pkg/cri/sbserver/sandbox_status.go +++ b/pkg/cri/sbserver/sandbox_status.go @@ -43,7 +43,7 @@ func (c *criService) PodSandboxStatus(ctx context.Context, r *runtime.PodSandbox return nil, fmt.Errorf("failed to get sandbox controller: %w", err) } - statusResponse, err := controller.Status(ctx, r.GetPodSandboxId(), r.GetVerbose()) + statusResponse, err := controller.Status(ctx, sandbox.ID, r.GetVerbose()) if err != nil { return nil, fmt.Errorf("failed to query controller status: %w", err) } diff --git a/pkg/cri/sbserver/sandbox_stop.go b/pkg/cri/sbserver/sandbox_stop.go index 5e2d76b35..754b9a8f7 100644 --- a/pkg/cri/sbserver/sandbox_stop.go +++ b/pkg/cri/sbserver/sandbox_stop.go @@ -64,13 +64,18 @@ func (c *criService) stopPodSandbox(ctx context.Context, sandbox sandboxstore.Sa } } - // Use sandbox controller to stop sandbox - controller, err := c.getSandboxController(sandbox.Config, sandbox.RuntimeHandler) - if err != nil { - return fmt.Errorf("failed to get sandbox controller: %w", err) - } - if _, err := controller.Stop(ctx, id); err != nil { - return fmt.Errorf("failed to stop sandbox %q: %w", id, err) + // Only stop sandbox container when it's running or unknown. + state := sandbox.Status.Get().State + if state == sandboxstore.StateReady || state == sandboxstore.StateUnknown { + // Use sandbox controller to stop sandbox + controller, err := c.getSandboxController(sandbox.Config, sandbox.RuntimeHandler) + if err != nil { + return fmt.Errorf("failed to get sandbox controller: %w", err) + } + + if _, err := controller.Stop(ctx, id); err != nil { + return fmt.Errorf("failed to stop sandbox %q: %w", id, err) + } } sandboxRuntimeStopTimer.WithValues(sandbox.RuntimeHandler).UpdateSince(stop) diff --git a/services/sandbox/controller_local.go b/services/sandbox/controller_local.go index 5b4ed5ae4..9302f28cc 100644 --- a/services/sandbox/controller_local.go +++ b/services/sandbox/controller_local.go @@ -156,7 +156,7 @@ func (c *controllerLocal) Stop(ctx context.Context, in *api.ControllerStopReques func (c *controllerLocal) Delete(ctx context.Context, in *api.ControllerDeleteRequest, opts ...grpc.CallOption) (*api.ControllerDeleteResponse, error) { if err := c.shims.Delete(ctx, in.SandboxID); err != nil { - return nil, fmt.Errorf("failed to delete sandbox shim: %w", err) + return nil, errdefs.ToGRPC(fmt.Errorf("failed to delete sandbox shim: %w", err)) } return &api.ControllerDeleteResponse{}, nil @@ -185,7 +185,7 @@ func (c *controllerLocal) Wait(ctx context.Context, in *api.ControllerWaitReques func (c *controllerLocal) Status(ctx context.Context, in *api.ControllerStatusRequest, opts ...grpc.CallOption) (*api.ControllerStatusResponse, error) { svc, err := c.getSandbox(ctx, in.SandboxID) if err != nil { - return nil, err + return nil, errdefs.ToGRPC(err) } resp, err := svc.SandboxStatus(ctx, &runtimeAPI.SandboxStatusRequest{SandboxID: in.SandboxID})