github.com/mika/distribution@v2.2.2-0.20160108133430-a75790e3d8e0+incompatible/registry/storage/manifestlisthandler.go (about) 1 package storage 2 3 import ( 4 "fmt" 5 6 "encoding/json" 7 "github.com/docker/distribution" 8 "github.com/docker/distribution/context" 9 "github.com/docker/distribution/digest" 10 "github.com/docker/distribution/manifest/manifestlist" 11 ) 12 13 // manifestListHandler is a ManifestHandler that covers schema2 manifest lists. 14 type manifestListHandler struct { 15 repository *repository 16 blobStore *linkedBlobStore 17 ctx context.Context 18 } 19 20 var _ ManifestHandler = &manifestListHandler{} 21 22 func (ms *manifestListHandler) Unmarshal(ctx context.Context, dgst digest.Digest, content []byte) (distribution.Manifest, error) { 23 context.GetLogger(ms.ctx).Debug("(*manifestListHandler).Unmarshal") 24 25 var m manifestlist.DeserializedManifestList 26 if err := json.Unmarshal(content, &m); err != nil { 27 return nil, err 28 } 29 30 return &m, nil 31 } 32 33 func (ms *manifestListHandler) Put(ctx context.Context, manifestList distribution.Manifest, skipDependencyVerification bool) (digest.Digest, error) { 34 context.GetLogger(ms.ctx).Debug("(*manifestListHandler).Put") 35 36 m, ok := manifestList.(*manifestlist.DeserializedManifestList) 37 if !ok { 38 return "", fmt.Errorf("wrong type put to manifestListHandler: %T", manifestList) 39 } 40 41 if err := ms.verifyManifest(ms.ctx, *m, skipDependencyVerification); err != nil { 42 return "", err 43 } 44 45 mt, payload, err := m.Payload() 46 if err != nil { 47 return "", err 48 } 49 50 revision, err := ms.blobStore.Put(ctx, mt, payload) 51 if err != nil { 52 context.GetLogger(ctx).Errorf("error putting payload into blobstore: %v", err) 53 return "", err 54 } 55 56 // Link the revision into the repository. 57 if err := ms.blobStore.linkBlob(ctx, revision); err != nil { 58 return "", err 59 } 60 61 return revision.Digest, nil 62 } 63 64 // verifyManifest ensures that the manifest content is valid from the 65 // perspective of the registry. As a policy, the registry only tries to 66 // store valid content, leaving trust policies of that content up to 67 // consumers. 68 func (ms *manifestListHandler) verifyManifest(ctx context.Context, mnfst manifestlist.DeserializedManifestList, skipDependencyVerification bool) error { 69 var errs distribution.ErrManifestVerification 70 71 if !skipDependencyVerification { 72 // This manifest service is different from the blob service 73 // returned by Blob. It uses a linked blob store to ensure that 74 // only manifests are accessible. 75 manifestService, err := ms.repository.Manifests(ctx) 76 if err != nil { 77 return err 78 } 79 80 for _, manifestDescriptor := range mnfst.References() { 81 exists, err := manifestService.Exists(ctx, manifestDescriptor.Digest) 82 if err != nil && err != distribution.ErrBlobUnknown { 83 errs = append(errs, err) 84 } 85 if err != nil || !exists { 86 // On error here, we always append unknown blob errors. 87 errs = append(errs, distribution.ErrManifestBlobUnknown{Digest: manifestDescriptor.Digest}) 88 } 89 } 90 } 91 if len(errs) != 0 { 92 return errs 93 } 94 95 return nil 96 }