diff --git a/main.go b/main.go index ded396ff0..1303d038b 100644 --- a/main.go +++ b/main.go @@ -27,6 +27,7 @@ import ( "github.com/coreos/etcd/etcdserver" "github.com/coreos/etcd/etcdserver/etcdhttp" "github.com/coreos/etcd/pkg/cors" + "github.com/coreos/etcd/pkg/fileutil" "github.com/coreos/etcd/pkg/flags" "github.com/coreos/etcd/pkg/transport" "github.com/coreos/etcd/pkg/types" @@ -152,6 +153,9 @@ func startEtcd() { if err := os.MkdirAll(*dir, privateDirMode); err != nil { log.Fatalf("etcd: cannot create data directory: %v", err) } + if err := fileutil.IsDirWriteable(*dir); err != nil { + log.Fatalf("etcd: cannot write to data directory: %v", err) + } pt, err := transport.NewTransport(peerTLSInfo) if err != nil { diff --git a/pkg/fileutil/fileutil.go b/pkg/fileutil/fileutil.go new file mode 100644 index 000000000..382d7b0fa --- /dev/null +++ b/pkg/fileutil/fileutil.go @@ -0,0 +1,37 @@ +/* + Copyright 2014 CoreOS, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package fileutil + +import ( + "io/ioutil" + "os" + "path" +) + +const ( + privateFileMode = 0600 +) + +// IsDirWriteable checks if dir is writable by writing and removing a file +// to dir. It returns nil if dir is writable. +func IsDirWriteable(dir string) error { + f := path.Join(dir, ".touch") + if err := ioutil.WriteFile(f, []byte(""), privateFileMode); err != nil { + return err + } + return os.Remove(f) +} diff --git a/pkg/fileutil/fileutil_test.go b/pkg/fileutil/fileutil_test.go new file mode 100644 index 000000000..6add5fdc4 --- /dev/null +++ b/pkg/fileutil/fileutil_test.go @@ -0,0 +1,39 @@ +/* + Copyright 2014 CoreOS, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package fileutil + +import ( + "io/ioutil" + "os" + "testing" +) + +func TestIsDirWriteable(t *testing.T) { + tmpdir, err := ioutil.TempDir("", "") + if err != nil { + t.Fatalf("unexpected ioutil.TempDir error: %v", err) + } + if err := IsDirWriteable(tmpdir); err != nil { + t.Fatalf("unexpected IsDirWriteable error: %v", err) + } + if err := os.Chmod(tmpdir, 0444); err != nil { + t.Fatalf("unexpected os.Chmod error: %v", err) + } + if err := IsDirWriteable(tmpdir); err == nil { + t.Fatalf("expected IsDirWriteable to error") + } +}