Be more robust in our writing of mobystash state

Be more robust in our writing of mobystash state

diff --git a/.gitignore b/.gitignore
index 0ef2df1..4a61385 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,5 +4,5 @@
 /coverage
 /.bundle
 /tmp
-
 .rubocop-https---raw-githubusercontent-com-discourse-discourse-master--rubocop-yml
+/mobystash_state.dump
diff --git a/lib/mobystash/system.rb b/lib/mobystash/system.rb
index 20b556a..b1164ca 100644
--- a/lib/mobystash/system.rb
+++ b/lib/mobystash/system.rb
@@ -158,7 +158,12 @@ module Mobystash
     end
 
     def write_state_file
-      File.write(@config.state_file, Marshal.dump(container_state))
+      File.open("#{@config.state_file}.new", File::WRONLY | File::CREAT | File::TRUNC | 0600) do |fd|
+        fd.write Marshal.dump(container_state)
+        fd.fdatasync
+      end
+
+      File.rename("#{@config.state_file}.new", @config.state_file)
     end
 
     def container_state
diff --git a/spec/system_spec.rb b/spec/system_spec.rb
index 5708a72..d5b98f6 100644
--- a/spec/system_spec.rb
+++ b/spec/system_spec.rb
@@ -241,15 +241,15 @@ describe Mobystash::System do
           expect(c1).to receive(:last_log_timestamp).ordered
           expect(c2).to receive(:last_log_timestamp).ordered
 
-          expect(File)
-            .to receive(:write)
-            .with(
-              "./mobystash_state.dump",
-              Marshal.dump(
-                "c1" => "2018-01-01T01:01:01.111111111Z",
-                "c2" => "2018-02-02T02:02:02.222222222Z",
-              )
+          expect(File).to receive(:open).with("./mobystash_state.dump.new", File::WRONLY | File::CREAT | File::TRUNC | 0600).and_yield(mock_file = instance_double(File))
+          expect(mock_file).to receive(:write).with(
+            Marshal.dump(
+              "c1" => "2018-01-01T01:01:01.111111111Z",
+              "c2" => "2018-02-02T02:02:02.222222222Z",
             )
+          )
+          expect(mock_file).to receive(:fdatasync)
+          expect(File).to receive(:rename).with("./mobystash_state.dump.new", "./mobystash_state.dump")
 
           system.run
         end

GitHub sha: 79195a73