github.com/opencontainers/umoci@v0.4.8-0.20240508124516-656e4836fb0d/oci/cas/cas.go (about) 1 /* 2 * umoci: Umoci Modifies Open Containers' Images 3 * Copyright (C) 2016-2020 SUSE LLC 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package cas 19 20 import ( 21 "context" 22 "fmt" 23 "io" 24 25 // We need to include sha256 in order for go-digest to properly handle such 26 // hashes, since Go's crypto library like to lazy-load cryptographic 27 // libraries. 28 _ "crypto/sha256" 29 30 "github.com/opencontainers/go-digest" 31 ispec "github.com/opencontainers/image-spec/specs-go/v1" 32 ) 33 34 const ( 35 // BlobAlgorithm is the name of the only supported digest algorithm for blobs. 36 // FIXME: We can make this a list. 37 BlobAlgorithm = digest.SHA256 38 ) 39 40 // Exposed errors. 41 var ( 42 // ErrNotExist is effectively an implementation-neutral version of 43 // os.ErrNotExist. 44 ErrNotExist = fmt.Errorf("no such blob or index") 45 46 // ErrInvalid is returned when an image was detected as being invalid. 47 ErrInvalid = fmt.Errorf("invalid image detected") 48 49 // ErrUnknownType is returned when an unknown (or otherwise unparseable) 50 // mediatype is encountered. Callers should not ignore this error unless it 51 // is in a context where ignoring it is more friendly to spec extensions. 52 ErrUnknownType = fmt.Errorf("unknown mediatype encountered") 53 54 // ErrNotImplemented is returned when a requested operation has not been 55 // implementing the backing image store. 56 ErrNotImplemented = fmt.Errorf("operation not implemented") 57 58 // ErrClobber is returned when a requested operation would require clobbering a 59 // reference or blob which already exists. 60 ErrClobber = fmt.Errorf("operation would clobber existing object") 61 ) 62 63 // Engine is an interface that provides methods for accessing and modifying an 64 // OCI image, namely allowing access to reference descriptors and blobs. 65 type Engine interface { 66 // PutBlob adds a new blob to the image. This is idempotent; a nil error 67 // means that "the content is stored at DIGEST" without implying "because 68 // of this PutBlob() call". 69 PutBlob(ctx context.Context, reader io.Reader) (digest digest.Digest, size int64, err error) 70 71 // GetBlob returns a reader for retrieving a blob from the image, which the 72 // caller must Close(). Returns ErrNotExist if the digest is not found. 73 // 74 // This function will return a VerifiedReadCloser, meaning that you must 75 // call Close() and check the error returned from Close() in order to 76 // ensure that the hash of the blob is verified. 77 // 78 // Please note that calling Close() on the returned blob will read the 79 // entire from disk and hash it (even if you didn't read any bytes before 80 // calling Close), so if you wish to only check if a blob exists you should 81 // use StatBlob() instead. 82 GetBlob(ctx context.Context, digest digest.Digest) (reader io.ReadCloser, err error) 83 84 // StatBlob returns whether the specified blob exists in the image. Returns 85 // ErrNotExist if the digest was not found. 86 StatBlob(ctx context.Context, digest digest.Digest) (bool, error) 87 88 // PutIndex sets the index of the OCI image to the given index, replacing 89 // the previously existing index. This operation is atomic; any readers 90 // attempting to access the OCI image while it is being modified will only 91 // ever see the new or old index. 92 PutIndex(ctx context.Context, index ispec.Index) (err error) 93 94 // GetIndex returns the index of the OCI image. Return ErrNotExist if the 95 // digest is not found. If the image doesn't have an index, ErrInvalid is 96 // returned (a valid OCI image MUST have an image index). 97 // 98 // It is not recommended that users of cas.Engine use this interface 99 // directly, due to the complication of properly handling references as 100 // well as correctly handling nested indexes. casext.Engine provides a 101 // wrapper for cas.Engine that implements various reference resolution 102 // functions that should work for most users. 103 GetIndex(ctx context.Context) (index ispec.Index, ierr error) 104 105 // DeleteBlob removes a blob from the image. This is idempotent; a nil 106 // error means "the content is not in the store" without implying "because 107 // of this DeleteBlob() call". 108 DeleteBlob(ctx context.Context, digest digest.Digest) (err error) 109 110 // ListBlobs returns the set of blob digests stored in the image. 111 ListBlobs(ctx context.Context) (digests []digest.Digest, err error) 112 113 // Clean executes a garbage collection of any non-blob garbage in the store 114 // (this includes temporary files and directories not reachable from the 115 // CAS interface). This MUST NOT remove any blobs or references in the 116 // store. 117 Clean(ctx context.Context) (err error) 118 119 // Close releases all references held by the engine. Subsequent operations 120 // may fail. 121 Close() (err error) 122 }