adding some support for annotations at the manifest level
Signed-off-by: Mike Brown <brownwm@us.ibm.com>master
							parent
							
								
									ec2aa05cdf
								
							
						
					
					
						commit
						f186e1da1c
					
				|  | @ -18,15 +18,19 @@ type builder struct { | ||||||
| 	// layers is a list of layer descriptors that gets built by successive
 | 	// layers is a list of layer descriptors that gets built by successive
 | ||||||
| 	// calls to AppendReference.
 | 	// calls to AppendReference.
 | ||||||
| 	layers []distribution.Descriptor | 	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
 | // NewManifestBuilder is used to build new manifests for the current schema
 | ||||||
| // version. It takes a BlobService so it can publish the configuration blob
 | // version. It takes a BlobService so it can publish the configuration blob
 | ||||||
| // as part of the Build process.
 | // as part of the Build process, and annotations.
 | ||||||
| func NewManifestBuilder(bs distribution.BlobService, configJSON []byte) distribution.ManifestBuilder { | func NewManifestBuilder(bs distribution.BlobService, configJSON []byte, annotations map[string]string) distribution.ManifestBuilder { | ||||||
| 	mb := &builder{ | 	mb := &builder{ | ||||||
| 		bs:          bs, | 		bs:          bs, | ||||||
| 		configJSON:  make([]byte, len(configJSON)), | 		configJSON:  make([]byte, len(configJSON)), | ||||||
|  | 		annotations: annotations, | ||||||
| 	} | 	} | ||||||
| 	copy(mb.configJSON, configJSON) | 	copy(mb.configJSON, configJSON) | ||||||
| 
 | 
 | ||||||
|  | @ -38,6 +42,7 @@ func (mb *builder) Build(ctx context.Context) (distribution.Manifest, error) { | ||||||
| 	m := Manifest{ | 	m := Manifest{ | ||||||
| 		Versioned:   SchemaVersion, | 		Versioned:   SchemaVersion, | ||||||
| 		Layers:      make([]distribution.Descriptor, len(mb.layers)), | 		Layers:      make([]distribution.Descriptor, len(mb.layers)), | ||||||
|  | 		Annotations: mb.annotations, | ||||||
| 	} | 	} | ||||||
| 	copy(m.Layers, mb.layers) | 	copy(m.Layers, mb.layers) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -88,6 +88,9 @@ func TestBuilder(t *testing.T) { | ||||||
|       ], |       ], | ||||||
|       "type": "layers" |       "type": "layers" | ||||||
|     }, |     }, | ||||||
|  |     "annotations": { | ||||||
|  |        "hot": "potato" | ||||||
|  |     } | ||||||
|     "history": [ |     "history": [ | ||||||
|       { |       { | ||||||
|         "created": "2015-10-31T22:22:54.690851953Z", |         "created": "2015-10-31T22:22:54.690851953Z", | ||||||
|  | @ -120,9 +123,10 @@ func TestBuilder(t *testing.T) { | ||||||
| 			MediaType: v1.MediaTypeImageLayerGzip, | 			MediaType: v1.MediaTypeImageLayerGzip, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  | 	annotations := map[string]string{"hot": "potato"} | ||||||
| 
 | 
 | ||||||
| 	bs := &mockBlobService{descriptors: make(map[digest.Digest]distribution.Descriptor)} | 	bs := &mockBlobService{descriptors: make(map[digest.Digest]distribution.Descriptor)} | ||||||
| 	builder := NewManifestBuilder(bs, imgJSON) | 	builder := NewManifestBuilder(bs, imgJSON, annotations) | ||||||
| 
 | 
 | ||||||
| 	for _, d := range descriptors { | 	for _, d := range descriptors { | ||||||
| 		if err := builder.AppendReference(d); err != nil { | 		if err := builder.AppendReference(d); err != nil { | ||||||
|  | @ -142,6 +146,9 @@ func TestBuilder(t *testing.T) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	manifest := built.(*DeserializedManifest).Manifest | 	manifest := built.(*DeserializedManifest).Manifest | ||||||
|  | 	if manifest.Annotations["hot"] != "potato" { | ||||||
|  | 		t.Fatalf("unexpected annotation in manifest: %s", manifest.Annotations["hot"]) | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	if manifest.Versioned.SchemaVersion != 2 { | 	if manifest.Versioned.SchemaVersion != 2 { | ||||||
| 		t.Fatal("SchemaVersion != 2") | 		t.Fatal("SchemaVersion != 2") | ||||||
|  | @ -154,7 +161,7 @@ func TestBuilder(t *testing.T) { | ||||||
| 	if target.MediaType != v1.MediaTypeImageConfig { | 	if target.MediaType != v1.MediaTypeImageConfig { | ||||||
| 		t.Fatalf("unexpected media type in target: %s", target.MediaType) | 		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) | 		t.Fatalf("unexpected size in target: %d", target.Size) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,7 +10,6 @@ import ( | ||||||
| 	"github.com/opencontainers/image-spec/specs-go/v1" | 	"github.com/opencontainers/image-spec/specs-go/v1" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // TODO (mikebrow): add annotations to the test
 |  | ||||||
| var expectedManifestSerialization = []byte(`{ | var expectedManifestSerialization = []byte(`{ | ||||||
|    "schemaVersion": 2, |    "schemaVersion": 2, | ||||||
|    "mediaType": "application/vnd.oci.image.manifest.v1+json", |    "mediaType": "application/vnd.oci.image.manifest.v1+json", | ||||||
|  | @ -31,7 +30,10 @@ var expectedManifestSerialization = []byte(`{ | ||||||
|             "lettuce": "wrap" |             "lettuce": "wrap" | ||||||
|          } |          } | ||||||
|       } |       } | ||||||
|    ] |    ], | ||||||
|  |    "annotations": { | ||||||
|  |       "hot": "potato" | ||||||
|  |    } | ||||||
| }`) | }`) | ||||||
| 
 | 
 | ||||||
| func TestManifest(t *testing.T) { | func TestManifest(t *testing.T) { | ||||||
|  | @ -51,6 +53,7 @@ func TestManifest(t *testing.T) { | ||||||
| 				Annotations: map[string]string{"lettuce": "wrap"}, | 				Annotations: map[string]string{"lettuce": "wrap"}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
|  | 		Annotations: map[string]string{"hot": "potato"}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	deserialized, err := FromStruct(manifest) | 	deserialized, err := FromStruct(manifest) | ||||||
|  | @ -87,6 +90,9 @@ func TestManifest(t *testing.T) { | ||||||
| 	if !reflect.DeepEqual(&unmarshalled, deserialized) { | 	if !reflect.DeepEqual(&unmarshalled, deserialized) { | ||||||
| 		t.Fatalf("manifests are different after unmarshaling: %v != %v", 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() | 	target := deserialized.Target() | ||||||
| 	if target.Digest != "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b" { | 	if target.Digest != "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b" { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue