diff --git a/libmachine/persist/filestore.go b/libmachine/persist/filestore.go index 739e9b5fc8..62263dfe8a 100644 --- a/libmachine/persist/filestore.go +++ b/libmachine/persist/filestore.go @@ -31,7 +31,31 @@ func (s Filestore) GetMachinesDir() string { } func (s Filestore) saveToFile(data []byte, file string) error { - return ioutil.WriteFile(file, data, 0600) + if _, err := os.Stat(file); os.IsNotExist(err) { + return ioutil.WriteFile(file, data, 0600) + } + + tmpfi, err := ioutil.TempFile(filepath.Dir(file), "config.json.tmp") + if err != nil { + return err + } + defer os.Remove(tmpfi.Name()) + + err = ioutil.WriteFile(tmpfi.Name(), data, 0600) + if err != nil { + return err + } + + err = os.Remove(file) + if err != nil { + return err + } + + err = os.Rename(tmpfi.Name(), file) + if err != nil { + return err + } + return nil } func (s Filestore) Save(host *host.Host) error { diff --git a/libmachine/persist/filestore_test.go b/libmachine/persist/filestore_test.go index 9928f89a3b..874ecda43b 100644 --- a/libmachine/persist/filestore_test.go +++ b/libmachine/persist/filestore_test.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "path/filepath" + "regexp" "testing" "github.com/docker/machine/commands/mcndirs" @@ -52,6 +53,17 @@ func TestStoreSave(t *testing.T) { if _, err := os.Stat(path); os.IsNotExist(err) { t.Fatalf("Host path doesn't exist: %s", path) } + + files, _ := ioutil.ReadDir(path) + for _, f := range files { + r, err := regexp.Compile("config.json.tmp*") + if err != nil { + t.Fatalf("Failed to compile regexp string") + } + if r.MatchString(f.Name()) { + t.Fatalf("Failed to remove temp filestore:%s", f.Name()) + } + } } func TestStoreSaveOmitRawDriver(t *testing.T) {