integration: Fix TestImageLoad() failure on CI

If docker in the host is configured to use the containerd image format,
then the docker pull/save commands above download the multi-platform
image. IOW, the index.json has references to the other platforms SHAs.

This references to things that are not present (the artifacts for other
platforms) is what make `ctr` fail. However, if we specify a platform,
then ctr ignores the other platforms and the import works just fine.

To try this locally, you can:
	$ docker pull ghcr.io/containerd/busybox:1.36
	$ docker save ghcr.io/containerd/busybox:1.36 -o image.tar
	$ ctr images import --local=true image.tar

The last command will fail if you are using the containerd image store
in docker. If you specify the platform with --platform, it works fine.

With docker overlayfs2 storage driver, if you untar the image you get only
things relevant for your platform:

```
$ cat index.json | jq
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:4d6b13f2ddbe87da8d9dee3719df1723a6d768e511802e70d42ab15370c6eb24",
      "size": 401,
      "annotations": {
        "io.containerd.image.name": "ghcr.io/containerd/busybox:1.36",
        "org.opencontainers.image.ref.name": "1.36"
      }
    }
  ]
}
$ cat blobs/sha256/4d6b13f2ddbe87da8d9dee3719df1723a6d768e511802e70d42ab15370c6eb24 | jq
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:66ba00ad3de8677a3fa4bc4ea0fc46ebca0f14db46ca365e7f60833068dd0148",
    "size": 1457
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar",
      "digest": "sha256:b64792c17e4ad443d16b218afb3a8f5d03ca0f4ec49b11c1a7aebe17f6c3c1d2",
      "size": 5096448
    }
  ]
}
```

But with the other you get for lot of other platforms too:

```

$ cat index.json | jq
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "manifests": [
    {
      "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
      "digest": "sha256:7b3ccabffc97de872a30dfd234fd972a66d247c8cfc69b0550f276481852627c",
      "size": 2295,
      "annotations": {
        "containerd.io/distribution.source.ghcr.io": "containerd/busybox",
        "io.containerd.image.name": "ghcr.io/containerd/busybox:1.36",
        "org.opencontainers.image.ref.name": "1.36"
      }
    }
  ]
}
$ cat blobs/sha256/7b3ccabffc97de872a30dfd234fd972a66d247c8cfc69b0550f276481852627c | jq
{
  "manifests": [
    {
      "digest": "sha256:907ca53d7e2947e849b839b1cd258c98fd3916c60f2e6e70c30edbf741ab6754",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      },
      "size": 528
    },
    {
      "digest": "sha256:dde8e930c7b6a490f728e66292bc9bce42efc9bbb5278bae40e4f30f6e00fe8c",
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "platform": {
        "architecture": "arm",
        "os": "linux",
        "variant": "v5"
      },
      "size": 528
    },
    {
    ...
```

You can switch to the containerd snapshotter in docker by adding this to the daemon.json:
```
{
  "features": {
    "containerd-snapshotter": true
  }
}

```

Signed-off-by: Rodrigo Campos <rodrigo@amutable.com>
(cherry picked from commit fafbfcb8c7)
Signed-off-by: Samuel Karp <samuelkarp@google.com>
This commit is contained in:
Rodrigo Campos
2026-02-16 12:03:54 +01:00
committed by Samuel Karp
parent bfee299990
commit c71c4a091a

View File

@@ -67,8 +67,15 @@ func TestImageLoad(t *testing.T) {
require.NoError(t, err, "ctr should be installed, make sure you've run `make install-deps`")
// Add --local=true option since currently the transfer service
// does not provide enough progress to avoid timeout
// and --platform to only check for manifests for this platform. The "ctr image import"
// command otherwise might fail, if the above docker commands use the containerd image
// store, as in that case `docker save` produces OCI artifacts referencing manifests for
// other platforms that are not included in what we downloaded. By specifying a platform, we
// just ignore the references to other platforms.
platform := "--platform=" + goruntime.GOOS + "/" + goruntime.GOARCH
output, err = exec.Command(ctr, "-address="+containerdEndpoint,
"-n=k8s.io", "images", "import", "--local=true", tar).CombinedOutput()
"-n=k8s.io", "images", "import", "--local=true",
platform, tar).CombinedOutput()
require.NoError(t, err, "output: %q", output)
t.Logf("make sure image is loaded")