mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-19 17:26:28 +00:00
leverage file locks for cache index.json
Signed-off-by: Avi Deitcher <avi@deitcher.net>
This commit is contained in:
parent
e6a1de1330
commit
9e4d499119
28
src/cmd/linuxkit/cache/cacheindex.go
vendored
28
src/cmd/linuxkit/cache/cacheindex.go
vendored
@ -6,13 +6,19 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/match"
|
"github.com/google/go-containerregistry/pkg/v1/match"
|
||||||
|
"github.com/linuxkit/linuxkit/src/cmd/linuxkit/util"
|
||||||
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
indexFile = "index.json"
|
||||||
|
)
|
||||||
|
|
||||||
// DescriptorWrite writes a descriptor to the cache index; it validates that it has a name
|
// DescriptorWrite writes a descriptor to the cache index; it validates that it has a name
|
||||||
// and replaces any existing one
|
// and replaces any existing one
|
||||||
func (p *Provider) DescriptorWrite(image string, desc v1.Descriptor) error {
|
func (p *Provider) DescriptorWrite(image string, desc v1.Descriptor) error {
|
||||||
@ -25,6 +31,17 @@ func (p *Provider) DescriptorWrite(image string, desc v1.Descriptor) error {
|
|||||||
desc.Annotations[imagespec.AnnotationRefName] = image
|
desc.Annotations[imagespec.AnnotationRefName] = image
|
||||||
log.Debugf("writing descriptor for image %s", image)
|
log.Debugf("writing descriptor for image %s", image)
|
||||||
|
|
||||||
|
// get our lock
|
||||||
|
lock, err := util.Lock(filepath.Join(p.dir, indexFile))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to lock cache index for writing descriptor for %s: %v", image, err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := lock.Unlock(); err != nil {
|
||||||
|
log.Errorf("unable to close lock for cache index after writing descriptor for %s: %v", image, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
// do we update an existing one? Or create a new one?
|
// do we update an existing one? Or create a new one?
|
||||||
if err := p.cache.RemoveDescriptors(match.Name(image)); err != nil {
|
if err := p.cache.RemoveDescriptors(match.Name(image)); err != nil {
|
||||||
return fmt.Errorf("unable to remove old descriptors for %s: %v", image, err)
|
return fmt.Errorf("unable to remove old descriptors for %s: %v", image, err)
|
||||||
@ -40,6 +57,15 @@ func (p *Provider) DescriptorWrite(image string, desc v1.Descriptor) error {
|
|||||||
// RemoveDescriptors removes all descriptors that match the provided matcher.
|
// RemoveDescriptors removes all descriptors that match the provided matcher.
|
||||||
// It does so in a parallel-access-safe way
|
// It does so in a parallel-access-safe way
|
||||||
func (p *Provider) RemoveDescriptors(matcher match.Matcher) error {
|
func (p *Provider) RemoveDescriptors(matcher match.Matcher) error {
|
||||||
// will be replaced with locking
|
// get our lock
|
||||||
|
lock, err := util.Lock(filepath.Join(p.dir, indexFile))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to lock cache index for removing descriptor for %v: %v", matcher, err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := lock.Unlock(); err != nil {
|
||||||
|
log.Errorf("unable to close lock for cache index after writing descriptor for %v: %v", matcher, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
return p.cache.RemoveDescriptors(matcher)
|
return p.cache.RemoveDescriptors(matcher)
|
||||||
}
|
}
|
||||||
|
12
src/cmd/linuxkit/cache/open.go
vendored
12
src/cmd/linuxkit/cache/open.go
vendored
@ -2,9 +2,12 @@ package cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/google/go-containerregistry/pkg/v1/empty"
|
"github.com/google/go-containerregistry/pkg/v1/empty"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/layout"
|
"github.com/google/go-containerregistry/pkg/v1/layout"
|
||||||
|
"github.com/linuxkit/linuxkit/src/cmd/linuxkit/util"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Get get or initialize the cache
|
// Get get or initialize the cache
|
||||||
@ -12,6 +15,15 @@ func Get(cache string) (layout.Path, error) {
|
|||||||
// initialize the cache path if needed
|
// initialize the cache path if needed
|
||||||
p, err := layout.FromPath(cache)
|
p, err := layout.FromPath(cache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
lock, err := util.Lock(filepath.Join(cache, indexFile))
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("unable to lock cache index for writing descriptor for new cache: %v", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := lock.Unlock(); err != nil {
|
||||||
|
log.Errorf("unable to close lock for cache index after writing descriptor for new cache: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
p, err = layout.Write(cache, empty.Index)
|
p, err = layout.Write(cache, empty.Index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return p, fmt.Errorf("could not initialize cache at path %s: %v", cache, err)
|
return p, fmt.Errorf("could not initialize cache at path %s: %v", cache, err)
|
||||||
|
3
src/cmd/linuxkit/cache/provider.go
vendored
3
src/cmd/linuxkit/cache/provider.go
vendored
@ -10,6 +10,7 @@ import (
|
|||||||
type Provider struct {
|
type Provider struct {
|
||||||
cache layout.Path
|
cache layout.Path
|
||||||
store content.Store
|
store content.Store
|
||||||
|
dir string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProvider create a new CacheProvider based in the provided directory
|
// NewProvider create a new CacheProvider based in the provided directory
|
||||||
@ -22,5 +23,5 @@ func NewProvider(dir string) (*Provider, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Provider{p, store}, nil
|
return &Provider{p, store, dir}, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user