adding some support for annotations at the manifest level

Signed-off-by: Mike Brown <brownwm@us.ibm.com>
This commit is contained in:
Mike Brown 2017-07-31 18:34:11 -05:00
parent ec2aa05cdf
commit f186e1da1c
3 changed files with 28 additions and 10 deletions

View file

@ -18,15 +18,19 @@ type builder struct {
// layers is a list of layer descriptors that gets built by successive
// calls to AppendReference.
layers []distribution.Descriptor
// Annotations contains arbitrary metadata relating to the targeted content.
annotations map[string]string
}
// NewManifestBuilder is used to build new manifests for the current schema
// version. It takes a BlobService so it can publish the configuration blob
// as part of the Build process.
func NewManifestBuilder(bs distribution.BlobService, configJSON []byte) distribution.ManifestBuilder {
// as part of the Build process, and annotations.
func NewManifestBuilder(bs distribution.BlobService, configJSON []byte, annotations map[string]string) distribution.ManifestBuilder {
mb := &builder{
bs: bs,
configJSON: make([]byte, len(configJSON)),
bs: bs,
configJSON: make([]byte, len(configJSON)),
annotations: annotations,
}
copy(mb.configJSON, configJSON)
@ -36,8 +40,9 @@ func NewManifestBuilder(bs distribution.BlobService, configJSON []byte) distribu
// Build produces a final manifest from the given references.
func (mb *builder) Build(ctx context.Context) (distribution.Manifest, error) {
m := Manifest{
Versioned: SchemaVersion,
Layers: make([]distribution.Descriptor, len(mb.layers)),
Versioned: SchemaVersion,
Layers: make([]distribution.Descriptor, len(mb.layers)),
Annotations: mb.annotations,
}
copy(m.Layers, mb.layers)

View file

@ -88,6 +88,9 @@ func TestBuilder(t *testing.T) {
],
"type": "layers"
},
"annotations": {
"hot": "potato"
}
"history": [
{
"created": "2015-10-31T22:22:54.690851953Z",
@ -120,9 +123,10 @@ func TestBuilder(t *testing.T) {
MediaType: v1.MediaTypeImageLayerGzip,
},
}
annotations := map[string]string{"hot": "potato"}
bs := &mockBlobService{descriptors: make(map[digest.Digest]distribution.Descriptor)}
builder := NewManifestBuilder(bs, imgJSON)
builder := NewManifestBuilder(bs, imgJSON, annotations)
for _, d := range descriptors {
if err := builder.AppendReference(d); err != nil {
@ -142,6 +146,9 @@ func TestBuilder(t *testing.T) {
}
manifest := built.(*DeserializedManifest).Manifest
if manifest.Annotations["hot"] != "potato" {
t.Fatalf("unexpected annotation in manifest: %s", manifest.Annotations["hot"])
}
if manifest.Versioned.SchemaVersion != 2 {
t.Fatal("SchemaVersion != 2")
@ -154,7 +161,7 @@ func TestBuilder(t *testing.T) {
if target.MediaType != v1.MediaTypeImageConfig {
t.Fatalf("unexpected media type in target: %s", target.MediaType)
}
if target.Size != 1582 {
if target.Size != 1632 {
t.Fatalf("unexpected size in target: %d", target.Size)
}

View file

@ -10,7 +10,6 @@ import (
"github.com/opencontainers/image-spec/specs-go/v1"
)
// TODO (mikebrow): add annotations to the test
var expectedManifestSerialization = []byte(`{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
@ -31,7 +30,10 @@ var expectedManifestSerialization = []byte(`{
"lettuce": "wrap"
}
}
]
],
"annotations": {
"hot": "potato"
}
}`)
func TestManifest(t *testing.T) {
@ -51,6 +53,7 @@ func TestManifest(t *testing.T) {
Annotations: map[string]string{"lettuce": "wrap"},
},
},
Annotations: map[string]string{"hot": "potato"},
}
deserialized, err := FromStruct(manifest)
@ -87,6 +90,9 @@ func TestManifest(t *testing.T) {
if !reflect.DeepEqual(&unmarshalled, deserialized) {
t.Fatalf("manifests are different after unmarshaling: %v != %v", unmarshalled, *deserialized)
}
if deserialized.Annotations["hot"] != "potato" {
t.Fatalf("unexpected annotation in manifest: %s", deserialized.Annotations["hot"])
}
target := deserialized.Target()
if target.Digest != "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b" {