Merge pull request #9124 from dmcgowan/cri-image-store-no-client
Update CRI image store to not use containerd client
This commit is contained in:
commit
3ebe5d1c56
@ -27,6 +27,7 @@ import (
|
||||
imagestore "github.com/containerd/containerd/pkg/cri/store/image"
|
||||
snapshotstore "github.com/containerd/containerd/pkg/cri/store/snapshot"
|
||||
"github.com/containerd/containerd/pkg/kmutex"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
docker "github.com/distribution/reference"
|
||||
imagedigest "github.com/opencontainers/go-digest"
|
||||
)
|
||||
@ -52,7 +53,7 @@ func NewService(config criconfig.Config, imageFSPath string, client *containerd.
|
||||
svc := CRIImageService{
|
||||
config: config,
|
||||
client: client,
|
||||
imageStore: imagestore.NewStore(client),
|
||||
imageStore: imagestore.NewStore(client.ImageService(), client.ContentStore(), platforms.Default()),
|
||||
imageFSPath: imageFSPath,
|
||||
snapshotStore: snapshotstore.NewStore(),
|
||||
unpackDuplicationSuppressor: kmutex.New(),
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
criconfig "github.com/containerd/containerd/pkg/cri/config"
|
||||
imagestore "github.com/containerd/containerd/pkg/cri/store/image"
|
||||
snapshotstore "github.com/containerd/containerd/pkg/cri/store/snapshot"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@ -42,7 +43,7 @@ func newTestCRIService() *CRIImageService {
|
||||
return &CRIImageService{
|
||||
config: testConfig,
|
||||
imageFSPath: testImageFSPath,
|
||||
imageStore: imagestore.NewStore(nil),
|
||||
imageStore: imagestore.NewStore(nil, nil, platforms.Default()),
|
||||
snapshotStore: snapshotstore.NewStore(),
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"github.com/containerd/containerd/pkg/cri/nri"
|
||||
"github.com/containerd/containerd/pkg/cri/streaming"
|
||||
"github.com/containerd/containerd/pkg/kmutex"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/containerd/plugin"
|
||||
cni "github.com/containerd/go-cni"
|
||||
"google.golang.org/grpc"
|
||||
@ -128,7 +129,7 @@ func NewCRIService(config criconfig.Config, client *containerd.Client, nri *nri.
|
||||
os: osinterface.RealOS{},
|
||||
sandboxStore: sandboxstore.NewStore(labels),
|
||||
containerStore: containerstore.NewStore(labels),
|
||||
imageStore: imagestore.NewStore(client),
|
||||
imageStore: imagestore.NewStore(client.ImageService(), client.ContentStore(), platforms.Default()),
|
||||
snapshotStore: snapshotstore.NewStore(),
|
||||
sandboxNameIndex: registrar.NewRegistrar(),
|
||||
containerNameIndex: registrar.NewRegistrar(),
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/oci"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
"github.com/containerd/go-cni"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -45,7 +46,7 @@ func newTestCRIService() *criService {
|
||||
imageFSPath: testImageFSPath,
|
||||
os: ostesting.NewFakeOS(),
|
||||
sandboxStore: sandboxstore.NewStore(labels),
|
||||
imageStore: imagestore.NewStore(nil),
|
||||
imageStore: imagestore.NewStore(nil, nil, platforms.Default()),
|
||||
snapshotStore: snapshotstore.NewStore(),
|
||||
sandboxNameIndex: registrar.NewRegistrar(),
|
||||
containerStore: containerstore.NewStore(labels),
|
||||
|
@ -16,12 +16,16 @@
|
||||
|
||||
package image
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containerd/containerd/platforms"
|
||||
)
|
||||
|
||||
// NewFakeStore returns an image store with predefined images.
|
||||
// Update is not allowed for this fake store.
|
||||
func NewFakeStore(images []Image) (*Store, error) {
|
||||
s := NewStore(nil)
|
||||
s := NewStore(nil, nil, platforms.Default())
|
||||
for _, i := range images {
|
||||
for _, ref := range i.References {
|
||||
s.refCache[ref] = i.ID
|
||||
|
@ -18,15 +18,20 @@ package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/images"
|
||||
"github.com/containerd/containerd/images/usage"
|
||||
"github.com/containerd/containerd/pkg/cri/labels"
|
||||
"github.com/containerd/containerd/pkg/cri/util"
|
||||
"github.com/containerd/containerd/platforms"
|
||||
docker "github.com/distribution/reference"
|
||||
|
||||
"github.com/opencontainers/go-digest"
|
||||
imagedigest "github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/go-digest/digestset"
|
||||
imageidentity "github.com/opencontainers/image-spec/identity"
|
||||
@ -50,22 +55,39 @@ type Image struct {
|
||||
Pinned bool
|
||||
}
|
||||
|
||||
// InfoProvider provides both content and info about content
|
||||
type InfoProvider interface {
|
||||
content.Provider
|
||||
Info(ctx context.Context, dgst digest.Digest) (content.Info, error)
|
||||
}
|
||||
|
||||
// Store stores all images.
|
||||
type Store struct {
|
||||
lock sync.RWMutex
|
||||
// refCache is a containerd image reference to image id cache.
|
||||
refCache map[string]string
|
||||
// client is the containerd client.
|
||||
client *containerd.Client
|
||||
|
||||
// images is the local image store
|
||||
images images.Store
|
||||
|
||||
// content provider
|
||||
provider InfoProvider
|
||||
|
||||
// platform represents the currently supported platform for images
|
||||
// TODO: Make this store multi-platform
|
||||
platform platforms.MatchComparer
|
||||
|
||||
// store is the internal image store indexed by image id.
|
||||
store *store
|
||||
}
|
||||
|
||||
// NewStore creates an image store.
|
||||
func NewStore(client *containerd.Client) *Store {
|
||||
func NewStore(img images.Store, provider InfoProvider, platform platforms.MatchComparer) *Store {
|
||||
return &Store{
|
||||
refCache: make(map[string]string),
|
||||
client: client,
|
||||
images: img,
|
||||
provider: provider,
|
||||
platform: platform,
|
||||
store: &store{
|
||||
images: make(map[string]Image),
|
||||
digestSet: digestset.NewSet(),
|
||||
@ -77,13 +99,15 @@ func NewStore(client *containerd.Client) *Store {
|
||||
func (s *Store) Update(ctx context.Context, ref string) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
i, err := s.client.GetImage(ctx, ref)
|
||||
|
||||
i, err := s.images.Get(ctx, ref)
|
||||
if err != nil && !errdefs.IsNotFound(err) {
|
||||
return fmt.Errorf("get image from containerd: %w", err)
|
||||
}
|
||||
|
||||
var img *Image
|
||||
if err == nil {
|
||||
img, err = getImage(ctx, i)
|
||||
img, err = s.getImage(ctx, i)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get image info from containerd: %w", err)
|
||||
}
|
||||
@ -116,36 +140,40 @@ func (s *Store) update(ref string, img *Image) error {
|
||||
return s.store.add(*img)
|
||||
}
|
||||
|
||||
// getImage gets image information from containerd.
|
||||
func getImage(ctx context.Context, i containerd.Image) (*Image, error) {
|
||||
// Get image information.
|
||||
diffIDs, err := i.RootFS(ctx)
|
||||
// getImage gets image information from containerd for current platform.
|
||||
func (s *Store) getImage(ctx context.Context, i images.Image) (*Image, error) {
|
||||
diffIDs, err := i.RootFS(ctx, s.provider, s.platform)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get image diffIDs: %w", err)
|
||||
}
|
||||
chainID := imageidentity.ChainID(diffIDs)
|
||||
|
||||
size, err := i.Size(ctx)
|
||||
size, err := usage.CalculateImageUsage(ctx, i, s.provider, usage.WithManifestLimit(s.platform, 1), usage.WithManifestUsage())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get image compressed resource size: %w", err)
|
||||
}
|
||||
|
||||
desc, err := i.Config(ctx)
|
||||
desc, err := i.Config(ctx, s.provider, s.platform)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get image config descriptor: %w", err)
|
||||
}
|
||||
id := desc.Digest.String()
|
||||
|
||||
spec, err := i.Spec(ctx)
|
||||
blob, err := content.ReadBlob(ctx, s.provider, desc)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get OCI image spec: %w", err)
|
||||
return nil, fmt.Errorf("read image config from content store: %w", err)
|
||||
}
|
||||
|
||||
pinned := i.Labels()[labels.PinnedImageLabelKey] == labels.PinnedImageLabelValue
|
||||
var spec imagespec.Image
|
||||
if err := json.Unmarshal(blob, &spec); err != nil {
|
||||
return nil, fmt.Errorf("unmarshal image config %s: %w", blob, err)
|
||||
}
|
||||
|
||||
pinned := i.Labels[labels.PinnedImageLabelKey] == labels.PinnedImageLabelValue
|
||||
|
||||
return &Image{
|
||||
ID: id,
|
||||
References: []string{i.Name()},
|
||||
References: []string{i.Name},
|
||||
ChainID: chainID.String(),
|
||||
Size: size,
|
||||
ImageSpec: spec,
|
||||
|
Loading…
Reference in New Issue
Block a user