Write the spec file during initialization only.

License: MIT
Signed-off-by: Kevin Atkinson <k@kevina.org>
This commit is contained in:
Kevin Atkinson 2017-07-14 05:07:32 -04:00 committed by Jeromy
parent d64ab3ce0f
commit ce62bed82e
3 changed files with 36 additions and 28 deletions

View File

@ -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

View File

@ -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()

View File

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