mirror of
https://github.com/containerd/containerd.git
synced 2026-08-09 17:39:22 +00:00
local: avoid writing to content root on readonly store
A contentstore can be created on top of readonly path and
should not fail unless there is an attempt to write into it.
Currently this fails because new ingest directory is created
always, meaning for example that you can't create a store to
read blobs from OCI layout without it contaminating the OCI
layout files.
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit 3cc2343de0)
Signed-off-by: Austin Vazquez <macedonv@amazon.com>
This commit is contained in:
committed by
Austin Vazquez
parent
b67a788072
commit
ddf2b03edf
@@ -67,6 +67,8 @@ type LabelStore interface {
|
||||
type store struct {
|
||||
root string
|
||||
ls LabelStore
|
||||
|
||||
ensureIngestRootOnce func() error
|
||||
}
|
||||
|
||||
// NewStore returns a local content store
|
||||
@@ -80,14 +82,13 @@ func NewStore(root string) (content.Store, error) {
|
||||
// require labels and should use `NewStore`. `NewLabeledStore` is primarily
|
||||
// useful for tests or standalone implementations.
|
||||
func NewLabeledStore(root string, ls LabelStore) (content.Store, error) {
|
||||
if err := os.MkdirAll(filepath.Join(root, "ingest"), 0777); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &store{
|
||||
s := &store{
|
||||
root: root,
|
||||
ls: ls,
|
||||
}, nil
|
||||
}
|
||||
|
||||
s.ensureIngestRootOnce = sync.OnceValue(s.ensureIngestRoot)
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *store) Info(ctx context.Context, dgst digest.Digest) (content.Info, error) {
|
||||
@@ -294,6 +295,9 @@ func (s *store) Status(ctx context.Context, ref string) (content.Status, error)
|
||||
func (s *store) ListStatuses(ctx context.Context, fs ...string) ([]content.Status, error) {
|
||||
fp, err := os.Open(filepath.Join(s.root, "ingest"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -344,6 +348,9 @@ func (s *store) ListStatuses(ctx context.Context, fs ...string) ([]content.Statu
|
||||
func (s *store) WalkStatusRefs(ctx context.Context, fn func(string) error) error {
|
||||
fp, err := os.Open(filepath.Join(s.root, "ingest"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -545,6 +552,11 @@ func (s *store) writer(ctx context.Context, ref string, total int64, expected di
|
||||
)
|
||||
|
||||
foundValidIngest := false
|
||||
|
||||
if err := s.ensureIngestRootOnce(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ensure that the ingest path has been created.
|
||||
if err := os.Mkdir(path, 0755); err != nil {
|
||||
if !os.IsExist(err) {
|
||||
@@ -655,6 +667,10 @@ func (s *store) ingestPaths(ref string) (string, string, string) {
|
||||
return fp, rp, dp
|
||||
}
|
||||
|
||||
func (s *store) ensureIngestRoot() error {
|
||||
return os.MkdirAll(filepath.Join(s.root, "ingest"), 0777)
|
||||
}
|
||||
|
||||
func readFileString(path string) (string, error) {
|
||||
p, err := os.ReadFile(path)
|
||||
return string(p), err
|
||||
|
||||
@@ -106,10 +106,6 @@ func TestContentWriter(t *testing.T) {
|
||||
defer cleanup()
|
||||
defer testutil.DumpDirOnFailure(t, tmpdir)
|
||||
|
||||
if _, err := os.Stat(filepath.Join(tmpdir, "ingest")); os.IsNotExist(err) {
|
||||
t.Fatal("ingest dir should be created", err)
|
||||
}
|
||||
|
||||
cw, err := cs.Writer(ctx, content.WithRef("myref"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -118,6 +114,10 @@ func TestContentWriter(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(filepath.Join(tmpdir, "ingest")); os.IsNotExist(err) {
|
||||
t.Fatal("ingest dir should be created", err)
|
||||
}
|
||||
|
||||
// reopen, so we can test things
|
||||
cw, err = cs.Writer(ctx, content.WithRef("myref"))
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user