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