diff --git a/repo/fsrepo/datastores.go b/repo/fsrepo/datastores.go index c5b81ce15..4d7306f56 100644 --- a/repo/fsrepo/datastores.go +++ b/repo/fsrepo/datastores.go @@ -31,14 +31,17 @@ type DatastoreConfig interface { Create(path string) (repo.Datastore, error) } -func (spec DiskSpec) String() string { +func (spec DiskSpec) Bytes() []byte { b, err := json.Marshal(spec) if err != nil { // should not happen panic(err) } - b = bytes.TrimSpace(b) - return string(b) + return bytes.TrimSpace(b) +} + +func (spec DiskSpec) String() string { + return string(spec.Bytes()) } var datastores map[string]ConfigFromMap diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index 44ef42382..b81052118 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -240,9 +240,29 @@ func initConfig(path string, conf *config.Config) error { if err := serialize.WriteConfigFile(configFilename, conf); err != nil { return err } + return nil } +func initSpec(path string, conf map[string]interface{}) error { + fn, err := config.Path(path, SpecFn) + if err != nil { + return err + } + + if util.FileExists(fn) { + return nil + } + + dsc, err := AnyDatastoreConfig(conf) + if err != nil { + return err + } + bytes := dsc.DiskSpec().Bytes() + + return ioutil.WriteFile(fn, bytes, 0600) +} + // Init initializes a new FSRepo at the given path with the provided config. // TODO add support for custom datastores. func Init(repoPath string, conf *config.Config) error { @@ -260,6 +280,10 @@ func Init(repoPath string, conf *config.Config) error { return err } + if err := initSpec(repoPath, conf.Datastore.Spec); err != nil { + return err + } + if err := mfsr.RepoPath(repoPath).WriteVersion(RepoVersion); err != nil { return err } @@ -370,19 +394,13 @@ func (r *FSRepo) openDatastore() error { spec := dsc.DiskSpec() oldSpec, err := r.readSpec() - if err == nil { - if oldSpec != spec.String() { - return fmt.Errorf("Datastore configuration of '%s' does not match what is on disk '%s'", - oldSpec, spec.String()) - } - } else if os.IsNotExist(err) { - err := r.writeSpec(spec.String()) - if err != nil { - return err - } - } else { + if err != nil { return err } + if oldSpec != spec.String() { + return fmt.Errorf("Datastore configuration of '%s' does not match what is on disk '%s'", + oldSpec, spec.String()) + } d, err := dsc.Create(r.path) if err != nil { @@ -411,19 +429,6 @@ func (r *FSRepo) readSpec() (string, error) { return strings.TrimSpace(string(b)), nil } -func (r *FSRepo) writeSpec(spec string) error { - fn, err := config.Path(r.path, SpecFn) - if err != nil { - return err - } - b := []byte(spec) - err = ioutil.WriteFile(fn, b, 0600) - if err != nil { - return err - } - return nil -} - // Close closes the FSRepo, releasing held resources. func (r *FSRepo) Close() error { packageLock.Lock() diff --git a/repo/fsrepo/fsrepo_test.go b/repo/fsrepo/fsrepo_test.go index c886db1d6..73ae54ab2 100644 --- a/repo/fsrepo/fsrepo_test.go +++ b/repo/fsrepo/fsrepo_test.go @@ -25,7 +25,7 @@ func TestInitIdempotence(t *testing.T) { t.Parallel() path := testRepoPath("", t) for i := 0; i < 10; i++ { - assert.Nil(Init(path, &config.Config{}), t, "multiple calls to init should succeed") + assert.Nil(Init(path, &config.Config{Datastore: config.DefaultDatastoreConfig()}), t, "multiple calls to init should succeed") } }