...

Source file src/github.com/docker/distribution/manifest/schema2/builder.go

Documentation: github.com/docker/distribution/manifest/schema2

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

View as plain text