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 }