github.com/mika/distribution@v2.2.2-0.20160108133430-a75790e3d8e0+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/libtrust"
    12  )
    13  
    14  // referenceManifestBuilder is a type for constructing manifests from schema1
    15  // dependencies.
    16  type referenceManifestBuilder struct {
    17  	Manifest
    18  	pk libtrust.PrivateKey
    19  }
    20  
    21  // NewReferenceManifestBuilder is used to build new manifests for the current
    22  // schema version using schema1 dependencies.
    23  func NewReferenceManifestBuilder(pk libtrust.PrivateKey, name, tag, architecture string) distribution.ManifestBuilder {
    24  	return &referenceManifestBuilder{
    25  		Manifest: Manifest{
    26  			Versioned: manifest.Versioned{
    27  				SchemaVersion: 1,
    28  			},
    29  			Name:         name,
    30  			Tag:          tag,
    31  			Architecture: architecture,
    32  		},
    33  		pk: pk,
    34  	}
    35  }
    36  
    37  func (mb *referenceManifestBuilder) Build(ctx context.Context) (distribution.Manifest, error) {
    38  	m := mb.Manifest
    39  	if len(m.FSLayers) == 0 {
    40  		return nil, errors.New("cannot build manifest with zero layers or history")
    41  	}
    42  
    43  	m.FSLayers = make([]FSLayer, len(mb.Manifest.FSLayers))
    44  	m.History = make([]History, len(mb.Manifest.History))
    45  	copy(m.FSLayers, mb.Manifest.FSLayers)
    46  	copy(m.History, mb.Manifest.History)
    47  
    48  	return Sign(&m, mb.pk)
    49  }
    50  
    51  // AppendReference adds a reference to the current ManifestBuilder
    52  func (mb *referenceManifestBuilder) AppendReference(d distribution.Describable) error {
    53  	r, ok := d.(Reference)
    54  	if !ok {
    55  		return fmt.Errorf("Unable to add non-reference type to v1 builder")
    56  	}
    57  
    58  	// Entries need to be prepended
    59  	mb.Manifest.FSLayers = append([]FSLayer{{BlobSum: r.Digest}}, mb.Manifest.FSLayers...)
    60  	mb.Manifest.History = append([]History{r.History}, mb.Manifest.History...)
    61  	return nil
    62  
    63  }
    64  
    65  // References returns the current references added to this builder
    66  func (mb *referenceManifestBuilder) References() []distribution.Descriptor {
    67  	refs := make([]distribution.Descriptor, len(mb.Manifest.FSLayers))
    68  	for i := range mb.Manifest.FSLayers {
    69  		layerDigest := mb.Manifest.FSLayers[i].BlobSum
    70  		history := mb.Manifest.History[i]
    71  		ref := Reference{layerDigest, 0, history}
    72  		refs[i] = ref.Descriptor()
    73  	}
    74  	return refs
    75  }
    76  
    77  // Reference describes a manifest v2, schema version 1 dependency.
    78  // An FSLayer associated with a history entry.
    79  type Reference struct {
    80  	Digest  digest.Digest
    81  	Size    int64 // if we know it, set it for the descriptor.
    82  	History History
    83  }
    84  
    85  // Descriptor describes a reference
    86  func (r Reference) Descriptor() distribution.Descriptor {
    87  	return distribution.Descriptor{
    88  		MediaType: MediaTypeManifestLayer,
    89  		Digest:    r.Digest,
    90  		Size:      r.Size,
    91  	}
    92  }