nerdctl checkpoint rm requires the container to exist, so a checkpoint whose container was removed can never be removed and its directory stays in the data root

Đang mở
#5,282 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 2 ngày

@jonyhy96 đang làm issue này rồi.

Từ ngày 22/10/2026.

  • #5284 của @jonyhy96 — đang mở

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
48/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
go
Lĩnh vực
cli

Hướng nghiên cứu

Read pkg/cmd/checkpoint/remove.go and trace how container.ID() is used to build the checkpoint directory with checkpointutil.GetCheckpointDir. Check how checkpoint removal and its tests handle missing containers and checkpoint directories. Done means an orphaned checkpoint can be removed safely and existing removal behavior remains covered by tests.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Summary

nerdctl checkpoint rm resolves the container argument and refuses to remove
the checkpoint if the container cannot be found — and it does so before it
deletes anything. So a checkpoint whose container has already been removed
cannot be removed with nerdctl at all, and its directory stays in the data root
forever.

The behaviour

$ nerdctl checkpoint rm <gone-container> <checkpoint-name>
error removing checkpoint for container: <gone-container>, no such container
$ echo $?
1

and the checkpoint directory is still there:

$ ls ~/.local/share/nerdctl/checkpoints/
<checkpoint-name>/

The same applies to a checkpoint whose create failed: nothing was stored, and
the removal fails for the same reason.

The source

pkg/cmd/checkpoint/remove.go:

	n, err := walker.Walk(ctx, containerID)
	if err != nil {
		return err
	} else if n == 0 {
		return fmt.Errorf("error removing checkpoint for container: %s, no such container", containerID)
	}

	targetPath, err := checkpointutil.GetCheckpointDir(options.CheckpointDir, checkpointName, container.ID(), false)
	if err != nil {
		return err
	}

	return os.RemoveAll(targetPath)

The container lookup is a hard precondition for the removal, and it is
resolved before os.RemoveAll(targetPath).

Note also that the target path is derived from container.ID() — so the
container's identity is load-bearing for the removal, not merely for the
lookup.

Why this matters

The checkpoint store is a directory of CRIU image files under the nerdctl
data root — it is not a containerd object, and the name is not scoped by
container or by namespace. That is a reasonable design (a checkpoint is a
self-contained image set), but it creates a gap: the store outlives both the
container and the namespace, while the only supported removal path requires the
container.

The result is a directory that:

  • occupies disk in the user's data root (a CRIU image set is not small);
  • cannot be removed with nerdctl checkpoint rm, because the container it was
    named after is gone;
  • can only be removed by hand, with rm -rf against a path the user has to
    reconstruct.

The natural order — remove the container, then the checkpoint — is the order a
user reaches for first, and it is the order that strands the directory. The
working order is the reverse: checkpoint rm then rm.

Suggested direction

Two independent improvements, either of which closes the gap:

  1. Do not require the container when the checkpoint directory exists. The
    container lookup appears to be a guard against removing a checkpoint that
    does not exist, but os.RemoveAll on a non-existent path is already
    idempotent. If the lookup failed, the removal could still proceed against
    the checkpoint directory alone.

  2. Add an explicit "remove by name" path — e.g. allowing the container
    argument to be omitted, or a --force/--all mode that removes orphaned
    checkpoint directories whose container no longer exists. A nerdctl checkpoint ls that can list a directory with no container would also make the orphan
    visible to the user.

Environment

  • nerdctl 2.4.1
  • containerd v2.4.1
  • CRIU 4.2.1
Ngôn ngữ chính
Go
Star
10.5k
Fork
839
Merge trung bình
3 ngày 11 giờ
Pull request đã merge (30 ngày)
41

Chuẩn bị môi trường

  • Có Dockerfile hoặc tệp Docker Compose
  • Không có mẫu pull request
  • Không có hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của containerd/nerdctl

Tất cả issue của containerd/nerdctl

Issue tương tự

Thêm issue về Go

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.