mirror of
https://github.com/project-zot/zot.git
synced 2024-12-16 21:56:37 -05:00
dedupe: record relative path for cache entries
In a production use case we found that the actual rootdir can be moved. Currently, cache entries for dedupe record the full blob path which doesn't work in the move use case. Only for dedupe cache entries, record relative blob paths.
This commit is contained in:
parent
36efa17915
commit
cb9e773a3e
3 changed files with 27 additions and 10 deletions
|
@ -2,6 +2,7 @@ package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/anuvu/zot/errors"
|
"github.com/anuvu/zot/errors"
|
||||||
|
@ -14,6 +15,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Cache struct {
|
type Cache struct {
|
||||||
|
rootDir string
|
||||||
db *bbolt.DB
|
db *bbolt.DB
|
||||||
log zlog.Logger
|
log zlog.Logger
|
||||||
}
|
}
|
||||||
|
@ -45,10 +47,16 @@ func NewCache(rootDir string, name string, log zlog.Logger) *Cache {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Cache{db: db, log: log}
|
return &Cache{rootDir: rootDir, db: db, log: log}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) PutBlob(digest string, path string) error {
|
func (c *Cache) PutBlob(digest string, path string) error {
|
||||||
|
// use only relative (to rootDir) paths on blobs
|
||||||
|
relp, err := filepath.Rel(c.rootDir, path)
|
||||||
|
if err != nil {
|
||||||
|
c.log.Error().Err(err).Str("path", path).Msg("unable to get relative path")
|
||||||
|
}
|
||||||
|
|
||||||
if err := c.db.Update(func(tx *bbolt.Tx) error {
|
if err := c.db.Update(func(tx *bbolt.Tx) error {
|
||||||
root := tx.Bucket([]byte(BlobsCache))
|
root := tx.Bucket([]byte(BlobsCache))
|
||||||
if root == nil {
|
if root == nil {
|
||||||
|
@ -63,8 +71,8 @@ func (c *Cache) PutBlob(digest string, path string) error {
|
||||||
c.log.Error().Err(err).Str("bucket", digest).Msg("unable to create a bucket")
|
c.log.Error().Err(err).Str("bucket", digest).Msg("unable to create a bucket")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := b.Put([]byte(path), nil); err != nil {
|
if err := b.Put([]byte(relp), nil); err != nil {
|
||||||
c.log.Error().Err(err).Str("bucket", digest).Str("value", path).Msg("unable to put record")
|
c.log.Error().Err(err).Str("bucket", digest).Str("value", relp).Msg("unable to put record")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -135,6 +143,12 @@ func (c *Cache) HasBlob(digest string, blob string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) DeleteBlob(digest string, path string) error {
|
func (c *Cache) DeleteBlob(digest string, path string) error {
|
||||||
|
// use only relative (to rootDir) paths on blobs
|
||||||
|
relp, err := filepath.Rel(c.rootDir, path)
|
||||||
|
if err != nil {
|
||||||
|
c.log.Error().Err(err).Str("path", path).Msg("unable to get relative path")
|
||||||
|
}
|
||||||
|
|
||||||
if err := c.db.Update(func(tx *bbolt.Tx) error {
|
if err := c.db.Update(func(tx *bbolt.Tx) error {
|
||||||
root := tx.Bucket([]byte(BlobsCache))
|
root := tx.Bucket([]byte(BlobsCache))
|
||||||
if root == nil {
|
if root == nil {
|
||||||
|
@ -149,8 +163,8 @@ func (c *Cache) DeleteBlob(digest string, path string) error {
|
||||||
return errors.ErrCacheMiss
|
return errors.ErrCacheMiss
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := b.Delete([]byte(path)); err != nil {
|
if err := b.Delete([]byte(relp)); err != nil {
|
||||||
c.log.Error().Err(err).Str("digest", digest).Str("path", path).Msg("unable to delete")
|
c.log.Error().Err(err).Str("digest", digest).Str("path", relp).Msg("unable to delete")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,9 +172,9 @@ func (c *Cache) DeleteBlob(digest string, path string) error {
|
||||||
k, _ := cur.First()
|
k, _ := cur.First()
|
||||||
|
|
||||||
if k == nil {
|
if k == nil {
|
||||||
c.log.Debug().Str("digest", digest).Str("path", path).Msg("deleting empty bucket")
|
c.log.Debug().Str("digest", digest).Str("path", relp).Msg("deleting empty bucket")
|
||||||
if err := root.DeleteBucket([]byte(digest)); err != nil {
|
if err := root.DeleteBucket([]byte(digest)); err != nil {
|
||||||
c.log.Error().Err(err).Str("digest", digest).Str("path", path).Msg("unable to delete")
|
c.log.Error().Err(err).Str("digest", digest).Str("path", relp).Msg("unable to delete")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package storage_test
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/anuvu/zot/errors"
|
"github.com/anuvu/zot/errors"
|
||||||
|
@ -33,7 +34,7 @@ func TestCache(t *testing.T) {
|
||||||
b := c.HasBlob("key", "value")
|
b := c.HasBlob("key", "value")
|
||||||
So(b, ShouldBeFalse)
|
So(b, ShouldBeFalse)
|
||||||
|
|
||||||
err = c.PutBlob("key", "value")
|
err = c.PutBlob("key", path.Join(dir, "value"))
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
b = c.HasBlob("key", "value")
|
b = c.HasBlob("key", "value")
|
||||||
|
|
|
@ -849,6 +849,8 @@ retry:
|
||||||
}
|
}
|
||||||
is.log.Debug().Str("src", src).Str("dst", dst).Msg("dedupe: rename")
|
is.log.Debug().Str("src", src).Str("dst", dst).Msg("dedupe: rename")
|
||||||
} else {
|
} else {
|
||||||
|
dstRecord = path.Join(is.rootDir, dstRecord)
|
||||||
|
|
||||||
dstRecordFi, err := os.Stat(dstRecord)
|
dstRecordFi, err := os.Stat(dstRecord)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
is.log.Error().Err(err).Str("blobPath", dstRecord).Msg("dedupe: unable to stat")
|
is.log.Error().Err(err).Str("blobPath", dstRecord).Msg("dedupe: unable to stat")
|
||||||
|
|
Loading…
Reference in a new issue