github.com/mgoltzsche/ctnr@v0.7.1-alpha/image/store.go (about)

     1  package image
     2  
     3  import (
     4  	"bytes"
     5  	"time"
     6  
     7  	"github.com/mgoltzsche/ctnr/pkg/fs"
     8  	"github.com/opencontainers/go-digest"
     9  	ispecs "github.com/opencontainers/image-spec/specs-go/v1"
    10  	"github.com/pkg/errors"
    11  )
    12  
    13  // containers/storage interface is not used to ease the OCI store implementation
    14  // which is required by unprivileged users (https://github.com/containers/storage/issues/96)
    15  
    16  type ImageStore interface {
    17  	ImageStoreRO
    18  	OpenLockedImageStore() (ImageStoreRW, error)
    19  	ImageGC(ttl, refTTL time.Duration, maxPerRepo int) error
    20  	DelImage(id ...digest.Digest) error
    21  }
    22  
    23  type ImageStoreRO interface {
    24  	Images() ([]*ImageInfo, error)
    25  	Image(id digest.Digest) (Image, error)
    26  	ImageByName(name string) (Image, error)
    27  }
    28  
    29  type ImageStoreRW interface {
    30  	ImageStoreRO
    31  	ImageUnpacker
    32  	ImportImage(name string) (Image, error)
    33  	SupportsTransport(transportName string) bool
    34  	AddImageConfig(m ispecs.Image, parentImageId *digest.Digest) (Image, error)
    35  	FS(imageId digest.Digest) (fs.FsNode, error)
    36  	// Creates a new layer as diff to parent. Returns errEmptyLayerDiff if nothing has changed
    37  	AddLayer(rootfs fs.FsNode, parentImageId *digest.Digest, author, createdByOp string) (Image, error)
    38  	TagImage(imageId digest.Digest, tag string) (ImageInfo, error)
    39  	UntagImage(tag string) error
    40  	Close() error
    41  }
    42  
    43  type ImageUnpacker interface {
    44  	UnpackImageLayers(id digest.Digest, rootfs string) error
    45  }
    46  
    47  type LayerSource interface {
    48  	DiffHash() (digest.Digest, error)
    49  	Close() error
    50  }
    51  
    52  type ErrNotExist error
    53  
    54  type ErrEmptyLayerDiff error
    55  
    56  func IsNotExist(err error) bool {
    57  	switch errors.Cause(err).(type) {
    58  	case ErrNotExist:
    59  		return true
    60  	}
    61  	return false
    62  }
    63  
    64  func IsEmptyLayerDiff(err error) bool {
    65  	switch errors.Cause(err).(type) {
    66  	case ErrEmptyLayerDiff:
    67  		return true
    68  	}
    69  	return false
    70  }
    71  
    72  func GetLocalImage(store ImageStoreRO, image string) (img Image, err error) {
    73  	if len(bytes.TrimSpace([]byte(image))) == 0 {
    74  		return img, errors.New("get image: no image specified")
    75  	}
    76  	if imgId, e := digest.Parse(image); e == nil && imgId.Validate() == nil {
    77  		return store.Image(imgId)
    78  	} else {
    79  		return store.ImageByName(image)
    80  	}
    81  }
    82  
    83  func GetImage(store ImageStoreRW, image string) (img Image, err error) {
    84  	if img, err = GetLocalImage(store, image); IsNotExist(err) {
    85  		img, err = store.ImportImage(image)
    86  	}
    87  	return
    88  }