diff --git a/cmd/core/metastore.go b/cmd/core/metastore.go index a0696a6b..feaba18c 100644 --- a/cmd/core/metastore.go +++ b/cmd/core/metastore.go @@ -135,7 +135,14 @@ func MetaStore(conf *config.Config) (meta.Store, error) { if conf.MetaBackend == "" { log.WithFunc("core.MetaStore").Info(ctx, "legacy json meta store in use; `cocoon meta convert` upgrades it to sqlite") } - if s, err := metajson.Open(MetaJSONNamespaces(conf)...); err != nil { + nss := MetaJSONNamespaces(conf) + for _, ns := range nss { + if err := utils.EnsureDirs(filepath.Dir(ns.LockPath)); err != nil { + metaErr = err + return + } + } + if s, err := metajson.Open(nss...); err != nil { metaErr = err } else { metaStore = s diff --git a/cmd/core/metastore_test.go b/cmd/core/metastore_test.go index 6f7f5165..c92bafa9 100644 --- a/cmd/core/metastore_test.go +++ b/cmd/core/metastore_test.go @@ -7,6 +7,8 @@ import ( "testing" "github.com/cocoonstack/cocoon/config" + "github.com/cocoonstack/cocoon/hypervisor" + "github.com/cocoonstack/cocoon/meta" "github.com/cocoonstack/cocoon/utils" ) @@ -39,6 +41,23 @@ func TestMetaStoreBootstrapsFreshRoot(t *testing.T) { resetMetaStore() } +func TestMetaStoreJSONFreshRootLocksPeerNamespace(t *testing.T) { + resetMetaStore() + conf := testConf(t) + conf.MetaBackend = config.MetaBackendJSON + s, err := MetaStore(conf) + if err != nil { + t.Fatalf("open fresh json root: %v", err) + } + ch := hypervisor.VMNamespaceName(string(config.HypervisorCloudHypervisor)) + fc := hypervisor.VMNamespaceName(string(config.HypervisorFirecracker)) + if err := s.Update(t.Context(), meta.Scope{Write: ch, Read: []string{fc}}, meta.CommitDurable, func(meta.Writer) error { return nil }); err != nil { + t.Fatalf("placement-shaped update on a fresh json root: %v", err) + } + CloseMetaStore(t.Context()) + resetMetaStore() +} + func TestMetaStoreKeepsLegacyJSON(t *testing.T) { resetMetaStore() conf := testConf(t)