oras
oras copied to clipboard
OCIStore is not concurrency safe at a process-level
When running multiple helm chart commands at the same time, there can be a race to write the updated OCIStore index reference resulting in missing references for later commands. Is it expected that this should work or should each helm chart command be given a new registry cache directory to avoid this?
Failing test case:
package content
import (
"io/ioutil"
"testing"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
func TestConcurrentSaveIndex(t *testing.T) {
tempdir, err := ioutil.TempDir("", "")
if err != nil {
t.Fatal(err)
}
store, err := NewOCIStore(tempdir)
if err != nil {
t.Fatal(err)
}
err = store.LoadIndex()
if err != nil {
t.Fatal(err)
}
parallelStore, err := NewOCIStore(tempdir)
if err != nil {
t.Fatal(err)
}
err = parallelStore.LoadIndex()
if err != nil {
t.Fatal(err)
}
store.AddReference("my-first-reference", ocispec.Descriptor{})
parallelStore.AddReference("my-second-reference", ocispec.Descriptor{})
err = store.SaveIndex()
if err != nil {
t.Fatal(err)
}
err = parallelStore.SaveIndex()
if err != nil {
t.Fatal(err)
}
err = store.LoadIndex()
if err != nil {
t.Fatal(err)
}
parallelStore.LoadIndex()
if err != nil {
t.Fatal(err)
}
if _, ok := store.ListReferences()["my-first-reference"]; !ok {
t.Error("Store does have have my-first-reference")
}
if _, ok := store.ListReferences()["my-second-reference"]; !ok {
t.Error("Store does have have my-second-reference")
}
if _, ok := parallelStore.ListReferences()["my-first-reference"]; !ok {
t.Error("Store does have have my-first-reference")
}
if _, ok := parallelStore.ListReferences()["my-second-reference"]; !ok {
t.Error("Store does have have my-second-reference")
}
}