...

Source file src/github.com/docker/distribution/blobs.go

Documentation: github.com/docker/distribution

     1  package distribution
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"net/http"
     9  	"time"
    10  
    11  	"github.com/distribution/reference"
    12  	"github.com/opencontainers/go-digest"
    13  	v1 "github.com/opencontainers/image-spec/specs-go/v1"
    14  )
    15  
    16  var (
    17  	// ErrBlobExists returned when blob already exists
    18  	ErrBlobExists = errors.New("blob exists")
    19  
    20  	// ErrBlobDigestUnsupported when blob digest is an unsupported version.
    21  	ErrBlobDigestUnsupported = errors.New("unsupported blob digest")
    22  
    23  	// ErrBlobUnknown when blob is not found.
    24  	ErrBlobUnknown = errors.New("unknown blob")
    25  
    26  	// ErrBlobUploadUnknown returned when upload is not found.
    27  	ErrBlobUploadUnknown = errors.New("blob upload unknown")
    28  
    29  	// ErrBlobInvalidLength returned when the blob has an expected length on
    30  	// commit, meaning mismatched with the descriptor or an invalid value.
    31  	ErrBlobInvalidLength = errors.New("blob invalid length")
    32  )
    33  
    34  // ErrBlobInvalidDigest returned when digest check fails.
    35  type ErrBlobInvalidDigest struct {
    36  	Digest digest.Digest
    37  	Reason error
    38  }
    39  
    40  func (err ErrBlobInvalidDigest) Error() string {
    41  	return fmt.Sprintf("invalid digest for referenced layer: %v, %v",
    42  		err.Digest, err.Reason)
    43  }
    44  
    45  // ErrBlobMounted returned when a blob is mounted from another repository
    46  // instead of initiating an upload session.
    47  type ErrBlobMounted struct {
    48  	From       reference.Canonical
    49  	Descriptor Descriptor
    50  }
    51  
    52  func (err ErrBlobMounted) Error() string {
    53  	return fmt.Sprintf("blob mounted from: %v to: %v",
    54  		err.From, err.Descriptor)
    55  }
    56  
    57  // Descriptor describes targeted content. Used in conjunction with a blob
    58  // store, a descriptor can be used to fetch, store and target any kind of
    59  // blob. The struct also describes the wire protocol format. Fields should
    60  // only be added but never changed.
    61  type Descriptor struct {
    62  	// MediaType describe the type of the content. All text based formats are
    63  	// encoded as utf-8.
    64  	MediaType string `json:"mediaType,omitempty"`
    65  
    66  	// Size in bytes of content.
    67  	Size int64 `json:"size,omitempty"`
    68  
    69  	// Digest uniquely identifies the content. A byte stream can be verified
    70  	// against this digest.
    71  	Digest digest.Digest `json:"digest,omitempty"`
    72  
    73  	// URLs contains the source URLs of this content.
    74  	URLs []string `json:"urls,omitempty"`
    75  
    76  	// Annotations contains arbitrary metadata relating to the targeted content.
    77  	Annotations map[string]string `json:"annotations,omitempty"`
    78  
    79  	// Platform describes the platform which the image in the manifest runs on.
    80  	// This should only be used when referring to a manifest.
    81  	Platform *v1.Platform `json:"platform,omitempty"`
    82  
    83  	// NOTE: Before adding a field here, please ensure that all
    84  	// other options have been exhausted. Much of the type relationships
    85  	// depend on the simplicity of this type.
    86  }
    87  
    88  // Descriptor returns the descriptor, to make it satisfy the Describable
    89  // interface. Note that implementations of Describable are generally objects
    90  // which can be described, not simply descriptors; this exception is in place
    91  // to make it more convenient to pass actual descriptors to functions that
    92  // expect Describable objects.
    93  func (d Descriptor) Descriptor() Descriptor {
    94  	return d
    95  }
    96  
    97  // BlobStatter makes blob descriptors available by digest. The service may
    98  // provide a descriptor of a different digest if the provided digest is not
    99  // canonical.
   100  type BlobStatter interface {
   101  	// Stat provides metadata about a blob identified by the digest. If the
   102  	// blob is unknown to the describer, ErrBlobUnknown will be returned.
   103  	Stat(ctx context.Context, dgst digest.Digest) (Descriptor, error)
   104  }
   105  
   106  // BlobDeleter enables deleting blobs from storage.
   107  type BlobDeleter interface {
   108  	Delete(ctx context.Context, dgst digest.Digest) error
   109  }
   110  
   111  // BlobEnumerator enables iterating over blobs from storage
   112  type BlobEnumerator interface {
   113  	Enumerate(ctx context.Context, ingester func(dgst digest.Digest) error) error
   114  }
   115  
   116  // BlobDescriptorService manages metadata about a blob by digest. Most
   117  // implementations will not expose such an interface explicitly. Such mappings
   118  // should be maintained by interacting with the BlobIngester. Hence, this is
   119  // left off of BlobService and BlobStore.
   120  type BlobDescriptorService interface {
   121  	BlobStatter
   122  
   123  	// SetDescriptor assigns the descriptor to the digest. The provided digest and
   124  	// the digest in the descriptor must map to identical content but they may
   125  	// differ on their algorithm. The descriptor must have the canonical
   126  	// digest of the content and the digest algorithm must match the
   127  	// annotators canonical algorithm.
   128  	//
   129  	// Such a facility can be used to map blobs between digest domains, with
   130  	// the restriction that the algorithm of the descriptor must match the
   131  	// canonical algorithm (ie sha256) of the annotator.
   132  	SetDescriptor(ctx context.Context, dgst digest.Digest, desc Descriptor) error
   133  
   134  	// Clear enables descriptors to be unlinked
   135  	Clear(ctx context.Context, dgst digest.Digest) error
   136  }
   137  
   138  // BlobDescriptorServiceFactory creates middleware for BlobDescriptorService.
   139  type BlobDescriptorServiceFactory interface {
   140  	BlobAccessController(svc BlobDescriptorService) BlobDescriptorService
   141  }
   142  
   143  // ReadSeekCloser is the primary reader type for blob data, combining
   144  // io.ReadSeeker with io.Closer.
   145  type ReadSeekCloser interface {
   146  	io.ReadSeeker
   147  	io.Closer
   148  }
   149  
   150  // BlobProvider describes operations for getting blob data.
   151  type BlobProvider interface {
   152  	// Get returns the entire blob identified by digest along with the descriptor.
   153  	Get(ctx context.Context, dgst digest.Digest) ([]byte, error)
   154  
   155  	// Open provides a ReadSeekCloser to the blob identified by the provided
   156  	// descriptor. If the blob is not known to the service, an error will be
   157  	// returned.
   158  	Open(ctx context.Context, dgst digest.Digest) (ReadSeekCloser, error)
   159  }
   160  
   161  // BlobServer can serve blobs via http.
   162  type BlobServer interface {
   163  	// ServeBlob attempts to serve the blob, identified by dgst, via http. The
   164  	// service may decide to redirect the client elsewhere or serve the data
   165  	// directly.
   166  	//
   167  	// This handler only issues successful responses, such as 2xx or 3xx,
   168  	// meaning it serves data or issues a redirect. If the blob is not
   169  	// available, an error will be returned and the caller may still issue a
   170  	// response.
   171  	//
   172  	// The implementation may serve the same blob from a different digest
   173  	// domain. The appropriate headers will be set for the blob, unless they
   174  	// have already been set by the caller.
   175  	ServeBlob(ctx context.Context, w http.ResponseWriter, r *http.Request, dgst digest.Digest) error
   176  }
   177  
   178  // BlobIngester ingests blob data.
   179  type BlobIngester interface {
   180  	// Put inserts the content p into the blob service, returning a descriptor
   181  	// or an error.
   182  	Put(ctx context.Context, mediaType string, p []byte) (Descriptor, error)
   183  
   184  	// Create allocates a new blob writer to add a blob to this service. The
   185  	// returned handle can be written to and later resumed using an opaque
   186  	// identifier. With this approach, one can Close and Resume a BlobWriter
   187  	// multiple times until the BlobWriter is committed or cancelled.
   188  	Create(ctx context.Context, options ...BlobCreateOption) (BlobWriter, error)
   189  
   190  	// Resume attempts to resume a write to a blob, identified by an id.
   191  	Resume(ctx context.Context, id string) (BlobWriter, error)
   192  }
   193  
   194  // BlobCreateOption is a general extensible function argument for blob creation
   195  // methods. A BlobIngester may choose to honor any or none of the given
   196  // BlobCreateOptions, which can be specific to the implementation of the
   197  // BlobIngester receiving them.
   198  // TODO (brianbland): unify this with ManifestServiceOption in the future
   199  type BlobCreateOption interface {
   200  	Apply(interface{}) error
   201  }
   202  
   203  // CreateOptions is a collection of blob creation modifiers relevant to general
   204  // blob storage intended to be configured by the BlobCreateOption.Apply method.
   205  type CreateOptions struct {
   206  	Mount struct {
   207  		ShouldMount bool
   208  		From        reference.Canonical
   209  		// Stat allows to pass precalculated descriptor to link and return.
   210  		// Blob access check will be skipped if set.
   211  		Stat *Descriptor
   212  	}
   213  }
   214  
   215  // BlobWriter provides a handle for inserting data into a blob store.
   216  // Instances should be obtained from BlobWriteService.Writer and
   217  // BlobWriteService.Resume. If supported by the store, a writer can be
   218  // recovered with the id.
   219  type BlobWriter interface {
   220  	io.WriteCloser
   221  	io.ReaderFrom
   222  
   223  	// Size returns the number of bytes written to this blob.
   224  	Size() int64
   225  
   226  	// ID returns the identifier for this writer. The ID can be used with the
   227  	// Blob service to later resume the write.
   228  	ID() string
   229  
   230  	// StartedAt returns the time this blob write was started.
   231  	StartedAt() time.Time
   232  
   233  	// Commit completes the blob writer process. The content is verified
   234  	// against the provided provisional descriptor, which may result in an
   235  	// error. Depending on the implementation, written data may be validated
   236  	// against the provisional descriptor fields. If MediaType is not present,
   237  	// the implementation may reject the commit or assign "application/octet-
   238  	// stream" to the blob. The returned descriptor may have a different
   239  	// digest depending on the blob store, referred to as the canonical
   240  	// descriptor.
   241  	Commit(ctx context.Context, provisional Descriptor) (canonical Descriptor, err error)
   242  
   243  	// Cancel ends the blob write without storing any data and frees any
   244  	// associated resources. Any data written thus far will be lost. Cancel
   245  	// implementations should allow multiple calls even after a commit that
   246  	// result in a no-op. This allows use of Cancel in a defer statement,
   247  	// increasing the assurance that it is correctly called.
   248  	Cancel(ctx context.Context) error
   249  }
   250  
   251  // BlobService combines the operations to access, read and write blobs. This
   252  // can be used to describe remote blob services.
   253  type BlobService interface {
   254  	BlobStatter
   255  	BlobProvider
   256  	BlobIngester
   257  }
   258  
   259  // BlobStore represent the entire suite of blob related operations. Such an
   260  // implementation can access, read, write, delete and serve blobs.
   261  type BlobStore interface {
   262  	BlobService
   263  	BlobServer
   264  	BlobDeleter
   265  }
   266  

View as plain text