github.com/mika/distribution@v2.2.2-0.20160108133430-a75790e3d8e0+incompatible/blobs.go (about) 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/digest" 12 ) 13 14 var ( 15 // ErrBlobExists returned when blob already exists 16 ErrBlobExists = errors.New("blob exists") 17 18 // ErrBlobDigestUnsupported when blob digest is an unsupported version. 19 ErrBlobDigestUnsupported = errors.New("unsupported blob digest") 20 21 // ErrBlobUnknown when blob is not found. 22 ErrBlobUnknown = errors.New("unknown blob") 23 24 // ErrBlobUploadUnknown returned when upload is not found. 25 ErrBlobUploadUnknown = errors.New("blob upload unknown") 26 27 // ErrBlobInvalidLength returned when the blob has an expected length on 28 // commit, meaning mismatched with the descriptor or an invalid value. 29 ErrBlobInvalidLength = errors.New("blob invalid length") 30 ) 31 32 // ErrBlobInvalidDigest returned when digest check fails. 33 type ErrBlobInvalidDigest struct { 34 Digest digest.Digest 35 Reason error 36 } 37 38 func (err ErrBlobInvalidDigest) Error() string { 39 return fmt.Sprintf("invalid digest for referenced layer: %v, %v", 40 err.Digest, err.Reason) 41 } 42 43 // Descriptor describes targeted content. Used in conjunction with a blob 44 // store, a descriptor can be used to fetch, store and target any kind of 45 // blob. The struct also describes the wire protocol format. Fields should 46 // only be added but never changed. 47 type Descriptor struct { 48 // MediaType describe the type of the content. All text based formats are 49 // encoded as utf-8. 50 MediaType string `json:"mediaType,omitempty"` 51 52 // Size in bytes of content. 53 Size int64 `json:"size,omitempty"` 54 55 // Digest uniquely identifies the content. A byte stream can be verified 56 // against against this digest. 57 Digest digest.Digest `json:"digest,omitempty"` 58 59 // NOTE: Before adding a field here, please ensure that all 60 // other options have been exhausted. Much of the type relationships 61 // depend on the simplicity of this type. 62 } 63 64 // Descriptor returns the descriptor, to make it satisfy the Describable 65 // interface. Note that implementations of Describable are generally objects 66 // which can be described, not simply descriptors; this exception is in place 67 // to make it more convenient to pass actual descriptors to functions that 68 // expect Describable objects. 69 func (d Descriptor) Descriptor() Descriptor { 70 return d 71 } 72 73 // BlobStatter makes blob descriptors available by digest. The service may 74 // provide a descriptor of a different digest if the provided digest is not 75 // canonical. 76 type BlobStatter interface { 77 // Stat provides metadata about a blob identified by the digest. If the 78 // blob is unknown to the describer, ErrBlobUnknown will be returned. 79 Stat(ctx context.Context, dgst digest.Digest) (Descriptor, error) 80 } 81 82 // BlobDeleter enables deleting blobs from storage. 83 type BlobDeleter interface { 84 Delete(ctx context.Context, dgst digest.Digest) error 85 } 86 87 // BlobDescriptorService manages metadata about a blob by digest. Most 88 // implementations will not expose such an interface explicitly. Such mappings 89 // should be maintained by interacting with the BlobIngester. Hence, this is 90 // left off of BlobService and BlobStore. 91 type BlobDescriptorService interface { 92 BlobStatter 93 94 // SetDescriptor assigns the descriptor to the digest. The provided digest and 95 // the digest in the descriptor must map to identical content but they may 96 // differ on their algorithm. The descriptor must have the canonical 97 // digest of the content and the digest algorithm must match the 98 // annotators canonical algorithm. 99 // 100 // Such a facility can be used to map blobs between digest domains, with 101 // the restriction that the algorithm of the descriptor must match the 102 // canonical algorithm (ie sha256) of the annotator. 103 SetDescriptor(ctx context.Context, dgst digest.Digest, desc Descriptor) error 104 105 // Clear enables descriptors to be unlinked 106 Clear(ctx context.Context, dgst digest.Digest) error 107 } 108 109 // ReadSeekCloser is the primary reader type for blob data, combining 110 // io.ReadSeeker with io.Closer. 111 type ReadSeekCloser interface { 112 io.ReadSeeker 113 io.Closer 114 } 115 116 // BlobProvider describes operations for getting blob data. 117 type BlobProvider interface { 118 // Get returns the entire blob identified by digest along with the descriptor. 119 Get(ctx context.Context, dgst digest.Digest) ([]byte, error) 120 121 // Open provides a ReadSeekCloser to the blob identified by the provided 122 // descriptor. If the blob is not known to the service, an error will be 123 // returned. 124 Open(ctx context.Context, dgst digest.Digest) (ReadSeekCloser, error) 125 } 126 127 // BlobServer can serve blobs via http. 128 type BlobServer interface { 129 // ServeBlob attempts to serve the blob, identifed by dgst, via http. The 130 // service may decide to redirect the client elsewhere or serve the data 131 // directly. 132 // 133 // This handler only issues successful responses, such as 2xx or 3xx, 134 // meaning it serves data or issues a redirect. If the blob is not 135 // available, an error will be returned and the caller may still issue a 136 // response. 137 // 138 // The implementation may serve the same blob from a different digest 139 // domain. The appropriate headers will be set for the blob, unless they 140 // have already been set by the caller. 141 ServeBlob(ctx context.Context, w http.ResponseWriter, r *http.Request, dgst digest.Digest) error 142 } 143 144 // BlobIngester ingests blob data. 145 type BlobIngester interface { 146 // Put inserts the content p into the blob service, returning a descriptor 147 // or an error. 148 Put(ctx context.Context, mediaType string, p []byte) (Descriptor, error) 149 150 // Create allocates a new blob writer to add a blob to this service. The 151 // returned handle can be written to and later resumed using an opaque 152 // identifier. With this approach, one can Close and Resume a BlobWriter 153 // multiple times until the BlobWriter is committed or cancelled. 154 Create(ctx context.Context) (BlobWriter, error) 155 156 // Resume attempts to resume a write to a blob, identified by an id. 157 Resume(ctx context.Context, id string) (BlobWriter, error) 158 } 159 160 // BlobWriter provides a handle for inserting data into a blob store. 161 // Instances should be obtained from BlobWriteService.Writer and 162 // BlobWriteService.Resume. If supported by the store, a writer can be 163 // recovered with the id. 164 type BlobWriter interface { 165 io.WriteSeeker 166 io.ReaderFrom 167 io.Closer 168 169 // ID returns the identifier for this writer. The ID can be used with the 170 // Blob service to later resume the write. 171 ID() string 172 173 // StartedAt returns the time this blob write was started. 174 StartedAt() time.Time 175 176 // Commit completes the blob writer process. The content is verified 177 // against the provided provisional descriptor, which may result in an 178 // error. Depending on the implementation, written data may be validated 179 // against the provisional descriptor fields. If MediaType is not present, 180 // the implementation may reject the commit or assign "application/octet- 181 // stream" to the blob. The returned descriptor may have a different 182 // digest depending on the blob store, referred to as the canonical 183 // descriptor. 184 Commit(ctx context.Context, provisional Descriptor) (canonical Descriptor, err error) 185 186 // Cancel ends the blob write without storing any data and frees any 187 // associated resources. Any data written thus far will be lost. Cancel 188 // implementations should allow multiple calls even after a commit that 189 // result in a no-op. This allows use of Cancel in a defer statement, 190 // increasing the assurance that it is correctly called. 191 Cancel(ctx context.Context) error 192 193 // Get a reader to the blob being written by this BlobWriter 194 Reader() (io.ReadCloser, error) 195 } 196 197 // BlobService combines the operations to access, read and write blobs. This 198 // can be used to describe remote blob services. 199 type BlobService interface { 200 BlobStatter 201 BlobProvider 202 BlobIngester 203 } 204 205 // BlobStore represent the entire suite of blob related operations. Such an 206 // implementation can access, read, write, delete and serve blobs. 207 type BlobStore interface { 208 BlobService 209 BlobServer 210 BlobDeleter 211 }