...
1 package storage
2
3 import (
4 "context"
5 "fmt"
6
7 "github.com/docker/distribution"
8 dcontext "github.com/docker/distribution/context"
9 "github.com/docker/distribution/manifest/manifestlist"
10 "github.com/opencontainers/go-digest"
11 )
12
13
14 type manifestListHandler struct {
15 repository distribution.Repository
16 blobStore distribution.BlobStore
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 dcontext.GetLogger(ms.ctx).Debug("(*manifestListHandler).Unmarshal")
24
25 m := &manifestlist.DeserializedManifestList{}
26 if err := m.UnmarshalJSON(content); 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 dcontext.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 dcontext.GetLogger(ctx).Errorf("error putting payload into blobstore: %v", err)
53 return "", err
54 }
55
56 return revision.Digest, nil
57 }
58
59
60
61
62
63 func (ms *manifestListHandler) verifyManifest(ctx context.Context, mnfst manifestlist.DeserializedManifestList, skipDependencyVerification bool) error {
64 var errs distribution.ErrManifestVerification
65
66 if mnfst.SchemaVersion != 2 {
67 return fmt.Errorf("unrecognized manifest list schema version %d", mnfst.SchemaVersion)
68 }
69
70 if !skipDependencyVerification {
71
72
73
74
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
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 }
97
View as plain text