RemovePodSandbox removes the sandbox. If there are running containers in the sandbox, they should be forcibly removed.
(ctx context.Context, r *runtime.RemovePodSandboxRequest)
| 32 | // RemovePodSandbox removes the sandbox. If there are running containers in the |
| 33 | // sandbox, they should be forcibly removed. |
| 34 | func (c *criService) RemovePodSandbox(ctx context.Context, r *runtime.RemovePodSandboxRequest) (*runtime.RemovePodSandboxResponse, error) { |
| 35 | span := tracing.SpanFromContext(ctx) |
| 36 | start := time.Now() |
| 37 | sandbox, err := c.sandboxStore.Get(r.GetPodSandboxId()) |
| 38 | if err != nil { |
| 39 | if !errdefs.IsNotFound(err) { |
| 40 | return nil, fmt.Errorf("an error occurred when try to find sandbox %q: %w", |
| 41 | r.GetPodSandboxId(), err) |
| 42 | } |
| 43 | // Do not return error if the id doesn't exist. |
| 44 | log.G(ctx).Tracef("RemovePodSandbox called for sandbox %q that does not exist", |
| 45 | r.GetPodSandboxId()) |
| 46 | return &runtime.RemovePodSandboxResponse{}, nil |
| 47 | } |
| 48 | |
| 49 | defer c.nri.BlockPluginSync().Unblock() |
| 50 | |
| 51 | // Use the full sandbox id. |
| 52 | id := sandbox.ID |
| 53 | span.SetAttributes(tracing.Attribute("sandbox.id", id)) |
| 54 | |
| 55 | // If the sandbox is still running, not ready, or in an unknown state, forcibly stop it. |
| 56 | // Even if it's in a NotReady state, this will close its network namespace, if open. |
| 57 | // This can happen if the task process associated with the Pod died or it was killed. |
| 58 | log.G(ctx).Infof("Forcibly stopping sandbox %q", id) |
| 59 | if err := c.stopPodSandbox(ctx, sandbox); err != nil { |
| 60 | return nil, fmt.Errorf("failed to forcibly stop sandbox %q: %w", id, err) |
| 61 | } |
| 62 | |
| 63 | if err := c.client.LeasesService().Delete(ctx, leases.Lease{ID: id}); err != nil { |
| 64 | if !errdefs.IsNotFound(err) { |
| 65 | return nil, fmt.Errorf("failed to delete lease for sandbox %q: %w", id, err) |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | // Return error if sandbox network namespace is not closed yet. |
| 70 | if sandbox.NetNS != nil { |
| 71 | nsPath := sandbox.NetNS.GetPath() |
| 72 | if closed, err := sandbox.NetNS.Closed(); err != nil { |
| 73 | return nil, fmt.Errorf("failed to check sandbox network namespace %q closed: %w", nsPath, err) |
| 74 | } else if !closed { |
| 75 | return nil, fmt.Errorf("sandbox network namespace %q is not fully closed", nsPath) |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | // Remove all containers inside the sandbox. |
| 80 | // NOTE(random-liu): container could still be created after this point, Kubelet should |
| 81 | // not rely on this behavior. |
| 82 | // TODO(random-liu): Introduce an intermediate state to avoid container creation after |
| 83 | // this point. |
| 84 | cntrs := c.containerStore.List() |
| 85 | for _, cntr := range cntrs { |
| 86 | if cntr.SandboxID != id { |
| 87 | continue |
| 88 | } |
| 89 | _, err = c.RemoveContainer(ctx, &runtime.RemoveContainerRequest{ContainerId: cntr.ID}) |
| 90 | if err != nil { |
| 91 | return nil, fmt.Errorf("failed to remove container %q: %w", cntr.ID, err) |
nothing calls this directly
no test coverage detected