Merge pull request #1775 from dmcgowan/get-content-digest
Add option to get content digest from manifest getmaster
						commit
						3b1b58e9c5
					
				|  | @ -394,11 +394,26 @@ func (o etagOption) Apply(ms distribution.ManifestService) error { | |||
| 	return fmt.Errorf("etag options is a client-only option") | ||||
| } | ||||
| 
 | ||||
| // ReturnContentDigest allows a client to set a the content digest on
 | ||||
| // a successful request from the 'Docker-Content-Digest' header. This
 | ||||
| // returned digest is represents the digest which the registry uses
 | ||||
| // to refer to the content and can be used to delete the content.
 | ||||
| func ReturnContentDigest(dgst *digest.Digest) distribution.ManifestServiceOption { | ||||
| 	return contentDigestOption{dgst} | ||||
| } | ||||
| 
 | ||||
| type contentDigestOption struct{ digest *digest.Digest } | ||||
| 
 | ||||
| func (o contentDigestOption) Apply(ms distribution.ManifestService) error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (ms *manifests) Get(ctx context.Context, dgst digest.Digest, options ...distribution.ManifestServiceOption) (distribution.Manifest, error) { | ||||
| 	var ( | ||||
| 		digestOrTag string | ||||
| 		ref         reference.Named | ||||
| 		err         error | ||||
| 		contentDgst *digest.Digest | ||||
| 	) | ||||
| 
 | ||||
| 	for _, option := range options { | ||||
|  | @ -408,6 +423,8 @@ func (ms *manifests) Get(ctx context.Context, dgst digest.Digest, options ...dis | |||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 		} else if opt, ok := option.(contentDigestOption); ok { | ||||
| 			contentDgst = opt.digest | ||||
| 		} else { | ||||
| 			err := option.Apply(ms) | ||||
| 			if err != nil { | ||||
|  | @ -450,6 +467,12 @@ func (ms *manifests) Get(ctx context.Context, dgst digest.Digest, options ...dis | |||
| 	if resp.StatusCode == http.StatusNotModified { | ||||
| 		return nil, distribution.ErrManifestNotModified | ||||
| 	} else if SuccessStatus(resp.StatusCode) { | ||||
| 		if contentDgst != nil { | ||||
| 			dgst, err := digest.ParseDigest(resp.Header.Get("Docker-Content-Digest")) | ||||
| 			if err == nil { | ||||
| 				*contentDgst = dgst | ||||
| 			} | ||||
| 		} | ||||
| 		mt := resp.Header.Get("Content-Type") | ||||
| 		body, err := ioutil.ReadAll(resp.Body) | ||||
| 
 | ||||
|  |  | |||
|  | @ -605,6 +605,14 @@ func addTestManifestWithEtag(repo reference.Named, reference string, content []b | |||
| 	*m = append(*m, testutil.RequestResponseMapping{Request: getReqWithEtag, Response: getRespWithEtag}) | ||||
| } | ||||
| 
 | ||||
| func contentDigestString(mediatype string, content []byte) string { | ||||
| 	if mediatype == schema1.MediaTypeSignedManifest { | ||||
| 		m, _, _ := distribution.UnmarshalManifest(mediatype, content) | ||||
| 		content = m.(*schema1.SignedManifest).Canonical | ||||
| 	} | ||||
| 	return digest.Canonical.FromBytes(content).String() | ||||
| } | ||||
| 
 | ||||
| func addTestManifest(repo reference.Named, reference string, mediatype string, content []byte, m *testutil.RequestResponseMap) { | ||||
| 	*m = append(*m, testutil.RequestResponseMapping{ | ||||
| 		Request: testutil.Request{ | ||||
|  | @ -618,6 +626,7 @@ func addTestManifest(repo reference.Named, reference string, mediatype string, c | |||
| 				"Content-Length":        {fmt.Sprint(len(content))}, | ||||
| 				"Last-Modified":         {time.Now().Add(-1 * time.Second).Format(time.ANSIC)}, | ||||
| 				"Content-Type":          {mediatype}, | ||||
| 				"Docker-Content-Digest": {contentDigestString(mediatype, content)}, | ||||
| 			}), | ||||
| 		}, | ||||
| 	}) | ||||
|  | @ -632,6 +641,7 @@ func addTestManifest(repo reference.Named, reference string, mediatype string, c | |||
| 				"Content-Length":        {fmt.Sprint(len(content))}, | ||||
| 				"Last-Modified":         {time.Now().Add(-1 * time.Second).Format(time.ANSIC)}, | ||||
| 				"Content-Type":          {mediatype}, | ||||
| 				"Docker-Content-Digest": {digest.Canonical.FromBytes(content).String()}, | ||||
| 			}), | ||||
| 		}, | ||||
| 	}) | ||||
|  | @ -710,7 +720,8 @@ func TestV1ManifestFetch(t *testing.T) { | |||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	manifest, err = ms.Get(ctx, dgst, distribution.WithTag("latest")) | ||||
| 	var contentDigest digest.Digest | ||||
| 	manifest, err = ms.Get(ctx, dgst, distribution.WithTag("latest"), ReturnContentDigest(&contentDigest)) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | @ -723,6 +734,10 @@ func TestV1ManifestFetch(t *testing.T) { | |||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	if contentDigest != dgst { | ||||
| 		t.Fatalf("Unexpected returned content digest %v, expected %v", contentDigest, dgst) | ||||
| 	} | ||||
| 
 | ||||
| 	manifest, err = ms.Get(ctx, dgst, distribution.WithTag("badcontenttype")) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue