oras icon indicating copy to clipboard operation
oras copied to clipboard

OCIStore is not concurrency safe at a process-level

Open steved opened this issue 5 years ago • 4 comments

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")
	}
}

steved avatar Feb 14 '20 23:02 steved