check lock when reading cache provider index (#4147)

Signed-off-by: Avi Deitcher <avi@deitcher.net>
This commit is contained in:
Avi Deitcher 2025-07-21 23:14:59 +03:00 committed by GitHub
parent bc44cb899c
commit eae788724a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 18 additions and 4 deletions

View File

@ -83,7 +83,7 @@ func (p *Provider) findIndex(imageName string) (v1.ImageIndex, error) {
// FindDescriptor get the first descriptor pointed to by the image reference, whether tagged or digested
func (p *Provider) FindDescriptor(ref *reference.Spec) (*v1.Descriptor, error) {
index, err := p.cache.ImageIndex()
index, err := p.Index()
// if there is no root index, we are broken
if err != nil {
return nil, fmt.Errorf("invalid image cache: %v", err)

View File

@ -14,7 +14,7 @@ func ListImages(dir string) (map[string]string, error) {
}
func (p *Provider) List() (map[string]string, error) {
ii, err := p.cache.ImageIndex()
ii, err := p.Index()
if err != nil {
return nil, err
}

View File

@ -7,6 +7,7 @@ import (
"github.com/containerd/containerd/v2/core/content"
"github.com/containerd/containerd/v2/plugins/content/local"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/layout"
"github.com/linuxkit/linuxkit/src/cmd/linuxkit/util"
log "github.com/sirupsen/logrus"
@ -37,6 +38,19 @@ func NewProvider(dir string) (*Provider, error) {
return p, nil
}
// Index returns the root image index for the cache.
// All attempts to read the index *must* use this function, so that it will lock the cache to prevent concurrent access.
// The underlying library writes modifications directly to the index,
// so not only must ensure that that only one process is writing at a time, but that no one is reading
// while we are writing, to avoid corruption.
func (p *Provider) Index() (v1.ImageIndex, error) {
if p.Lock() != nil {
return nil, fmt.Errorf("unable to lock cache %s", p.dir)
}
defer p.Unlock()
return p.cache.ImageIndex()
}
// Lock locks the cache directory to prevent concurrent access
func (p *Provider) Lock() error {
// if the lock is already set, we do not need to do anything

View File

@ -51,7 +51,7 @@ func (l layoutIndex) Digest() (v1.Hash, error) {
// a given imageName.
func (p *Provider) FindRoot(imageName string) (ResolvableDescriptor, error) {
matcher := match.Name(imageName)
rootIndex, err := p.cache.ImageIndex()
rootIndex, err := p.Index()
// of there is no root index, we are broken
if err != nil {
return nil, fmt.Errorf("invalid image cache: %v", err)

View File

@ -239,7 +239,7 @@ func (p *Provider) IndexWrite(ref *reference.Spec, descriptors ...v1.Descriptor)
return errors.New("cannot create index without any manifests")
}
ii, err := p.cache.ImageIndex()
ii, err := p.Index()
if err != nil {
return fmt.Errorf("unable to get root index: %v", err)
}