diff --git a/clientv3/snapshot/v3_snapshot.go b/clientv3/snapshot/v3_snapshot.go index c29e175db29..10bfd00da1e 100644 --- a/clientv3/snapshot/v3_snapshot.go +++ b/clientv3/snapshot/v3_snapshot.go @@ -102,7 +102,7 @@ func (s *v3Manager) Save(ctx context.Context, cfg clientv3.Config, dbPath string defer os.RemoveAll(partpath) var f *os.File - f, err = os.Create(partpath) + f, err = os.OpenFile(partpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, fileutil.PrivateFileMode) if err != nil { return fmt.Errorf("could not open %s (%v)", partpath, err) } diff --git a/clientv3/snapshot/v3_snapshot_test.go b/clientv3/snapshot/v3_snapshot_test.go index 5443e9b79d7..dc1c892ecad 100644 --- a/clientv3/snapshot/v3_snapshot_test.go +++ b/clientv3/snapshot/v3_snapshot_test.go @@ -26,6 +26,7 @@ import ( "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/embed" + "github.com/coreos/etcd/pkg/fileutil" "github.com/coreos/etcd/pkg/testutil" "go.uber.org/zap" @@ -141,6 +142,25 @@ func TestSnapshotV3RestoreMulti(t *testing.T) { } } +// TestSnapshotFilePermissions ensures that the snapshot is saved with +// the correct file permissions. +func TestSnapshotFilePermissions(t *testing.T) { + expectedFileMode := os.FileMode(fileutil.PrivateFileMode) + kvs := []kv{{"foo1", "bar1"}, {"foo2", "bar2"}, {"foo3", "bar3"}} + dbPath := createSnapshotFile(t, kvs) + defer os.RemoveAll(dbPath) + + dbInfo, err := os.Stat(dbPath) + if err != nil { + t.Fatalf("failed to get test snapshot file status: %v", err) + } + actualFileMode := dbInfo.Mode() + + if expectedFileMode != actualFileMode { + t.Fatalf("expected test snapshot file mode %s, got %s:", expectedFileMode, actualFileMode) + } +} + type kv struct { k, v string }