Pārlūkot izejas kodu

Use docker media type for plugin layers

This was changed as part of a refactor to use containerd dist code. The
problem is the OCI media types are not compatible with older versions of
Docker.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Brian Goff 4 gadi atpakaļ
vecāks
revīzija
a876ede24f
2 mainītis faili ar 64 papildinājumiem un 1 dzēšanām
  1. 63 0
      integration/plugin/common/plugin_test.go
  2. 1 1
      plugin/backend_linux.go

+ 63 - 0
integration/plugin/common/plugin_test.go

@@ -15,12 +15,17 @@ import (
 	"strings"
 	"testing"
 
+	"github.com/containerd/containerd/images"
+	"github.com/containerd/containerd/remotes/docker"
 	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/pkg/jsonmessage"
 	"github.com/docker/docker/testutil/daemon"
 	"github.com/docker/docker/testutil/fixtures/plugin"
 	"github.com/docker/docker/testutil/registry"
 	"github.com/docker/docker/testutil/request"
+	v1 "github.com/opencontainers/image-spec/specs-go/v1"
 	"gotest.tools/v3/assert"
+	"gotest.tools/v3/assert/cmp"
 	is "gotest.tools/v3/assert/cmp"
 	"gotest.tools/v3/skip"
 )
@@ -223,3 +228,61 @@ func TestPluginsWithRuntimes(t *testing.T) {
 		assert.NilError(t, err)
 	})
 }
+
+func TestPluginBackCompatMediaTypes(t *testing.T) {
+	skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon")
+	skip.If(t, testEnv.OSType == "windows")
+	skip.If(t, testEnv.IsRootless, "Rootless has a different view of localhost (needed for test registry access)")
+
+	defer setupTest(t)()
+
+	reg := registry.NewV2(t)
+	defer reg.Close()
+	reg.WaitReady(t)
+
+	repo := path.Join(registry.DefaultURL, strings.ToLower(t.Name())+":latest")
+
+	client := testEnv.APIClient()
+
+	ctx := context.Background()
+	assert.NilError(t, plugin.Create(ctx, client, repo))
+
+	rdr, err := client.PluginPush(ctx, repo, "")
+	assert.NilError(t, err)
+	defer rdr.Close()
+
+	buf := &strings.Builder{}
+	assert.NilError(t, jsonmessage.DisplayJSONMessagesStream(rdr, buf, 0, false, nil), buf)
+
+	// Use custom header here because older versions of the registry do not
+	// parse the accept header correctly and does not like the accept header
+	// that the default resolver code uses. "Older registries" here would be
+	// like the one currently included in the test suite.
+	headers := http.Header{}
+	headers.Add("Accept", images.MediaTypeDockerSchema2Manifest)
+
+	resolver := docker.NewResolver(docker.ResolverOptions{
+		Headers: headers,
+	})
+	assert.NilError(t, err)
+
+	n, desc, err := resolver.Resolve(ctx, repo)
+	assert.NilError(t, err, repo)
+
+	fetcher, err := resolver.Fetcher(ctx, n)
+	assert.NilError(t, err)
+
+	rdr, err = fetcher.Fetch(ctx, desc)
+	assert.NilError(t, err)
+	defer rdr.Close()
+
+	type manifest struct {
+		MediaType string
+		v1.Manifest
+	}
+	var m manifest
+	assert.NilError(t, json.NewDecoder(rdr).Decode(&m))
+	assert.Check(t, cmp.Equal(m.MediaType, images.MediaTypeDockerSchema2Manifest))
+	assert.Check(t, cmp.Len(m.Layers, 1))
+	assert.Check(t, cmp.Equal(m.Layers[0].MediaType, images.MediaTypeDockerSchema2LayerGzip))
+}

+ 1 - 1
plugin/backend_linux.go

@@ -492,7 +492,7 @@ func buildManifest(ctx context.Context, s content.Manager, config digest.Digest,
 			return m, errors.Wrapf(err, "error fetching info for content digest %s", l)
 		}
 		m.Layers = append(m.Layers, specs.Descriptor{
-			MediaType: specs.MediaTypeImageLayerGzip, // TODO: This is assuming everything is a gzip compressed layer, but that may not be true.
+			MediaType: images.MediaTypeDockerSchema2LayerGzip, // TODO: This is assuming everything is a gzip compressed layer, but that may not be true.
 			Digest:    l,
 			Size:      info.Size,
 		})