github.com/samsalisbury/distribution@v2.2.1-0.20151123021722-54f974340220+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 // BlobStatter makes blob descriptors available by digest. The service may 65 // provide a descriptor of a different digest if the provided digest is not 66 // canonical. 67 type BlobStatter interface { 68 // Stat provides metadata about a blob identified by the digest. If the 69 // blob is unknown to the describer, ErrBlobUnknown will be returned. 70 Stat(ctx context.Context, dgst digest.Digest) (Descriptor, error) 71 } 72 73 // BlobDeleter enables deleting blobs from storage. 74 type BlobDeleter interface { 75 Delete(ctx context.Context, dgst digest.Digest) error 76 } 77 78 // BlobDescriptorService manages metadata about a blob by digest. Most 79 // implementations will not expose such an interface explicitly. Such mappings 80 // should be maintained by interacting with the BlobIngester. Hence, this is 81 // left off of BlobService and BlobStore. 82 type BlobDescriptorService interface { 83 BlobStatter 84 85 // SetDescriptor assigns the descriptor to the digest. The provided digest and 86 // the digest in the descriptor must map to identical content but they may 87 // differ on their algorithm. The descriptor must have the canonical 88 // digest of the content and the digest algorithm must match the 89 // annotators canonical algorithm. 90 // 91 // Such a facility can be used to map blobs between digest domains, with 92 // the restriction that the algorithm of the descriptor must match the 93 // canonical algorithm (ie sha256) of the annotator. 94 SetDescriptor(ctx context.Context, dgst digest.Digest, desc Descriptor) error 95 96 // Clear enables descriptors to be unlinked 97 Clear(ctx context.Context, dgst digest.Digest) error 98 } 99 100 // ReadSeekCloser is the primary reader type for blob data, combining 101 // io.ReadSeeker with io.Closer. 102 type ReadSeekCloser interface { 103 io.ReadSeeker 104 io.Closer 105 } 106 107 // BlobProvider describes operations for getting blob data. 108 type BlobProvider interface { 109 // Get returns the entire blob identified by digest along with the descriptor. 110 Get(ctx context.Context, dgst digest.Digest) ([]byte, error) 111 112 // Open provides a ReadSeekCloser to the blob identified by the provided 113 // descriptor. If the blob is not known to the service, an error will be 114 // returned. 115 Open(ctx context.Context, dgst digest.Digest) (ReadSeekCloser, error) 116 } 117 118 // BlobServer can serve blobs via http. 119 type BlobServer interface { 120 // ServeBlob attempts to serve the blob, identifed by dgst, via http. The 121 // service may decide to redirect the client elsewhere or serve the data 122 // directly. 123 // 124 // This handler only issues successful responses, such as 2xx or 3xx, 125 // meaning it serves data or issues a redirect. If the blob is not 126 // available, an error will be returned and the caller may still issue a 127 // response. 128 // 129 // The implementation may serve the same blob from a different digest 130 // domain. The appropriate headers will be set for the blob, unless they 131 // have already been set by the caller. 132 ServeBlob(ctx context.Context, w http.ResponseWriter, r *http.Request, dgst digest.Digest) error 133 } 134 135 // BlobIngester ingests blob data. 136 type BlobIngester interface { 137 // Put inserts the content p into the blob service, returning a descriptor 138 // or an error. 139 Put(ctx context.Context, mediaType string, p []byte) (Descriptor, error) 140 141 // Create allocates a new blob writer to add a blob to this service. The 142 // returned handle can be written to and later resumed using an opaque 143 // identifier. With this approach, one can Close and Resume a BlobWriter 144 // multiple times until the BlobWriter is committed or cancelled. 145 Create(ctx context.Context) (BlobWriter, error) 146 147 // Resume attempts to resume a write to a blob, identified by an id. 148 Resume(ctx context.Context, id string) (BlobWriter, error) 149 } 150 151 // BlobWriter provides a handle for inserting data into a blob store. 152 // Instances should be obtained from BlobWriteService.Writer and 153 // BlobWriteService.Resume. If supported by the store, a writer can be 154 // recovered with the id. 155 type BlobWriter interface { 156 io.WriteSeeker 157 io.ReaderFrom 158 io.Closer 159 160 // ID returns the identifier for this writer. The ID can be used with the 161 // Blob service to later resume the write. 162 ID() string 163 164 // StartedAt returns the time this blob write was started. 165 StartedAt() time.Time 166 167 // Commit completes the blob writer process. The content is verified 168 // against the provided provisional descriptor, which may result in an 169 // error. Depending on the implementation, written data may be validated 170 // against the provisional descriptor fields. If MediaType is not present, 171 // the implementation may reject the commit or assign "application/octet- 172 // stream" to the blob. The returned descriptor may have a different 173 // digest depending on the blob store, referred to as the canonical 174 // descriptor. 175 Commit(ctx context.Context, provisional Descriptor) (canonical Descriptor, err error) 176 177 // Cancel ends the blob write without storing any data and frees any 178 // associated resources. Any data written thus far will be lost. Cancel 179 // implementations should allow multiple calls even after a commit that 180 // result in a no-op. This allows use of Cancel in a defer statement, 181 // increasing the assurance that it is correctly called. 182 Cancel(ctx context.Context) error 183 184 // Get a reader to the blob being written by this BlobWriter 185 Reader() (io.ReadCloser, error) 186 } 187 188 // BlobService combines the operations to access, read and write blobs. This 189 // can be used to describe remote blob services. 190 type BlobService interface { 191 BlobStatter 192 BlobProvider 193 BlobIngester 194 } 195 196 // BlobStore represent the entire suite of blob related operations. Such an 197 // implementation can access, read, write, delete and serve blobs. 198 type BlobStore interface { 199 BlobService 200 BlobServer 201 BlobDeleter 202 }