github.com/npaton/distribution@v2.3.1-rc.0+incompatible/manifest/schema1/reference_builder.go (about) 1 package schema1 2 3 import ( 4 "fmt" 5 6 "errors" 7 "github.com/docker/distribution" 8 "github.com/docker/distribution/context" 9 "github.com/docker/distribution/digest" 10 "github.com/docker/distribution/manifest" 11 "github.com/docker/distribution/reference" 12 "github.com/docker/libtrust" 13 ) 14 15 // referenceManifestBuilder is a type for constructing manifests from schema1 16 // dependencies. 17 type referenceManifestBuilder struct { 18 Manifest 19 pk libtrust.PrivateKey 20 } 21 22 // NewReferenceManifestBuilder is used to build new manifests for the current 23 // schema version using schema1 dependencies. 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 // AppendReference adds a reference to the current ManifestBuilder 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 // Entries need to be prepended 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 // References returns the current references added to this builder 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 // Reference describes a manifest v2, schema version 1 dependency. 84 // An FSLayer associated with a history entry. 85 type Reference struct { 86 Digest digest.Digest 87 Size int64 // if we know it, set it for the descriptor. 88 History History 89 } 90 91 // Descriptor describes a reference 92 func (r Reference) Descriptor() distribution.Descriptor { 93 return distribution.Descriptor{ 94 MediaType: MediaTypeManifestLayer, 95 Digest: r.Digest, 96 Size: r.Size, 97 } 98 }