github.com/mika/distribution@v2.2.2-0.20160108133430-a75790e3d8e0+incompatible/manifest/schema2/builder.go (about)

     1  package schema2
     2  
     3  import (
     4  	"github.com/docker/distribution"
     5  	"github.com/docker/distribution/context"
     6  	"github.com/docker/distribution/digest"
     7  )
     8  
     9  // builder is a type for constructing manifests.
    10  type builder struct {
    11  	// bs is a BlobService used to publish the configuration blob.
    12  	bs distribution.BlobService
    13  
    14  	// configJSON references
    15  	configJSON []byte
    16  
    17  	// layers is a list of layer descriptors that gets built by successive
    18  	// calls to AppendReference.
    19  	layers []distribution.Descriptor
    20  }
    21  
    22  // NewManifestBuilder is used to build new manifests for the current schema
    23  // version. It takes a BlobService so it can publish the configuration blob
    24  // as part of the Build process.
    25  func NewManifestBuilder(bs distribution.BlobService, configJSON []byte) distribution.ManifestBuilder {
    26  	mb := &builder{
    27  		bs:         bs,
    28  		configJSON: make([]byte, len(configJSON)),
    29  	}
    30  	copy(mb.configJSON, configJSON)
    31  
    32  	return mb
    33  }
    34  
    35  // Build produces a final manifest from the given references.
    36  func (mb *builder) Build(ctx context.Context) (distribution.Manifest, error) {
    37  	m := Manifest{
    38  		Versioned: SchemaVersion,
    39  		Layers:    make([]distribution.Descriptor, len(mb.layers)),
    40  	}
    41  	copy(m.Layers, mb.layers)
    42  
    43  	configDigest := digest.FromBytes(mb.configJSON)
    44  
    45  	var err error
    46  	m.Config, err = mb.bs.Stat(ctx, configDigest)
    47  	switch err {
    48  	case nil:
    49  		return FromStruct(m)
    50  	case distribution.ErrBlobUnknown:
    51  		// nop
    52  	default:
    53  		return nil, err
    54  	}
    55  
    56  	// Add config to the blob store
    57  	m.Config, err = mb.bs.Put(ctx, MediaTypeConfig, mb.configJSON)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  
    62  	return FromStruct(m)
    63  }
    64  
    65  // AppendReference adds a reference to the current ManifestBuilder.
    66  func (mb *builder) AppendReference(d distribution.Describable) error {
    67  	mb.layers = append(mb.layers, d.Descriptor())
    68  	return nil
    69  }
    70  
    71  // References returns the current references added to this builder.
    72  func (mb *builder) References() []distribution.Descriptor {
    73  	return mb.layers
    74  }