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  }