Repository: containerd/nerdctl
Pull request #4017: update slirp4netns (1.3.2), containerd (2.0.4), runc (1.2.6)...; verify the git tags with the commit hashes
Author: login: AkihiroSuda
Created: 2025-03-18T08:51:12Z | Merged: 2025-03-20T14:56:01Z

Will release v2.0.4 after merging this



Diff:
diff --git a/.github/workflows/test-canary.yml b/.github/workflows/test-canary.yml
index 45d25c2372e..0a890600afa 100644
--- a/.github/workflows/test-canary.yml
+++ b/.github/workflows/test-canary.yml
@@ -81,7 +81,7 @@ jobs:
       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
         with:
           repository: containerd/containerd
-          ref: "v1.7.25"
+          ref: "v1.7.27"
           path: containerd
           fetch-depth: 1
       - name: "Set up CNI"
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index a50b3c8a75c..0ce8c02b607 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -26,13 +26,13 @@ jobs:
       matrix:
         include:
           - runner: ubuntu-24.04
-            containerd: v1.6.36
+            containerd: v1.6.38
             arch: amd64
           - runner: ubuntu-24.04
-            containerd: v2.0.3
+            containerd: v2.0.4
             arch: amd64
           - runner: ubuntu-24.04-arm
-            containerd: v2.0.3
+            containerd: v2.0.4
             arch: arm64
     env:
       CONTAINERD_VERSION: "${{ matrix.containerd }}"
@@ -82,7 +82,7 @@ jobs:
         uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
         with:
           repository: containerd/containerd
-          ref: v1.7.25
+          ref: v1.7.27
           path: containerd
           fetch-depth: 1
       - if: ${{ matrix.goos=='windows' }}
@@ -102,15 +102,15 @@ jobs:
       matrix:
         include:
           - ubuntu: 22.04
-            containerd: v1.6.36
+            containerd: v1.6.38
             runner: "ubuntu-22.04"
             arch: amd64
           - ubuntu: 24.04
-            containerd: v2.0.3
+            containerd: v2.0.4
             runner: "ubuntu-24.04"
             arch: amd64
           - ubuntu: 24.04
-            containerd: v2.0.3
+            containerd: v2.0.4
             runner: "ubuntu-24.04-arm"
             arch: arm64
     env:
@@ -160,7 +160,7 @@ jobs:
       matrix:
         include:
           - ubuntu: 24.04
-            containerd: v2.0.3
+            containerd: v2.0.4
             arch: amd64
     env:
       CONTAINERD_VERSION: "${{ matrix.containerd }}"
@@ -221,25 +221,25 @@ jobs:
       matrix:
         include:
           - ubuntu: 22.04
-            containerd: v1.6.36
+            containerd: v1.6.38
             rootlesskit: v1.1.1  # Deprecated
             target: rootless
             runner: "ubuntu-22.04"
             arch: amd64
           - ubuntu: 24.04
-            containerd: v2.0.3
+            containerd: v2.0.4
             rootlesskit: v2.3.4
             target: rootless
             arch: amd64
             runner: "ubuntu-24.04"
           - ubuntu: 24.04
-            containerd: v2.0.3
+            containerd: v2.0.4
             rootlesskit: v2.3.4
             target: rootless
             arch: arm64
             runner: "ubuntu-24.04-arm"
           - ubuntu: 24.04
-            containerd: v2.0.3
+            containerd: v2.0.4
             rootlesskit: v2.3.4
             target: rootless-port-slirp4netns
             arch: amd64
@@ -373,7 +373,7 @@ jobs:
       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
         with:
           repository: containerd/containerd
-          ref: v1.7.25
+          ref: v1.7.27
           path: containerd
           fetch-depth: 1
       - name: "Set up CNI"
@@ -381,7 +381,7 @@ jobs:
         run: GOPATH=$(go env GOPATH) script/setup/install-cni-windows
       - name: "Set up containerd"
         env:
-          ctrdVersion: 1.7.25
+          ctrdVersion: 1.7.27
         run: powershell hack/configure-windows-ci.ps1
       - name: "Run integration tests"
         run: ./hack/test-integration.sh -test.only-flaky=false
@@ -437,7 +437,7 @@ jobs:
     env:
       MODE: ${{ matrix.mode }}
       # FIXME: this is only necessary to access the build cache. To remove with build cleanup.
-      CONTAINERD_VERSION: v2.0.3
+      CONTAINERD_VERSION: v2.0.4
     steps:
       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
         with:
diff --git a/Dockerfile b/Dockerfile
index 0d441c18acd..8750018a18e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -15,42 +15,42 @@
 # -----------------------------------------------------------------------------
 # Usage: `docker run -it --privileged <IMAGE>`. Make sure to add `-t` and `--privileged`.
 
-# TODO: verify commit hash
-
 # Basic deps
-ARG CONTAINERD_VERSION=v2.0.3
-ARG RUNC_VERSION=v1.2.5
-ARG CNI_PLUGINS_VERSION=v1.6.2
+# @BINARY: the binary checksums are verified via Dockerfile.d/SHA256SUMS.d/<COMPONENT>-<VERSION>
+ARG CONTAINERD_VERSION=v2.0.4@1a43cb6a1035441f9aca8f5666a9b3ef9e70ab20
+ARG RUNC_VERSION=v1.2.6@e89a29929c775025419ab0d218a43588b4c12b9a
+ARG CNI_PLUGINS_VERSION=v1.6.2@BINARY
 
 # Extra deps: Build
-ARG BUILDKIT_VERSION=v0.20.1
+ARG BUILDKIT_VERSION=v0.20.1@BINARY
 # Extra deps: Lazy-pulling
-ARG STARGZ_SNAPSHOTTER_VERSION=v0.16.3
+ARG STARGZ_SNAPSHOTTER_VERSION=v0.16.3@BINARY
 # Extra deps: Encryption
-ARG IMGCRYPT_VERSION=v2.0.0
+ARG IMGCRYPT_VERSION=v2.0.1@c377ec98ff79ec9205eabf555ebd2ea784738c6c
 # Extra deps: Rootless
-ARG ROOTLESSKIT_VERSION=v2.3.4
-ARG SLIRP4NETNS_VERSION=v1.3.1
+ARG ROOTLESSKIT_VERSION=v2.3.4@BINARY
+ARG SLIRP4NETNS_VERSION=v1.3.2@BINARY
 # Extra deps: bypass4netns
-ARG BYPASS4NETNS_VERSION=v0.4.2
+ARG BYPASS4NETNS_VERSION=v0.4.2@aa04bd3dcc48c6dae6d7327ba219bda8fe2a4634
 # Extra deps: FUSE-OverlayFS
-ARG FUSE_OVERLAYFS_VERSION=v1.14
-ARG CONTAINERD_FUSE_OVERLAYFS_VERSION=v2.1.1
+ARG FUSE_OVERLAYFS_VERSION=v1.14@BINARY
+ARG CONTAINERD_FUSE_OVERLAYFS_VERSION=v2.1.2@BINARY
 # Extra deps: Init
-ARG TINI_VERSION=v0.19.0
+ARG TINI_VERSION=v0.19.0@BINARY
 # Extra deps: Debug
-ARG BUILDG_VERSION=v0.4.1
+ARG BUILDG_VERSION=v0.4.1@BINARY
 
 # Test deps
+# Currently, the Docker Official Images and the test deps are not pinned by the hash
 ARG GO_VERSION=1.24
 ARG UBUNTU_VERSION=24.04
 ARG CONTAINERIZED_SYSTEMD_VERSION=v0.1.1
 ARG GOTESTSUM_VERSION=v1.12.0
 ARG NYDUS_VERSION=v2.3.0
 ARG SOCI_SNAPSHOTTER_VERSION=0.8.0
-ARG KUBO_VERSION=v0.32.1
+ARG KUBO_VERSION=v0.33.2
 
-FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.6.1 AS xx
+FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.6.1@sha256:923441d7c25f1e2eb5789f82d987693c47b8ed987c4ab3b075d6ed2b5d6779a3 AS xx
 
 
 FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-bookworm AS build-base-debian
@@ -70,13 +70,14 @@ RUN xx-apt-get update -qq && xx-apt-get install -qq --no-install-recommends \
   libseccomp-dev \
   pkg-config
 RUN git config --global advice.detachedHead false
+ADD hack/git-checkout-tag-with-hash.sh /usr/local/bin/
 
 FROM build-base-debian AS build-containerd
 ARG TARGETARCH
 ARG CONTAINERD_VERSION
 RUN git clone https://github.com/containerd/containerd.git /go/src/github.com/containerd/containerd
 WORKDIR /go/src/github.com/containerd/containerd
-RUN git checkout ${CONTAINERD_VERSION} && \
+RUN git-checkout-tag-with-hash.sh ${CONTAINERD_VERSION} && \
   mkdir -p /out /out/$TARGETARCH && \
   cp -a containerd.service /out
 RUN GO=xx-go make STATIC=1 && \
@@ -87,7 +88,7 @@ ARG RUNC_VERSION
 ARG TARGETARCH
 RUN git clone https://github.com/opencontainers/runc.git /go/src/github.com/opencontainers/runc
 WORKDIR /go/src/github.com/opencontainers/runc
-RUN git checkout ${RUNC_VERSION} && \
+RUN git-checkout-tag-with-hash.sh ${RUNC_VERSION} && \
   mkdir -p /out
 ENV CGO_ENABLED=1
 RUN GO=xx-go CC=$(xx-info)-gcc STRIP=$(xx-info)-strip make static && \
@@ -98,7 +99,7 @@ ARG BYPASS4NETNS_VERSION
 ARG TARGETARCH
 RUN git clone https://github.com/rootless-containers/bypass4netns.git /go/src/github.com/rootless-containers/bypass4netns
 WORKDIR /go/src/github.com/rootless-containers/bypass4netns
-RUN git checkout ${BYPASS4NETNS_VERSION} && \
+RUN git-checkout-tag-with-hash.sh ${BYPASS4NETNS_VERSION} && \
   mkdir -p /out/${TARGETARCH}
 ENV CGO_ENABLED=1
 RUN GO=xx-go make static && \
@@ -109,7 +110,7 @@ ARG KUBO_VERSION
 ARG TARGETARCH
 RUN git clone https://github.com/ipfs/kubo.git /go/src/github.com/ipfs/kubo
 WORKDIR /go/src/github.com/ipfs/kubo
-RUN git checkout ${KUBO_VERSION} && \
+RUN git-checkout-tag-with-hash.sh ${KUBO_VERSION} && \
   mkdir -p /out/${TARGETARCH}
 ENV CGO_ENABLED=0
 RUN xx-go --wrap && \
@@ -119,6 +120,7 @@ RUN xx-go --wrap && \
 FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS build-base
 RUN apk add --no-cache make git curl
 RUN git config --global advice.detachedHead false
+ADD hack/git-checkout-tag-with-hash.sh /usr/local/bin/
 
 FROM build-base AS build-minimal
 RUN BINDIR=/out/bin make binaries install
@@ -134,12 +136,13 @@ RUN mkdir -p /out/share/doc/nerdctl-full && touch /out/share/doc/nerdctl-full/RE
 ARG CONTAINERD_VERSION
 COPY --from=build-containerd /out/${TARGETARCH:-amd64}/* /out/bin/
 COPY --from=build-containerd /out/containerd.service /out/lib/systemd/system/containerd.service
-RUN echo "- containerd: ${CONTAINERD_VERSION}" >> /out/share/doc/nerdctl-full/README.md
+RUN echo "- containerd: ${CONTAINERD_VERSION/@*}" >> /out/share/doc/nerdctl-full/README.md
 ARG RUNC_VERSION
 COPY --from=build-runc /out/runc.${TARGETARCH:-amd64} /out/bin/runc
-RUN echo "- runc: ${RUNC_VERSION}" >> /out/share/doc/nerdctl-full/README.md
+RUN echo "- runc: ${RUNC_VERSION/@*}" >> /out/share/doc/nerdctl-full/README.md
 ARG CNI_PLUGINS_VERSION
-RUN fname="cni-plugins-${TARGETOS:-linux}-${TARGETARCH:-amd64}-${CNI_PLUGINS_VERSION}.tgz" && \
+RUN CNI_PLUGINS_VERSION=${CNI_PLUGINS_VERSION/@BINARY}; \
+  fname="cni-plugins-${TARGETOS:-linux}-${TARGETARCH:-amd64}-${CNI_PLUGINS_VERSION}.tgz" && \
   curl -o "${fname}" -fsSL --proto '=https' --tlsv1.2 "https://github.com/containernetworking/plugins/releases/download/${CNI_PLUGINS_VERSION}/${fname}" && \
   grep "${fname}" "/SHA256SUMS.d/cni-plugins-${CNI_PLUGINS_VERSION}" | sha256sum -c && \
   mkdir -p /out/libexec/cni && \
@@ -147,7 +150,8 @@ RUN fname="cni-plugins-${TARGETOS:-linux}-${TARGETARCH:-amd64}-${CNI_PLUGINS_VER
   rm -f "${fname}" && \
   echo "- CNI plugins: ${CNI_PLUGINS_VERSION}" >> /out/share/doc/nerdctl-full/README.md
 ARG BUILDKIT_VERSION
-RUN fname="buildkit-${BUILDKIT_VERSION}.${TARGETOS:-linux}-${TARGETARCH:-amd64}.tar.gz" && \
+RUN BUILDKIT_VERSION=${BUILDKIT_VERSION/@BINARY}; \
+  fname="buildkit-${BUILDKIT_VERSION}.${TARGETOS:-linux}-${TARGETARCH:-amd64}.tar.gz" && \
   curl -o "${fname}" -fsSL --proto '=https' --tlsv1.2 "https://github.com/moby/buildkit/releases/download/${BUILDKIT_VERSION}/${fname}" && \
   grep "${fname}" "/SHA256SUMS.d/buildkit-${BUILDKIT_VERSION}" | sha256sum -c && \
   tar xzf "${fname}" -C /out && \
@@ -161,7 +165,8 @@ RUN cd /out/lib/systemd/system && \
   echo "" >> buildkit.service && \
   echo "# This file was converted from containerd.service, with \`sed -E '${sedcomm}'\`" >> buildkit.service
 ARG STARGZ_SNAPSHOTTER_VERSION
-RUN fname="stargz-snapshotter-${STARGZ_SNAPSHOTTER_VERSION}-${TARGETOS:-linux}-${TARGETARCH:-amd64}.tar.gz" && \
+RUN STARGZ_SNAPSHOTTER_VERSION=${STARGZ_SNAPSHOTTER_VERSION/@BINARY}; \
+  fname="stargz-snapshotter-${STARGZ_SNAPSHOTTER_VERSION}-${TARGETOS:-linux}-${TARGETARCH:-amd64}.tar.gz" && \
   curl -o "${fname}" -fsSL --proto '=https' --tlsv1.2 "https://github.com/containerd/stargz-snapshotter/releases/download/${STARGZ_SNAPSHOTTER_VERSION}/${fname}" && \
   curl -o "stargz-snapshotter.service" -fsSL --proto '=https' --tlsv1.2 "https://raw.githubusercontent.com/containerd/stargz-snapshotter/${STARGZ_SNAPSHOTTER_VERSION}/script/config/etc/systemd/system/stargz-snapshotter.service" && \
   grep "${fname}" "/SHA256SUMS.d/stargz-snapshotter-${STARGZ_SNAPSHOTTER_VERSION}" | sha256sum -c - && \
@@ -173,11 +178,12 @@ RUN fname="stargz-snapshotter-${STARGZ_SNAPSHOTTER_VERSION}-${TARGETOS:-linux}-$
 ARG IMGCRYPT_VERSION
 RUN git clone https://github.com/containerd/imgcrypt.git /go/src/github.com/containerd/imgcrypt && \
   cd /go/src/github.com/containerd/imgcrypt && \
-  git checkout "${IMGCRYPT_VERSION}" && \
+  git-checkout-tag-with-hash.sh "${IMGCRYPT_VERSION}" && \
   CGO_ENABLED=0 make && DESTDIR=/out make install && \
-  echo "- imgcrypt: ${IMGCRYPT_VERSION}" >> /out/share/doc/nerdctl-full/README.md
+  echo "- imgcrypt: ${IMGCRYPT_VERSION/@*}" >> /out/share/doc/nerdctl-full/README.md
 ARG SLIRP4NETNS_VERSION
-RUN fname="slirp4netns-$(cat /target_uname_m)" && \
+RUN SLIRP4NETNS_VERSION=${SLIRP4NETNS_VERSION/@BINARY}; \
+  fname="slirp4netns-$(cat /target_uname_m)" && \
   curl -o "${fname}" -fsSL --proto '=https' --tlsv1.2 "https://github.com/rootless-containers/slirp4netns/releases/download/${SLIRP4NETNS_VERSION}/${fname}" && \
   grep "${fname}" "/SHA256SUMS.d/slirp4netns-${SLIRP4NETNS_VERSION}" | sha256sum -c && \
   mv "${fname}" /out/bin/slirp4netns && \
@@ -185,36 +191,41 @@ RUN fname="slirp4netns-$(cat /target_uname_m)" && \
   echo "- slirp4netns: ${SLIRP4NETNS_VERSION}" >> /out/share/doc/nerdctl-full/README.md
 ARG BYPASS4NETNS_VERSION
 COPY --from=build-bypass4netns /out/${TARGETARCH:-amd64}/* /out/bin/
-RUN echo "- bypass4netns: ${BYPASS4NETNS_VERSION}" >> /out/share/doc/nerdctl-full/README.md
+RUN echo "- bypass4netns: ${BYPASS4NETNS_VERSION/@*}" >> /out/share/doc/nerdctl-full/README.md
 ARG FUSE_OVERLAYFS_VERSION
-RUN fname="fuse-overlayfs-$(cat /target_uname_m)" && \
+RUN FUSE_OVERLAYFS_VERSION=${FUSE_OVERLAYFS_VERSION/@BINARY}; \
+  fname="fuse-overlayfs-$(cat /target_uname_m)" && \
   curl -o "${fname}" -fsSL --proto '=https' --tlsv1.2 "https://github.com/containers/fuse-overlayfs/releases/download/${FUSE_OVERLAYFS_VERSION}/${fname}" && \
   grep "${fname}" "/SHA256SUMS.d/fuse-overlayfs-${FUSE_OVERLAYFS_VERSION}" | sha256sum -c && \
   mv "${fname}" /out/bin/fuse-overlayfs && \
   chmod +x /out/bin/fuse-overlayfs && \
   echo "- fuse-overlayfs: ${FUSE_OVERLAYFS_VERSION}" >> /out/share/doc/nerdctl-full/README.md
 ARG CONTAINERD_FUSE_OVERLAYFS_VERSION
-RUN fname="containerd-fuse-overlayfs-${CONTAINERD_FUSE_OVERLAYFS_VERSION/v}-${TARGETOS:-linux}-${TARGETARCH:-amd64}.tar.gz" && \
+RUN CONTAINERD_FUSE_OVERLAYFS_VERSION=${CONTAINERD_FUSE_OVERLAYFS_VERSION/@BINARY}; \
+  fname="containerd-fuse-overlayfs-${CONTAINERD_FUSE_OVERLAYFS_VERSION/v}-${TARGETOS:-linux}-${TARGETARCH:-amd64}.tar.gz" && \
   curl -o "${fname}" -fsSL --proto '=https' --tlsv1.2 "https://github.com/containerd/fuse-overlayfs-snapshotter/releases/download/${CONTAINERD_FUSE_OVERLAYFS_VERSION}/${fname}" && \
   grep "${fname}" "/SHA256SUMS.d/containerd-fuse-overlayfs-${CONTAINERD_FUSE_OVERLAYFS_VERSION}" | sha256sum -c && \
   tar xzf "${fname}" -C /out/bin && \
   rm -f "${fname}" && \
   echo "- containerd-fuse-overlayfs: ${CONTAINERD_FUSE_OVERLAYFS_VERSION}" >> /out/share/doc/nerdctl-full/README.md
 ARG TINI_VERSION
-RUN fname="tini-static-${TARGETARCH:-amd64}" && \
+RUN TINI_VERSION=${TINI_VERSION/@BINARY}; \
+  fname="tini-static-${TARGETARCH:-amd64}" && \
   curl -o "${fname}" -fsSL --proto '=https' --tlsv1.2 "https://github.com/krallin/tini/releases/download/${TINI_VERSION}/${fname}" && \
   grep "${fname}" "/SHA256SUMS.d/tini-${TINI_VERSION}" | sha256sum -c && \
   cp -a "${fname}" /out/bin/tini && chmod +x /out/bin/tini && \
   echo "- Tini: ${TINI_VERSION}" >> /out/share/doc/nerdctl-full/README.md
 ARG BUILDG_VERSION
-RUN fname="buildg-${BUILDG_VERSION}-${TARGETOS:-linux}-${TARGETARCH:-amd64}.tar.gz" && \
+RUN BUILDG_VERSION=${BUILDG_VERSION/@BINARY}; \
+  fname="buildg-${BUILDG_VERSION}-${TARGETOS:-linux}-${TARGETARCH:-amd64}.tar.gz" && \
   curl -o "${fname}" -fsSL --proto '=https' --tlsv1.2 "https://github.com/ktock/buildg/releases/download/${BUILDG_VERSION}/${fname}" && \
   grep "${fname}" "/SHA256SUMS.d/buildg-${BUILDG_VERSION}" | sha256sum -c && \
   tar xzf "${fname}" -C /out/bin && \
   rm -f "${fname}" && \
   echo "- buildg: ${BUILDG_VERSION}" >> /out/share/doc/nerdctl-full/README.md
 ARG ROOTLESSKIT_VERSION
-RUN fname="rootlesskit-$(cat /target_uname_m).tar.gz" && \
+RUN ROOTLESSKIT_VERSION=${ROOTLESSKIT_VERSION/@BINARY}; \
+  fname="rootlesskit-$(cat /target_uname_m).tar.gz" && \
   curl -o "${fname}" -fsSL --proto '=https' --tlsv1.2 "https://github.com/rootless-containers/rootlesskit/releases/download/${ROOTLESSKIT_VERSION}/${fname}" && \
   grep "${fname}" "/SHA256SUMS.d/rootlesskit-${ROOTLESSKIT_VERSION}" | sha256sum -c && \
   tar xzf "${fname}" -C /out/bin && \
@@ -223,10 +234,10 @@ RUN fname="rootlesskit-$(cat /target_uname_m).tar.gz" && \
 
 RUN echo "" >> /out/share/doc/nerdctl-full/README.md && \
   echo "## License" >> /out/share/doc/nerdctl-full/README.md && \
-  echo "- bin/slirp4netns:    [GNU GENERAL PUBLIC LICENSE, Version 2](https://github.com/rootless-containers/slirp4netns/blob/${SLIRP4NETNS_VERSION}/COPYING)" >> /out/share/doc/nerdctl-full/README.md && \
-  echo "- bin/fuse-overlayfs: [GNU GENERAL PUBLIC LICENSE, Version 2](https://github.com/containers/fuse-overlayfs/blob/${FUSE_OVERLAYFS_VERSION}/COPYING)" >> /out/share/doc/nerdctl-full/README.md && \
+  echo "- bin/slirp4netns:    [GNU GENERAL PUBLIC LICENSE, Version 2](https://github.com/rootless-containers/slirp4netns/blob/${SLIRP4NETNS_VERSION/@*}/COPYING)" >> /out/share/doc/nerdctl-full/README.md && \
+  echo "- bin/fuse-overlayfs: [GNU GENERAL PUBLIC LICENSE, Version 2](https://github.com/containers/fuse-overlayfs/blob/${FUSE_OVERLAYFS_VERSION/@*}/COPYING)" >> /out/share/doc/nerdctl-full/README.md && \
   echo "- bin/{runc,bypass4netns,bypass4netnsd}: Apache License 2.0, statically linked with libseccomp ([LGPL 2.1](https://github.com/seccomp/libseccomp/blob/main/LICENSE), source code available at https://github.com/seccomp/libseccomp/)" >> /out/share/doc/nerdctl-full/README.md && \
-  echo "- bin/tini: [MIT License](https://github.com/krallin/tini/blob/${TINI_VERSION}/LICENSE)" >> /out/share/doc/nerdctl-full/README.md && \
+  echo "- bin/tini: [MIT License](https://github.com/krallin/tini/blob/${TINI_VERSION/@*}/LICENSE)" >> /out/share/doc/nerdctl-full/README.md && \
   echo "- Other files: [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)" >> /out/share/doc/nerdctl-full/README.md
 
 FROM build-dependencies AS build-full
diff --git a/Dockerfile.d/SHA256SUMS.d/containerd-fuse-overlayfs-v2.1.1 b/Dockerfile.d/SHA256SUMS.d/containerd-fuse-overlayfs-v2.1.1
deleted file mode 100644
index 6596447644d..00000000000
--- a/Dockerfile.d/SHA256SUMS.d/containerd-fuse-overlayfs-v2.1.1
+++ /dev/null
@@ -1,6 +0,0 @@
-2061a4064d163544f69e36fe56d008ab90f791906d5a96bddf87d3151fdde836  containerd-fuse-overlayfs-2.1.1-linux-amd64.tar.gz
-99d08b0f41ede108f36efb9b5d8e0613be69336785cf97a73074487b52d9e71e  containerd-fuse-overlayfs-2.1.1-linux-arm-v7.tar.gz
-2219bf91d943480ce7021d6fce956379050757a500d36540b4372d45616c74eb  containerd-fuse-overlayfs-2.1.1-linux-arm64.tar.gz
-a2515f00553334b23470d52b088e49c3aa69aa9d66163dc14f188684bc8c774d  containerd-fuse-overlayfs-2.1.1-linux-ppc64le.tar.gz
-ae0fc07af2d34fb4c599364f82570ec43fed07f1892e493726f5414ecf8c8908  containerd-fuse-overlayfs-2.1.1-linux-riscv64.tar.gz
-1200244a100b2433cc98a7ec8a0138073e9ad1c5e11ed503f5d2b3063dd40197  containerd-fuse-overlayfs-2.1.1-linux-s390x.tar.gz
diff --git a/Dockerfile.d/SHA256SUMS.d/containerd-fuse-overlayfs-v2.1.2 b/Dockerfile.d/SHA256SUMS.d/containerd-fuse-overlayfs-v2.1.2
new file mode 100644
index 00000000000..260fe0dedad
--- /dev/null
+++ b/Dockerfile.d/SHA256SUMS.d/containerd-fuse-overlayfs-v2.1.2
@@ -0,0 +1,6 @@
+b484d76468b7e91e215c7bdab99eb6322e3c396707cd72c3571d8bc6a62f4fb5  containerd-fuse-overlayfs-2.1.2-linux-amd64.tar.gz
+35648602f4eea1a84095ac19ca63752e3a9faa2e1a3b9ba95c6e555aee932820  containerd-fuse-overlayfs-2.1.2-linux-arm-v7.tar.gz
+0d9a75ef98e4538f039fea3da621560fd2b85a6bc34735f189121decf7d2266b  containerd-fuse-overlayfs-2.1.2-linux-arm64.tar.gz
+02a4f9c90b2fbabd4326a19f7659638b36910c4633fe1772f44da6239c4e95fa  containerd-fuse-overlayfs-2.1.2-linux-ppc64le.tar.gz
+febd653d766cc724383045509b6958d8f1bdfc4d4b8d5027099d7760c6374dca  containerd-fuse-overlayfs-2.1.2-linux-riscv64.tar.gz
+44a6c830d3371d522033ac47a2f90b6be12311d72a8b290a70d73771aa062e6c  containerd-fuse-overlayfs-2.1.2-linux-s390x.tar.gz
diff --git a/Dockerfile.d/SHA256SUMS.d/slirp4netns-v1.3.1 b/Dockerfile.d/SHA256SUMS.d/slirp4netns-v1.3.1
deleted file mode 100644
index 4d0d9ea9444..00000000000
--- a/Dockerfile.d/SHA256SUMS.d/slirp4netns-v1.3.1
+++ /dev/null
@@ -1,6 +0,0 @@
-2dd9aac6c2e3203e53cb7b6e4b9fc7123e4e4a9716c8bb1d95951853059a6af5  slirp4netns-aarch64
-ed618c0f2c74014bb736e9e427e18c8791ad9d68311872a41b06fac0d7cb9ef2  slirp4netns-armv7l
-a10f70209cee0dd0532fea0e8b6bfde5d16dec5206fd4b3387d861721456de66  slirp4netns-ppc64le
-38209015c2f3f4619d9fc46610852887910f33c7a0b96f7d2aa835a7bbc73f31  slirp4netns-riscv64
-9f42718455b1f9cf4b6f0efee314b78e860b8c36dbbb6290f09c8fbedda9ff8a  slirp4netns-s390x
-4bc5d6c311f9fa7ae00ce54aefe10c2afaf0800fe9e99f32616a964ed804a9e1  slirp4netns-x86_64
diff --git a/Dockerfile.d/SHA256SUMS.d/slirp4netns-v1.3.2 b/Dockerfile.d/SHA256SUMS.d/slirp4netns-v1.3.2
new file mode 100644
index 00000000000..db7c5ae07df
--- /dev/null
+++ b/Dockerfile.d/SHA256SUMS.d/slirp4netns-v1.3.2
@@ -0,0 +1,7 @@
+b4162d27bbbd3683ca8ee57b51a1b270c0054b3a15fcc1830a5d7c10b77ad045  SOURCE_DATE_EPOCH
+c55117faa5e18345a3ee1515267f056822ff0c1897999ae5422b0114ee48df85  slirp4netns-aarch64
+f55a6c9e3ec8280e9c3cec083f07dc124e2846ce8139a9281c35013e968d7e95  slirp4netns-armv7l
+7b388a9cacbd89821f7f7a6457470fcae8f51aa846162521589feb4634ec7586  slirp4netns-ppc64le
+041f9fe507510de1fbb802933a6add093ff19f941185965295c81f2ba4fc9cec  slirp4netns-riscv64
+aa39cf14414ae53dbff6b79dfdfa55b5ff8ac5250e2261804863cd365b33a818  slirp4netns-s390x
+4d55a3658ae259e3e74bb75cf058eb05d6e39ad6bbe170ca8e94c2462bea0eb1  slirp4netns-x86_64
diff --git a/hack/git-checkout-tag-with-hash.sh b/hack/git-checkout-tag-with-hash.sh
new file mode 100755
index 00000000000..aecbd5421d9
--- /dev/null
+++ b/hack/git-checkout-tag-with-hash.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+#   Copyright The containerd Authors.
+
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+
+#       http://www.apache.org/licenses/LICENSE-2.0
+
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+# This script is intended to be usable in other projects too.
+# * Must not have project-specific logics
+# * Must be compatible with bash, dash, and busybox
+
+set -eu
+if [ "$#" -ne 1 ]; then
+	echo "$0: checkout TAG with HASH, and validate it"
+	echo "Usage: $0 TAG[@HASH]"
+	exit 0
+fi
+
+: "${GIT:=git}"
+TAG="$(echo "$1" | cut -d@ -f1)"
+HASH=""
+case "$1" in
+*@*)
+	HASH="$(echo "$1" | cut -d@ -f2)"
+	;;
+esac
+
+"$GIT" checkout "$TAG"
+HEAD="$("$GIT" rev-parse HEAD)"
+if [ -z "$HASH" ]; then
+	echo >&2 "WARNING: ${TAG}: commit hash was not specified (got ${HEAD})"
+else
+	if [ "$HEAD" != "$HASH" ]; then
+		echo >&2 "ERROR: ${TAG}: expected ${HASH}, got ${HEAD}"
+		exit 1
+	fi
+fi


Reviews:
user: login: fahedouch
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-18T09:30:04Z
user: login: fahedouch
body: Thanks
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-18T09:30:42Z
user: login: fahedouch
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-18T12:45:26Z
user: login: austinvazquez
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-18T14:27:10Z
user: login: apostasie
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T16:35:29Z
user: login: AkihiroSuda
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-19T06:44:55Z
user: login: AkihiroSuda
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-19T06:47:00Z
user: login: AkihiroSuda
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-19T07:32:41Z
user: login: AkihiroSuda
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-19T13:37:05Z
user: login: AkihiroSuda
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-19T13:37:32Z
user: login: apostasie
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T18:27:34Z
user: login: apostasie
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T18:28:21Z
user: login: AkihiroSuda
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-19T19:17:33Z
user: login: apostasie
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T19:54:38Z
user: login: apostasie
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T21:52:58Z
user: login: fahedouch
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T09:39:04Z
user: login: AkihiroSuda
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T14:14:46Z
user: login: AkihiroSuda
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T14:15:27Z
user: login: fahedouch
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T14:32:37Z
user: login: apostasie
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T14:51:55Z
user: login: AkihiroSuda
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-20T14:55:54Z

Review comments:
diff_hunk: @@ -15,11 +15,15 @@
 # -----------------------------------------------------------------------------
 # Usage: `docker run -it --privileged <IMAGE>`. Make sure to add `-t` and `--privileged`.
 
-# TODO: verify commit hash
+# Some deps are compiled from the source releases, some ones are installed from the binary releases.
+#
+# To update a dep, one of the following files have to be updated:
+# - Dockerfile.d/COMMITS.d/<COMPONENT>-<VERSION>:    the hash of the source release
+# - Dockerfile.d/SHA256SUMS.d/<COMPONENT>-<VERSION>: the hash of the binary release
path: Dockerfile
user: login: fahedouch
body: good. Thanks
created_at: 2025-03-18T09:30:04Z
author_association: MEMBER
diff_hunk: @@ -74,42 +79,54 @@ RUN git config --global advice.detachedHead false
 FROM build-base-debian AS build-containerd
 ARG TARGETARCH
 ARG CONTAINERD_VERSION
+ARG CANARY
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/containerd/containerd.git /go/src/github.com/containerd/containerd
 WORKDIR /go/src/github.com/containerd/containerd
-RUN git checkout ${CONTAINERD_VERSION} && \
+RUN set -eux ; git checkout ${CONTAINERD_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/containerd-${CONTAINERD_VERSION})" ] && \
   mkdir -p /out /out/$TARGETARCH && \
   cp -a containerd.service /out
 RUN GO=xx-go make STATIC=1 && \
   cp -a bin/containerd bin/containerd-shim-runc-v2 bin/ctr /out/$TARGETARCH
 
 FROM build-base-debian AS build-runc
 ARG RUNC_VERSION
+ARG CANARY
 ARG TARGETARCH
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/opencontainers/runc.git /go/src/github.com/opencontainers/runc
 WORKDIR /go/src/github.com/opencontainers/runc
-RUN git checkout ${RUNC_VERSION} && \
+RUN set -eux ; git checkout ${RUNC_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/runc-${RUNC_VERSION})" ] && \
   mkdir -p /out
 ENV CGO_ENABLED=1
 RUN GO=xx-go CC=$(xx-info)-gcc STRIP=$(xx-info)-strip make static && \
   xx-verify --static runc && cp -v -a runc /out/runc.${TARGETARCH}
 
 FROM build-base-debian AS build-bypass4netns
 ARG BYPASS4NETNS_VERSION
+ARG CANARY
 ARG TARGETARCH
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/rootless-containers/bypass4netns.git /go/src/github.com/rootless-containers/bypass4netns
 WORKDIR /go/src/github.com/rootless-containers/bypass4netns
-RUN git checkout ${BYPASS4NETNS_VERSION} && \
+RUN set -eux ; git checkout ${BYPASS4NETNS_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/bypass4netns-${BYPASS4NETNS_VERSION})" ] && \
path: Dockerfile
user: login: apostasie
body: Since we are ignoring commit verification for canary, maybe we could also ignore shasum verification - that would simplify the canary script significantly (eg: not having to retrieve archives and create shasum files on the fly).
created_at: 2025-03-18T16:28:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -74,42 +79,54 @@ RUN git config --global advice.detachedHead false
 FROM build-base-debian AS build-containerd
 ARG TARGETARCH
 ARG CONTAINERD_VERSION
+ARG CANARY
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/containerd/containerd.git /go/src/github.com/containerd/containerd
 WORKDIR /go/src/github.com/containerd/containerd
-RUN git checkout ${CONTAINERD_VERSION} && \
+RUN set -eux ; git checkout ${CONTAINERD_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/containerd-${CONTAINERD_VERSION})" ] && \
   mkdir -p /out /out/$TARGETARCH && \
   cp -a containerd.service /out
 RUN GO=xx-go make STATIC=1 && \
   cp -a bin/containerd bin/containerd-shim-runc-v2 bin/ctr /out/$TARGETARCH
 
 FROM build-base-debian AS build-runc
 ARG RUNC_VERSION
+ARG CANARY
 ARG TARGETARCH
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/opencontainers/runc.git /go/src/github.com/opencontainers/runc
 WORKDIR /go/src/github.com/opencontainers/runc
-RUN git checkout ${RUNC_VERSION} && \
+RUN set -eux ; git checkout ${RUNC_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/runc-${RUNC_VERSION})" ] && \
path: Dockerfile
user: login: apostasie
body: Could we have the commits in ARGs inside the Dockerfile instead?
Maintaining separate independent files seem to increase complexity / maintenance? 

https://github.com/farcloser/lepton/blob/main/Dockerfile#L36
created_at: 2025-03-18T16:31:19Z
author_association: CONTRIBUTOR
path: Dockerfile
user: login: AkihiroSuda
body: Checking if we can have a new release of BuildKit soon as well:
- https://github.com/moby/buildkit/pull/5844#issuecomment-2735296815
created_at: 2025-03-19T06:44:55Z
author_association: MEMBER
diff_hunk: @@ -74,42 +79,54 @@ RUN git config --global advice.detachedHead false
 FROM build-base-debian AS build-containerd
 ARG TARGETARCH
 ARG CONTAINERD_VERSION
+ARG CANARY
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/containerd/containerd.git /go/src/github.com/containerd/containerd
 WORKDIR /go/src/github.com/containerd/containerd
-RUN git checkout ${CONTAINERD_VERSION} && \
+RUN set -eux ; git checkout ${CONTAINERD_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/containerd-${CONTAINERD_VERSION})" ] && \
   mkdir -p /out /out/$TARGETARCH && \
   cp -a containerd.service /out
 RUN GO=xx-go make STATIC=1 && \
   cp -a bin/containerd bin/containerd-shim-runc-v2 bin/ctr /out/$TARGETARCH
 
 FROM build-base-debian AS build-runc
 ARG RUNC_VERSION
+ARG CANARY
 ARG TARGETARCH
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/opencontainers/runc.git /go/src/github.com/opencontainers/runc
 WORKDIR /go/src/github.com/opencontainers/runc
-RUN git checkout ${RUNC_VERSION} && \
+RUN set -eux ; git checkout ${RUNC_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/runc-${RUNC_VERSION})" ] && \
path: Dockerfile
user: login: AkihiroSuda
body: We already have the checksum files for the binaries, so the maintenance cost might be just same.

Just having a single `ARG` is also useful when testing multiple containerd version. (`--build-arg CONTAINERD_VERSION=...`)
created_at: 2025-03-19T06:47:00Z
author_association: MEMBER
diff_hunk: @@ -74,42 +79,54 @@ RUN git config --global advice.detachedHead false
 FROM build-base-debian AS build-containerd
 ARG TARGETARCH
 ARG CONTAINERD_VERSION
+ARG CANARY
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/containerd/containerd.git /go/src/github.com/containerd/containerd
 WORKDIR /go/src/github.com/containerd/containerd
-RUN git checkout ${CONTAINERD_VERSION} && \
+RUN set -eux ; git checkout ${CONTAINERD_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/containerd-${CONTAINERD_VERSION})" ] && \
   mkdir -p /out /out/$TARGETARCH && \
   cp -a containerd.service /out
 RUN GO=xx-go make STATIC=1 && \
   cp -a bin/containerd bin/containerd-shim-runc-v2 bin/ctr /out/$TARGETARCH
 
 FROM build-base-debian AS build-runc
 ARG RUNC_VERSION
+ARG CANARY
 ARG TARGETARCH
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/opencontainers/runc.git /go/src/github.com/opencontainers/runc
 WORKDIR /go/src/github.com/opencontainers/runc
-RUN git checkout ${RUNC_VERSION} && \
+RUN set -eux ; git checkout ${RUNC_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/runc-${RUNC_VERSION})" ] && \
path: Dockerfile
user: login: AkihiroSuda
body: I'll update the PR to use a helper script with a single arg like `RUN git-checkout-tag-with-hash.sh v1.2.3@deadbeef`
created_at: 2025-03-19T07:32:41Z
author_association: MEMBER
diff_hunk: @@ -74,42 +79,54 @@ RUN git config --global advice.detachedHead false
 FROM build-base-debian AS build-containerd
 ARG TARGETARCH
 ARG CONTAINERD_VERSION
+ARG CANARY
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/containerd/containerd.git /go/src/github.com/containerd/containerd
 WORKDIR /go/src/github.com/containerd/containerd
-RUN git checkout ${CONTAINERD_VERSION} && \
+RUN set -eux ; git checkout ${CONTAINERD_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/containerd-${CONTAINERD_VERSION})" ] && \
   mkdir -p /out /out/$TARGETARCH && \
   cp -a containerd.service /out
 RUN GO=xx-go make STATIC=1 && \
   cp -a bin/containerd bin/containerd-shim-runc-v2 bin/ctr /out/$TARGETARCH
 
 FROM build-base-debian AS build-runc
 ARG RUNC_VERSION
+ARG CANARY
 ARG TARGETARCH
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/opencontainers/runc.git /go/src/github.com/opencontainers/runc
 WORKDIR /go/src/github.com/opencontainers/runc
-RUN git checkout ${RUNC_VERSION} && \
+RUN set -eux ; git checkout ${RUNC_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/runc-${RUNC_VERSION})" ] && \
path: Dockerfile
user: login: AkihiroSuda
body: done
created_at: 2025-03-19T13:37:05Z
author_association: MEMBER
diff_hunk: @@ -74,42 +79,54 @@ RUN git config --global advice.detachedHead false
 FROM build-base-debian AS build-containerd
 ARG TARGETARCH
 ARG CONTAINERD_VERSION
+ARG CANARY
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/containerd/containerd.git /go/src/github.com/containerd/containerd
 WORKDIR /go/src/github.com/containerd/containerd
-RUN git checkout ${CONTAINERD_VERSION} && \
+RUN set -eux ; git checkout ${CONTAINERD_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/containerd-${CONTAINERD_VERSION})" ] && \
   mkdir -p /out /out/$TARGETARCH && \
   cp -a containerd.service /out
 RUN GO=xx-go make STATIC=1 && \
   cp -a bin/containerd bin/containerd-shim-runc-v2 bin/ctr /out/$TARGETARCH
 
 FROM build-base-debian AS build-runc
 ARG RUNC_VERSION
+ARG CANARY
 ARG TARGETARCH
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/opencontainers/runc.git /go/src/github.com/opencontainers/runc
 WORKDIR /go/src/github.com/opencontainers/runc
-RUN git checkout ${RUNC_VERSION} && \
+RUN set -eux ; git checkout ${RUNC_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/runc-${RUNC_VERSION})" ] && \
   mkdir -p /out
 ENV CGO_ENABLED=1
 RUN GO=xx-go CC=$(xx-info)-gcc STRIP=$(xx-info)-strip make static && \
   xx-verify --static runc && cp -v -a runc /out/runc.${TARGETARCH}
 
 FROM build-base-debian AS build-bypass4netns
 ARG BYPASS4NETNS_VERSION
+ARG CANARY
 ARG TARGETARCH
+COPY ./Dockerfile.d/COMMITS.d/ /COMMITS.d
 RUN git clone https://github.com/rootless-containers/bypass4netns.git /go/src/github.com/rootless-containers/bypass4netns
 WORKDIR /go/src/github.com/rootless-containers/bypass4netns
-RUN git checkout ${BYPASS4NETNS_VERSION} && \
+RUN set -eux ; git checkout ${BYPASS4NETNS_VERSION} && \
+  [ "${CANARY}" = "1" -o "$(git rev-parse HEAD)" = "$(cat /COMMITS.d/bypass4netns-${BYPASS4NETNS_VERSION})" ] && \
path: Dockerfile
user: login: AkihiroSuda
body: The variable is now ignored.
Can be discussed in another issue/PR.

created_at: 2025-03-19T13:37:32Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,46 @@
+#!/bin/sh
+
+#   Copyright The containerd Authors.
+
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+
+#       http://www.apache.org/licenses/LICENSE-2.0
+
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+# This script is intended to be usable in other projects too.
+# * Must not have project-specific logics
+# * Must be compatible with bash, dash, and busybox
+
+set -eu
+if [ "$#" -ne 1 ]; then
+	echo "$0: checkout TAG with HASH, and validate it"
+	echo "Usage: $0 TAG[@HASH]"
+	exit 0
+fi
+
+: "${GIT:=git}"
+TAG="$(echo "$1" | cut -d@ -f1)"
+HASH=""
+case "$1" in
+*@*)
+	HASH="$(echo "$1" | cut -d@ -f2)"
+	;;
+esac
+
+"$GIT" checkout "$TAG"
path: hack/git-checkout-tag-with-hash.sh
user: login: apostasie
body: Could be a separate PR, but we should:
- quiet the output
- consider shallow clones instead of full checkouts (listed in #4021).

eg: `git clone --quiet --depth 1 --branch "$VERSION"`
created_at: 2025-03-19T18:23:42Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,46 @@
+#!/bin/sh
+
+#   Copyright The containerd Authors.
+
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+
+#       http://www.apache.org/licenses/LICENSE-2.0
+
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+# This script is intended to be usable in other projects too.
+# * Must not have project-specific logics
+# * Must be compatible with bash, dash, and busybox
+
+set -eu
+if [ "$#" -ne 1 ]; then
+	echo "$0: checkout TAG with HASH, and validate it"
+	echo "Usage: $0 TAG[@HASH]"
+	exit 0
+fi
+
+: "${GIT:=git}"
+TAG="$(echo "$1" | cut -d@ -f1)"
+HASH=""
+case "$1" in
+*@*)
+	HASH="$(echo "$1" | cut -d@ -f2)"
+	;;
+esac
+
+"$GIT" checkout "$TAG"
path: hack/git-checkout-tag-with-hash.sh
user: login: apostasie
body: LGTM - but if you feel like doing it in this PR, suggesting we do `quiet` and shallow clone.
created_at: 2025-03-19T18:28:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,46 @@
+#!/bin/sh
+
+#   Copyright The containerd Authors.
+
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+
+#       http://www.apache.org/licenses/LICENSE-2.0
+
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+# This script is intended to be usable in other projects too.
+# * Must not have project-specific logics
+# * Must be compatible with bash, dash, and busybox
+
+set -eu
+if [ "$#" -ne 1 ]; then
+	echo "$0: checkout TAG with HASH, and validate it"
+	echo "Usage: $0 TAG[@HASH]"
+	exit 0
+fi
+
+: "${GIT:=git}"
+TAG="$(echo "$1" | cut -d@ -f1)"
+HASH=""
+case "$1" in
+*@*)
+	HASH="$(echo "$1" | cut -d@ -f2)"
+	;;
+esac
+
+"$GIT" checkout "$TAG"
path: hack/git-checkout-tag-with-hash.sh
user: login: AkihiroSuda
body: Cloning is out of the scope of this script.
Probably dockerfile's ADD git:// instruction should be used for cache optimality 

created_at: 2025-03-19T19:17:33Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,46 @@
+#!/bin/sh
+
+#   Copyright The containerd Authors.
+
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+
+#       http://www.apache.org/licenses/LICENSE-2.0
+
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+# This script is intended to be usable in other projects too.
+# * Must not have project-specific logics
+# * Must be compatible with bash, dash, and busybox
+
+set -eu
+if [ "$#" -ne 1 ]; then
+	echo "$0: checkout TAG with HASH, and validate it"
+	echo "Usage: $0 TAG[@HASH]"
+	exit 0
+fi
+
+: "${GIT:=git}"
+TAG="$(echo "$1" | cut -d@ -f1)"
+HASH=""
+case "$1" in
+*@*)
+	HASH="$(echo "$1" | cut -d@ -f2)"
+	;;
+esac
+
+"$GIT" checkout "$TAG"
path: hack/git-checkout-tag-with-hash.sh
user: login: apostasie
body: Sure, we can discuss separately.
re: ADD.
I do not know what `ADD git://` does under the hood. Is it still only on dockerfile/labs or generally available? Also, need to check what it does wrt `quiet` and `--depth`.
created_at: 2025-03-19T19:54:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,46 @@
+#!/bin/sh
+
+#   Copyright The containerd Authors.
+
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+
+#       http://www.apache.org/licenses/LICENSE-2.0
+
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+# This script is intended to be usable in other projects too.
+# * Must not have project-specific logics
+# * Must be compatible with bash, dash, and busybox
+
+set -eu
+if [ "$#" -ne 1 ]; then
+	echo "$0: checkout TAG with HASH, and validate it"
+	echo "Usage: $0 TAG[@HASH]"
+	exit 0
+fi
+
+: "${GIT:=git}"
+TAG="$(echo "$1" | cut -d@ -f1)"
+HASH=""
+case "$1" in
+*@*)
+	HASH="$(echo "$1" | cut -d@ -f2)"
+	;;
+esac
+
+"$GIT" checkout "$TAG"
path: hack/git-checkout-tag-with-hash.sh
user: login: apostasie
body: > Cloning is out of the scope of this script.

To clarify: there should be no need for a separate `checkout` operation at all, which is why I am bringing it up here.
created_at: 2025-03-19T21:52:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,46 @@
+#!/bin/sh
+
+#   Copyright The containerd Authors.
+
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+
+#       http://www.apache.org/licenses/LICENSE-2.0
+
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+# This script is intended to be usable in other projects too.
+# * Must not have project-specific logics
+# * Must be compatible with bash, dash, and busybox
+
+set -eu
+if [ "$#" -ne 1 ]; then
+	echo "$0: checkout TAG with HASH, and validate it"
+	echo "Usage: $0 TAG[@HASH]"
+	exit 0
+fi
+
+: "${GIT:=git}"
+TAG="$(echo "$1" | cut -d@ -f1)"
+HASH=""
+case "$1" in
+*@*)
+	HASH="$(echo "$1" | cut -d@ -f2)"
+	;;
+esac
+
+"$GIT" checkout "$TAG"
path: hack/git-checkout-tag-with-hash.sh
user: login: fahedouch
body: > git clone --quiet --depth 1 --branch "$VERSION"

LGTM, the cmd is sandboxed in the ci container, no cache is left and no need to fetch the git entire history of the the tag.
created_at: 2025-03-20T09:30:32Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,46 @@
+#!/bin/sh
+
+#   Copyright The containerd Authors.
+
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+
+#       http://www.apache.org/licenses/LICENSE-2.0
+
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+# This script is intended to be usable in other projects too.
+# * Must not have project-specific logics
+# * Must be compatible with bash, dash, and busybox
+
+set -eu
+if [ "$#" -ne 1 ]; then
+	echo "$0: checkout TAG with HASH, and validate it"
+	echo "Usage: $0 TAG[@HASH]"
+	exit 0
+fi
+
+: "${GIT:=git}"
+TAG="$(echo "$1" | cut -d@ -f1)"
+HASH=""
+case "$1" in
+*@*)
+	HASH="$(echo "$1" | cut -d@ -f2)"
+	;;
+esac
+
+"$GIT" checkout "$TAG"
+HEAD="$("$GIT" rev-parse HEAD)"
+if [ -z "$HASH" ]; then
+	echo >&2 "WARNING: ${TAG}: commit hash was not specified (got ${HEAD})"
+else
+	if [ "$HEAD" != "$HASH" ]; then
+		echo >&2 "ERROR: ${TAG}: expected ${HASH}, got ${HEAD}"
+		exit 1
+	fi
+fi
path: hack/git-checkout-tag-with-hash.sh
user: login: fahedouch
body: shallow fetch makes the `else` block useless. The following `cond` is always true:
  `"$HEAD" == "$HASH"` 
created_at: 2025-03-20T09:31:46Z
author_association: MEMBER
diff_hunk: @@ -15,42 +15,42 @@
 # -----------------------------------------------------------------------------
 # Usage: `docker run -it --privileged <IMAGE>`. Make sure to add `-t` and `--privileged`.
 
-# TODO: verify commit hash
-
 # Basic deps
-ARG CONTAINERD_VERSION=v2.0.3
-ARG RUNC_VERSION=v1.2.5
-ARG CNI_PLUGINS_VERSION=v1.6.2
+# @BINARY: the binary checksums are verified via Dockerfile.d/SHA256SUMS.d/<COMPONENT>-<VERSION>
+ARG CONTAINERD_VERSION=v2.0.4@1a43cb6a1035441f9aca8f5666a9b3ef9e70ab20
+ARG RUNC_VERSION=v1.2.6@e89a29929c775025419ab0d218a43588b4c12b9a
+ARG CNI_PLUGINS_VERSION=v1.6.2@BINARY
path: Dockerfile
user: login: fahedouch
body: (not blocker) a comment to mention that module is `BINARY` is not enough ?
created_at: 2025-03-20T09:38:58Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,46 @@
+#!/bin/sh
+
+#   Copyright The containerd Authors.
+
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+
+#       http://www.apache.org/licenses/LICENSE-2.0
+
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+# This script is intended to be usable in other projects too.
+# * Must not have project-specific logics
+# * Must be compatible with bash, dash, and busybox
+
+set -eu
+if [ "$#" -ne 1 ]; then
+	echo "$0: checkout TAG with HASH, and validate it"
+	echo "Usage: $0 TAG[@HASH]"
+	exit 0
+fi
+
+: "${GIT:=git}"
+TAG="$(echo "$1" | cut -d@ -f1)"
+HASH=""
+case "$1" in
+*@*)
+	HASH="$(echo "$1" | cut -d@ -f2)"
+	;;
+esac
+
+"$GIT" checkout "$TAG"
path: hack/git-checkout-tag-with-hash.sh
user: login: AkihiroSuda
body: `ADD git://` is available 
since 2022 (https://github.com/moby/buildkit/pull/2799) and out of experimental since 2023 (https://github.com/moby/buildkit/pull/3979)

https://docs.docker.com/reference/dockerfile/#adding-files-from-a-git-repository

This might be more cache-efficient when running tests with several containerd versions
created_at: 2025-03-20T14:14:45Z
author_association: MEMBER
diff_hunk: @@ -15,42 +15,42 @@
 # -----------------------------------------------------------------------------
 # Usage: `docker run -it --privileged <IMAGE>`. Make sure to add `-t` and `--privileged`.
 
-# TODO: verify commit hash
-
 # Basic deps
-ARG CONTAINERD_VERSION=v2.0.3
-ARG RUNC_VERSION=v1.2.5
-ARG CNI_PLUGINS_VERSION=v1.6.2
+# @BINARY: the binary checksums are verified via Dockerfile.d/SHA256SUMS.d/<COMPONENT>-<VERSION>
+ARG CONTAINERD_VERSION=v2.0.4@1a43cb6a1035441f9aca8f5666a9b3ef9e70ab20
+ARG RUNC_VERSION=v1.2.6@e89a29929c775025419ab0d218a43588b4c12b9a
+ARG CNI_PLUGINS_VERSION=v1.6.2@BINARY
path: Dockerfile
user: login: AkihiroSuda
body: What do you mean?
created_at: 2025-03-20T14:15:26Z
author_association: MEMBER
diff_hunk: @@ -15,42 +15,42 @@
 # -----------------------------------------------------------------------------
 # Usage: `docker run -it --privileged <IMAGE>`. Make sure to add `-t` and `--privileged`.
 
-# TODO: verify commit hash
-
 # Basic deps
-ARG CONTAINERD_VERSION=v2.0.3
-ARG RUNC_VERSION=v1.2.5
-ARG CNI_PLUGINS_VERSION=v1.6.2
+# @BINARY: the binary checksums are verified via Dockerfile.d/SHA256SUMS.d/<COMPONENT>-<VERSION>
+ARG CONTAINERD_VERSION=v2.0.4@1a43cb6a1035441f9aca8f5666a9b3ef9e70ab20
+ARG RUNC_VERSION=v1.2.6@e89a29929c775025419ab0d218a43588b4c12b9a
+ARG CNI_PLUGINS_VERSION=v1.6.2@BINARY
path: Dockerfile
user: login: fahedouch
body: the `@BINARY` suffix is ​​a bit disturbing
created_at: 2025-03-20T14:32:37Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,46 @@
+#!/bin/sh
+
+#   Copyright The containerd Authors.
+
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+
+#       http://www.apache.org/licenses/LICENSE-2.0
+
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+# This script is intended to be usable in other projects too.
+# * Must not have project-specific logics
+# * Must be compatible with bash, dash, and busybox
+
+set -eu
+if [ "$#" -ne 1 ]; then
+	echo "$0: checkout TAG with HASH, and validate it"
+	echo "Usage: $0 TAG[@HASH]"
+	exit 0
+fi
+
+: "${GIT:=git}"
+TAG="$(echo "$1" | cut -d@ -f1)"
+HASH=""
+case "$1" in
+*@*)
+	HASH="$(echo "$1" | cut -d@ -f2)"
+	;;
+esac
+
+"$GIT" checkout "$TAG"
path: hack/git-checkout-tag-with-hash.sh
user: login: apostasie
body: Moving that part of the conversation to #4022
created_at: 2025-03-20T14:51:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,46 @@
+#!/bin/sh
+
+#   Copyright The containerd Authors.
+
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+
+#       http://www.apache.org/licenses/LICENSE-2.0
+
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+# This script is intended to be usable in other projects too.
+# * Must not have project-specific logics
+# * Must be compatible with bash, dash, and busybox
+
+set -eu
+if [ "$#" -ne 1 ]; then
+	echo "$0: checkout TAG with HASH, and validate it"
+	echo "Usage: $0 TAG[@HASH]"
+	exit 0
+fi
+
+: "${GIT:=git}"
+TAG="$(echo "$1" | cut -d@ -f1)"
+HASH=""
+case "$1" in
+*@*)
+	HASH="$(echo "$1" | cut -d@ -f2)"
+	;;
+esac
+
+"$GIT" checkout "$TAG"
+HEAD="$("$GIT" rev-parse HEAD)"
+if [ -z "$HASH" ]; then
+	echo >&2 "WARNING: ${TAG}: commit hash was not specified (got ${HEAD})"
+else
+	if [ "$HEAD" != "$HASH" ]; then
+		echo >&2 "ERROR: ${TAG}: expected ${HASH}, got ${HEAD}"
+		exit 1
+	fi
+fi
path: hack/git-checkout-tag-with-hash.sh
user: login: AkihiroSuda
body: Doesn't seem so?

```bash
$ git clone --depth 1 --branch v2.0.4 https://github.com/containerd/containerd
$ cd containerd
$ ~/gopath/src/github.com/containerd/nerdctl/hack/git-checkout-tag-with-hash.sh v2.0.4@wrong-hash
HEAD is now at 1a43cb6 Merge commit from fork
ERROR: v2.0.4: expected wrong-hash, got 1a43cb6a1035441f9aca8f5666a9b3ef9e70ab20
```
created_at: 2025-03-20T14:55:53Z
author_association: MEMBER

PR comments:
user: login: fahedouch
created_at: 2025-03-20T09:44:34Z
body: There are people waiting for the release, let's focus on `v2.0.4` and then address all this refactoring later please
author_association: MEMBER
user: login: apostasie
created_at: 2025-03-20T14:44:23Z
body: > There are people waiting for the release, let's focus on `v2.0.4` and then address all this refactoring later please

Suggesting we just merge this now.
It does bring in important updates, and is good enough in its current shape.
We can refine the controversial bits later.
author_association: CONTRIBUTOR
user: login: AkihiroSuda
created_at: 2025-03-20T14:56:27Z
body: Merging and making a release, but we will probably to make another new release soon with a new release of BuildKit

author_association: MEMBER