RemoveContainer removes the container.
(ctx context.Context, r *runtime.RemoveContainerRequest)
| 32 | |
| 33 | // RemoveContainer removes the container. |
| 34 | func (c *criService) RemoveContainer(ctx context.Context, r *runtime.RemoveContainerRequest) (_ *runtime.RemoveContainerResponse, retErr error) { |
| 35 | span := tracing.SpanFromContext(ctx) |
| 36 | start := time.Now() |
| 37 | ctrID := r.GetContainerId() |
| 38 | container, err := c.containerStore.Get(ctrID) |
| 39 | if err != nil { |
| 40 | if !errdefs.IsNotFound(err) { |
| 41 | return nil, fmt.Errorf("an error occurred when try to find container %q: %w", ctrID, err) |
| 42 | } |
| 43 | // Do not return error if container metadata doesn't exist. |
| 44 | log.G(ctx).Tracef("RemoveContainer called for container %q that does not exist", ctrID) |
| 45 | return &runtime.RemoveContainerResponse{}, nil |
| 46 | } |
| 47 | |
| 48 | defer c.nri.BlockPluginSync().Unblock() |
| 49 | |
| 50 | id := container.ID |
| 51 | span.SetAttributes(tracing.Attribute("container.id", id)) |
| 52 | i, err := container.Container.Info(ctx) |
| 53 | if err != nil { |
| 54 | if !errdefs.IsNotFound(err) { |
| 55 | return nil, fmt.Errorf("get container info: %w", err) |
| 56 | } |
| 57 | // Since containerd doesn't see the container and criservice's content store does, |
| 58 | // we should try to recover from this state by removing entry for this container |
| 59 | // from the container store as well and return successfully. |
| 60 | log.G(ctx).WithError(err).Warn("get container info failed") |
| 61 | c.containerStore.Delete(ctrID) |
| 62 | c.containerNameIndex.ReleaseByKey(ctrID) |
| 63 | return &runtime.RemoveContainerResponse{}, nil |
| 64 | } |
| 65 | |
| 66 | // Forcibly stop the containers if they are in running or unknown state |
| 67 | state := container.Status.Get().State() |
| 68 | if state == runtime.ContainerState_CONTAINER_RUNNING || |
| 69 | state == runtime.ContainerState_CONTAINER_UNKNOWN { |
| 70 | log.L.Infof("Forcibly stopping container %q", id) |
| 71 | if err := c.stopContainerRetryOnConnectionClosed(ctx, container, 0); err != nil { |
| 72 | return nil, fmt.Errorf("failed to forcibly stop container %q: %w", id, err) |
| 73 | } |
| 74 | |
| 75 | } |
| 76 | |
| 77 | // Set removing state to prevent other start/remove operations against this container |
| 78 | // while it's being removed. |
| 79 | if err := setContainerRemoving(container); err != nil { |
| 80 | return nil, fmt.Errorf("failed to set removing state for container %q: %w", id, err) |
| 81 | } |
| 82 | defer func() { |
| 83 | if retErr != nil { |
| 84 | // Reset removing if remove failed. |
| 85 | if err := resetContainerRemoving(container); err != nil { |
| 86 | log.G(ctx).WithError(err).Errorf("failed to reset removing state for container %q", id) |
| 87 | } |
| 88 | } |
| 89 | }() |
| 90 | |
| 91 | sandbox, err := c.sandboxStore.Get(container.SandboxID) |
no test coverage detected