adds support for oci manifests and manifestlists
Signed-off-by: Mike Brown <brownwm@us.ibm.com>
This commit is contained in:
parent
749f6afb45
commit
9986e8ca7c
10 changed files with 957 additions and 62 deletions
|
@ -7,11 +7,17 @@ import (
|
|||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/manifest"
|
||||
"github.com/docker/distribution/manifest/ocischema"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// MediaTypeManifestList specifies the mediaType for manifest lists.
|
||||
const MediaTypeManifestList = "application/vnd.docker.distribution.manifest.list.v2+json"
|
||||
const (
|
||||
// MediaTypeManifestList specifies the mediaType for manifest lists.
|
||||
MediaTypeManifestList = "application/vnd.docker.distribution.manifest.list.v2+json"
|
||||
// MediaTypeOCIManifestList specifies the mediaType for OCI compliant manifest
|
||||
// lists.
|
||||
MediaTypeOCIManifestList = "application/vnd.oci.image.manifest.list.v1+json"
|
||||
)
|
||||
|
||||
// SchemaVersion provides a pre-initialized version structure for this
|
||||
// packages version of the manifest.
|
||||
|
@ -20,6 +26,13 @@ var SchemaVersion = manifest.Versioned{
|
|||
MediaType: MediaTypeManifestList,
|
||||
}
|
||||
|
||||
// OCISchemaVersion provides a pre-initialized version structure for this
|
||||
// packages OCIschema version of the manifest.
|
||||
var OCISchemaVersion = manifest.Versioned{
|
||||
SchemaVersion: 2,
|
||||
MediaType: MediaTypeOCIManifestList,
|
||||
}
|
||||
|
||||
func init() {
|
||||
manifestListFunc := func(b []byte) (distribution.Manifest, distribution.Descriptor, error) {
|
||||
m := new(DeserializedManifestList)
|
||||
|
@ -105,8 +118,15 @@ type DeserializedManifestList struct {
|
|||
// DeserializedManifestList which contains the resulting manifest list
|
||||
// and its JSON representation.
|
||||
func FromDescriptors(descriptors []ManifestDescriptor) (*DeserializedManifestList, error) {
|
||||
m := ManifestList{
|
||||
Versioned: SchemaVersion,
|
||||
var m ManifestList
|
||||
if len(descriptors) > 0 && descriptors[0].Descriptor.MediaType == ocischema.MediaTypeManifest {
|
||||
m = ManifestList{
|
||||
Versioned: OCISchemaVersion,
|
||||
}
|
||||
} else {
|
||||
m = ManifestList{
|
||||
Versioned: SchemaVersion,
|
||||
}
|
||||
}
|
||||
|
||||
m.Manifests = make([]ManifestDescriptor, len(descriptors), len(descriptors))
|
||||
|
|
|
@ -69,7 +69,7 @@ func TestManifestList(t *testing.T) {
|
|||
t.Fatalf("error creating DeserializedManifestList: %v", err)
|
||||
}
|
||||
|
||||
mediaType, canonical, err := deserialized.Payload()
|
||||
mediaType, canonical, _ := deserialized.Payload()
|
||||
|
||||
if mediaType != MediaTypeManifestList {
|
||||
t.Fatalf("unexpected media type: %s", mediaType)
|
||||
|
@ -109,3 +109,104 @@ func TestManifestList(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
var expectedOCIManifestListSerialization = []byte(`{
|
||||
"schemaVersion": 2,
|
||||
"mediaType": "application/vnd.oci.image.manifest.list.v1+json",
|
||||
"manifests": [
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 985,
|
||||
"digest": "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b",
|
||||
"platform": {
|
||||
"architecture": "amd64",
|
||||
"os": "linux",
|
||||
"features": [
|
||||
"sse4"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.oci.image.manifest.v1+json",
|
||||
"size": 2392,
|
||||
"digest": "sha256:6346340964309634683409684360934680934608934608934608934068934608",
|
||||
"platform": {
|
||||
"architecture": "sun4m",
|
||||
"os": "sunos"
|
||||
}
|
||||
}
|
||||
]
|
||||
}`)
|
||||
|
||||
func TestOCIManifestList(t *testing.T) {
|
||||
manifestDescriptors := []ManifestDescriptor{
|
||||
{
|
||||
Descriptor: distribution.Descriptor{
|
||||
Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b",
|
||||
Size: 985,
|
||||
MediaType: "application/vnd.oci.image.manifest.v1+json",
|
||||
},
|
||||
Platform: PlatformSpec{
|
||||
Architecture: "amd64",
|
||||
OS: "linux",
|
||||
Features: []string{"sse4"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Descriptor: distribution.Descriptor{
|
||||
Digest: "sha256:6346340964309634683409684360934680934608934608934608934068934608",
|
||||
Size: 2392,
|
||||
MediaType: "application/vnd.oci.image.manifest.v1+json",
|
||||
},
|
||||
Platform: PlatformSpec{
|
||||
Architecture: "sun4m",
|
||||
OS: "sunos",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
deserialized, err := FromDescriptors(manifestDescriptors)
|
||||
if err != nil {
|
||||
t.Fatalf("error creating DeserializedManifestList: %v", err)
|
||||
}
|
||||
|
||||
mediaType, canonical, _ := deserialized.Payload()
|
||||
|
||||
if mediaType != MediaTypeOCIManifestList {
|
||||
t.Fatalf("unexpected media type: %s", mediaType)
|
||||
}
|
||||
|
||||
// Check that the canonical field is the same as json.MarshalIndent
|
||||
// with these parameters.
|
||||
p, err := json.MarshalIndent(&deserialized.ManifestList, "", " ")
|
||||
if err != nil {
|
||||
t.Fatalf("error marshaling manifest list: %v", err)
|
||||
}
|
||||
if !bytes.Equal(p, canonical) {
|
||||
t.Fatalf("manifest bytes not equal: %q != %q", string(canonical), string(p))
|
||||
}
|
||||
|
||||
// Check that the canonical field has the expected value.
|
||||
if !bytes.Equal(expectedOCIManifestListSerialization, canonical) {
|
||||
t.Fatalf("manifest bytes not equal: %q != %q", string(canonical), string(expectedOCIManifestListSerialization))
|
||||
}
|
||||
|
||||
var unmarshalled DeserializedManifestList
|
||||
if err := json.Unmarshal(deserialized.canonical, &unmarshalled); err != nil {
|
||||
t.Fatalf("error unmarshaling manifest: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(&unmarshalled, deserialized) {
|
||||
t.Fatalf("manifests are different after unmarshaling: %v != %v", unmarshalled, *deserialized)
|
||||
}
|
||||
|
||||
references := deserialized.References()
|
||||
if len(references) != 2 {
|
||||
t.Fatalf("unexpected number of references: %d", len(references))
|
||||
}
|
||||
for i := range references {
|
||||
if !reflect.DeepEqual(references[i], manifestDescriptors[i].Descriptor) {
|
||||
t.Fatalf("unexpected value %d returned by References: %v", i, references[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue