...
1 package schema1
2
3 import (
4 "context"
5 "errors"
6 "fmt"
7
8 "github.com/distribution/reference"
9 "github.com/docker/distribution"
10 "github.com/docker/distribution/manifest"
11 "github.com/docker/libtrust"
12 "github.com/opencontainers/go-digest"
13 )
14
15
16
17 type referenceManifestBuilder struct {
18 Manifest
19 pk libtrust.PrivateKey
20 }
21
22
23
24 func NewReferenceManifestBuilder(pk libtrust.PrivateKey, ref reference.Named, architecture string) distribution.ManifestBuilder {
25 tag := ""
26 if tagged, isTagged := ref.(reference.Tagged); isTagged {
27 tag = tagged.Tag()
28 }
29
30 return &referenceManifestBuilder{
31 Manifest: Manifest{
32 Versioned: manifest.Versioned{
33 SchemaVersion: 1,
34 },
35 Name: ref.Name(),
36 Tag: tag,
37 Architecture: architecture,
38 },
39 pk: pk,
40 }
41 }
42
43 func (mb *referenceManifestBuilder) Build(ctx context.Context) (distribution.Manifest, error) {
44 m := mb.Manifest
45 if len(m.FSLayers) == 0 {
46 return nil, errors.New("cannot build manifest with zero layers or history")
47 }
48
49 m.FSLayers = make([]FSLayer, len(mb.Manifest.FSLayers))
50 m.History = make([]History, len(mb.Manifest.History))
51 copy(m.FSLayers, mb.Manifest.FSLayers)
52 copy(m.History, mb.Manifest.History)
53
54 return Sign(&m, mb.pk)
55 }
56
57
58 func (mb *referenceManifestBuilder) AppendReference(d distribution.Describable) error {
59 r, ok := d.(Reference)
60 if !ok {
61 return fmt.Errorf("unable to add non-reference type to v1 builder")
62 }
63
64
65 mb.Manifest.FSLayers = append([]FSLayer{{BlobSum: r.Digest}}, mb.Manifest.FSLayers...)
66 mb.Manifest.History = append([]History{r.History}, mb.Manifest.History...)
67 return nil
68
69 }
70
71
72 func (mb *referenceManifestBuilder) References() []distribution.Descriptor {
73 refs := make([]distribution.Descriptor, len(mb.Manifest.FSLayers))
74 for i := range mb.Manifest.FSLayers {
75 layerDigest := mb.Manifest.FSLayers[i].BlobSum
76 history := mb.Manifest.History[i]
77 ref := Reference{layerDigest, 0, history}
78 refs[i] = ref.Descriptor()
79 }
80 return refs
81 }
82
83
84
85 type Reference struct {
86 Digest digest.Digest
87 Size int64
88 History History
89 }
90
91
92 func (r Reference) Descriptor() distribution.Descriptor {
93 return distribution.Descriptor{
94 MediaType: MediaTypeManifestLayer,
95 Digest: r.Digest,
96 Size: r.Size,
97 }
98 }
99
View as plain text