Drop our dependency on github.com/containers/image

Drop our dependency on the image library's manifest package by requiring
that callers pass its Digest() function to us as a callback.  This makes
our CLI test/diagnostic tool calculate digests of s1 manifests
incorrectly, but that's not something that we were testing.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
Nalin Dahyabhai 2019-03-05 09:54:57 -05:00
parent 8caea6f790
commit 4867edfac1
5 changed files with 40 additions and 24 deletions

View File

@ -8,6 +8,7 @@ import (
"github.com/containers/storage" "github.com/containers/storage"
"github.com/containers/storage/pkg/mflag" "github.com/containers/storage/pkg/mflag"
digest "github.com/opencontainers/go-digest"
) )
var ( var (
@ -95,6 +96,10 @@ func getImageBigData(flags *mflag.FlagSet, action string, m storage.Store, args
return 0 return 0
} }
func wrongManifestDigest(b []byte) (digest.Digest, error) {
return digest.Canonical.FromBytes(b), nil
}
func getImageBigDataSize(flags *mflag.FlagSet, action string, m storage.Store, args []string) int { func getImageBigDataSize(flags *mflag.FlagSet, action string, m storage.Store, args []string) int {
image, err := m.Image(args[0]) image, err := m.Image(args[0])
if err != nil { if err != nil {
@ -149,7 +154,7 @@ func setImageBigData(flags *mflag.FlagSet, action string, m storage.Store, args
fmt.Fprintf(os.Stderr, "%v\n", err) fmt.Fprintf(os.Stderr, "%v\n", err)
return 1 return 1
} }
err = m.SetImageBigData(image.ID, args[1], b) err = m.SetImageBigData(image.ID, args[1], b, wrongManifestDigest)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err) fmt.Fprintf(os.Stderr, "%v\n", err)
return 1 return 1
@ -207,7 +212,7 @@ func init() {
command{ command{
names: []string{"set-image-data", "setimagedata"}, names: []string{"set-image-data", "setimagedata"},
optionsHelp: "[options [...]] imageNameOrID dataName", optionsHelp: "[options [...]] imageNameOrID dataName",
usage: "Set data that is attached to an image", usage: "Set data that is attached to an image (with sometimes wrong digest)",
action: setImageBigData, action: setImageBigData,
minArgs: 2, minArgs: 2,
addFlags: func(flags *mflag.FlagSet, cmd *command) { addFlags: func(flags *mflag.FlagSet, cmd *command) {

View File

@ -71,7 +71,7 @@ type Container struct {
type ContainerStore interface { type ContainerStore interface {
FileBasedStore FileBasedStore
MetadataStore MetadataStore
BigDataStore ContainerBigDataStore
FlaggableStore FlaggableStore
// Create creates a container that has a specified ID (or generates a // Create creates a container that has a specified ID (or generates a
@ -456,7 +456,7 @@ func (r *containerStore) BigDataSize(id, key string) (int64, error) {
return size, nil return size, nil
} }
if data, err := r.BigData(id, key); err == nil && data != nil { if data, err := r.BigData(id, key); err == nil && data != nil {
if r.SetBigData(id, key, data) == nil { if err = r.SetBigData(id, key, data); err == nil {
c, ok := r.lookup(id) c, ok := r.lookup(id)
if !ok { if !ok {
return -1, ErrContainerUnknown return -1, ErrContainerUnknown
@ -464,6 +464,8 @@ func (r *containerStore) BigDataSize(id, key string) (int64, error) {
if size, ok := c.BigDataSizes[key]; ok { if size, ok := c.BigDataSizes[key]; ok {
return size, nil return size, nil
} }
} else {
return -1, err
} }
} }
return -1, ErrSizeUnknown return -1, ErrSizeUnknown
@ -484,7 +486,7 @@ func (r *containerStore) BigDataDigest(id, key string) (digest.Digest, error) {
return d, nil return d, nil
} }
if data, err := r.BigData(id, key); err == nil && data != nil { if data, err := r.BigData(id, key); err == nil && data != nil {
if r.SetBigData(id, key, data) == nil { if err = r.SetBigData(id, key, data); err == nil {
c, ok := r.lookup(id) c, ok := r.lookup(id)
if !ok { if !ok {
return "", ErrContainerUnknown return "", ErrContainerUnknown
@ -492,6 +494,8 @@ func (r *containerStore) BigDataDigest(id, key string) (digest.Digest, error) {
if d, ok := c.BigDataDigests[key]; ok { if d, ok := c.BigDataDigests[key]; ok {
return d, nil return d, nil
} }
} else {
return "", err
} }
} }
return "", ErrDigestUnknown return "", ErrDigestUnknown

View File

@ -8,7 +8,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/containers/image/manifest"
"github.com/containers/storage/pkg/ioutils" "github.com/containers/storage/pkg/ioutils"
"github.com/containers/storage/pkg/stringid" "github.com/containers/storage/pkg/stringid"
"github.com/containers/storage/pkg/truncindex" "github.com/containers/storage/pkg/truncindex"
@ -117,7 +116,7 @@ type ImageStore interface {
ROImageStore ROImageStore
RWFileBasedStore RWFileBasedStore
RWMetadataStore RWMetadataStore
RWBigDataStore RWImageBigDataStore
FlaggableStore FlaggableStore
// Create creates an image that has a specified ID (or a random one) and // Create creates an image that has a specified ID (or a random one) and
@ -636,7 +635,7 @@ func imageSliceWithoutValue(slice []*Image, value *Image) []*Image {
return modified return modified
} }
func (r *imageStore) SetBigData(id, key string, data []byte) error { func (r *imageStore) SetBigData(id, key string, data []byte, digestManifest func([]byte) (digest.Digest, error)) error {
if key == "" { if key == "" {
return errors.Wrapf(ErrInvalidBigDataName, "can't set empty name for image big data item") return errors.Wrapf(ErrInvalidBigDataName, "can't set empty name for image big data item")
} }
@ -653,7 +652,10 @@ func (r *imageStore) SetBigData(id, key string, data []byte) error {
} }
var newDigest digest.Digest var newDigest digest.Digest
if bigDataNameIsManifest(key) { if bigDataNameIsManifest(key) {
if newDigest, err = manifest.Digest(data); err != nil { if digestManifest == nil {
return errors.Wrapf(ErrDigestUnknown, "error digesting manifest: no manifest digest callback provided")
}
if newDigest, err = digestManifest(data); err != nil {
return errors.Wrapf(err, "error digesting manifest") return errors.Wrapf(err, "error digesting manifest")
} }
} else { } else {

View File

@ -102,19 +102,21 @@ type ROBigDataStore interface {
BigDataNames(id string) ([]string, error) BigDataNames(id string) ([]string, error)
} }
// A RWBigDataStore wraps up the read-write big-data related methods of the // A RWImageBigDataStore wraps up how we store big-data associated with images.
// various types of file-based lookaside stores that we implement. type RWImageBigDataStore interface {
type RWBigDataStore interface { // SetBigData stores a (potentially large) piece of data associated
// SetBigData stores a (potentially large) piece of data associated with this // with this ID.
// ID. // Pass github.com/containers/image/manifest.Digest as digestManifest
SetBigData(id, key string, data []byte) error // to allow ByDigest to find images by their correct digests.
SetBigData(id, key string, data []byte, digestManifest func([]byte) (digest.Digest, error)) error
} }
// A BigDataStore wraps up the most common big-data related methods of the // A ContainerBigDataStore wraps up how we store big-data associated with containers.
// various types of file-based lookaside stores that we implement. type ContainerBigDataStore interface {
type BigDataStore interface {
ROBigDataStore ROBigDataStore
RWBigDataStore // SetBigData stores a (potentially large) piece of data associated
// with this ID.
SetBigData(id, key string, data []byte) error
} }
// A FlaggableStore can have flags set and cleared on items which it manages. // A FlaggableStore can have flags set and cleared on items which it manages.
@ -352,9 +354,11 @@ type Store interface {
// of named data associated with an image. // of named data associated with an image.
ImageBigDataDigest(id, key string) (digest.Digest, error) ImageBigDataDigest(id, key string) (digest.Digest, error)
// SetImageBigData stores a (possibly large) chunk of named data associated // SetImageBigData stores a (possibly large) chunk of named data
// with an image. // associated with an image. Pass
SetImageBigData(id, key string, data []byte) error // github.com/containers/image/manifest.Digest as digestManifest to
// allow ImagesByDigest to find images by their correct digests.
SetImageBigData(id, key string, data []byte, digestManifest func([]byte) (digest.Digest, error)) error
// ImageSize computes the size of the image's layers and ancillary data. // ImageSize computes the size of the image's layers and ancillary data.
ImageSize(id string) (int64, error) ImageSize(id string) (int64, error)
@ -1485,7 +1489,7 @@ func (s *store) ImageBigData(id, key string) ([]byte, error) {
return nil, ErrImageUnknown return nil, ErrImageUnknown
} }
func (s *store) SetImageBigData(id, key string, data []byte) error { func (s *store) SetImageBigData(id, key string, data []byte, digestManifest func([]byte) (digest.Digest, error)) error {
ristore, err := s.ImageStore() ristore, err := s.ImageStore()
if err != nil { if err != nil {
return err return err
@ -1499,7 +1503,7 @@ func (s *store) SetImageBigData(id, key string, data []byte) error {
} }
} }
return ristore.SetBigData(id, key, data) return ristore.SetBigData(id, key, data, digestManifest)
} }
func (s *store) ImageSize(id string) (int64, error) { func (s *store) ImageSize(id string) (int64, error) {

View File

@ -131,6 +131,7 @@ load helpers
run storage get-container-data-size $container no-such-item run storage get-container-data-size $container no-such-item
[ "$status" -ne 0 ] [ "$status" -ne 0 ]
run storage --debug=false get-container-data-size $container big-item-1 run storage --debug=false get-container-data-size $container big-item-1
echo "$output"
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
[ "$output" -eq 1234 ] [ "$output" -eq 1234 ]
run storage --debug=false get-container-data-size $container big-item-2 run storage --debug=false get-container-data-size $container big-item-2