diff --git a/content/local/store.go b/content/local/store.go index e1baee4c27..efe886014c 100644 --- a/content/local/store.go +++ b/content/local/store.go @@ -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 diff --git a/content/local/store_test.go b/content/local/store_test.go index 48ad54a0b7..8fcedce829 100644 --- a/content/local/store_test.go +++ b/content/local/store_test.go @@ -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 {