Tizen_4.0 base
[platform/upstream/docker-engine.git] / vendor / github.com / docker / distribution / blobs.go
1 package distribution
2
3 import (
4         "errors"
5         "fmt"
6         "io"
7         "net/http"
8         "time"
9
10         "github.com/docker/distribution/context"
11         "github.com/docker/distribution/reference"
12         "github.com/opencontainers/go-digest"
13 )
14
15 var (
16         // ErrBlobExists returned when blob already exists
17         ErrBlobExists = errors.New("blob exists")
18
19         // ErrBlobDigestUnsupported when blob digest is an unsupported version.
20         ErrBlobDigestUnsupported = errors.New("unsupported blob digest")
21
22         // ErrBlobUnknown when blob is not found.
23         ErrBlobUnknown = errors.New("unknown blob")
24
25         // ErrBlobUploadUnknown returned when upload is not found.
26         ErrBlobUploadUnknown = errors.New("blob upload unknown")
27
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")
31 )
32
33 // ErrBlobInvalidDigest returned when digest check fails.
34 type ErrBlobInvalidDigest struct {
35         Digest digest.Digest
36         Reason error
37 }
38
39 func (err ErrBlobInvalidDigest) Error() string {
40         return fmt.Sprintf("invalid digest for referenced layer: %v, %v",
41                 err.Digest, err.Reason)
42 }
43
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
48         Descriptor Descriptor
49 }
50
51 func (err ErrBlobMounted) Error() string {
52         return fmt.Sprintf("blob mounted from: %v to: %v",
53                 err.From, err.Descriptor)
54 }
55
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
62         // encoded as utf-8.
63         MediaType string `json:"mediaType,omitempty"`
64
65         // Size in bytes of content.
66         Size int64 `json:"size,omitempty"`
67
68         // Digest uniquely identifies the content. A byte stream can be verified
69         // against against this digest.
70         Digest digest.Digest `json:"digest,omitempty"`
71
72         // URLs contains the source URLs of this content.
73         URLs []string `json:"urls,omitempty"`
74
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.
78 }
79
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 {
86         return d
87 }
88
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
91 // canonical.
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)
96 }
97
98 // BlobDeleter enables deleting blobs from storage.
99 type BlobDeleter interface {
100         Delete(ctx context.Context, dgst digest.Digest) error
101 }
102
103 // BlobEnumerator enables iterating over blobs from storage
104 type BlobEnumerator interface {
105         Enumerate(ctx context.Context, ingester func(dgst digest.Digest) error) error
106 }
107
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 {
113         BlobStatter
114
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.
120         //
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
125
126         // Clear enables descriptors to be unlinked
127         Clear(ctx context.Context, dgst digest.Digest) error
128 }
129
130 // BlobDescriptorServiceFactory creates middleware for BlobDescriptorService.
131 type BlobDescriptorServiceFactory interface {
132         BlobAccessController(svc BlobDescriptorService) BlobDescriptorService
133 }
134
135 // ReadSeekCloser is the primary reader type for blob data, combining
136 // io.ReadSeeker with io.Closer.
137 type ReadSeekCloser interface {
138         io.ReadSeeker
139         io.Closer
140 }
141
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)
146
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
149         // returned.
150         Open(ctx context.Context, dgst digest.Digest) (ReadSeekCloser, error)
151 }
152
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
157         // directly.
158         //
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
162         // response.
163         //
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
168 }
169
170 // BlobIngester ingests blob data.
171 type BlobIngester interface {
172         // Put inserts the content p into the blob service, returning a descriptor
173         // or an error.
174         Put(ctx context.Context, mediaType string, p []byte) (Descriptor, error)
175
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)
181
182         // Resume attempts to resume a write to a blob, identified by an id.
183         Resume(ctx context.Context, id string) (BlobWriter, error)
184 }
185
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
193 }
194
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 {
198         Mount struct {
199                 ShouldMount bool
200                 From        reference.Canonical
201                 // Stat allows to pass precalculated descriptor to link and return.
202                 // Blob access check will be skipped if set.
203                 Stat *Descriptor
204         }
205 }
206
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 {
212         io.WriteCloser
213         io.ReaderFrom
214
215         // Size returns the number of bytes written to this blob.
216         Size() int64
217
218         // ID returns the identifier for this writer. The ID can be used with the
219         // Blob service to later resume the write.
220         ID() string
221
222         // StartedAt returns the time this blob write was started.
223         StartedAt() time.Time
224
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
232         // descriptor.
233         Commit(ctx context.Context, provisional Descriptor) (canonical Descriptor, err error)
234
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
241 }
242
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 {
246         BlobStatter
247         BlobProvider
248         BlobIngester
249 }
250
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 {
254         BlobService
255         BlobServer
256         BlobDeleter
257 }