@cryptotaxi247 / kubo / commits / 8ea502f1b

clean up and fix init permissions handling

Jeromy committed May 20, 2015 at 08:55 UTC 8ea502f1b37dc103c988f13e7ac3fe3ec81f1d51
5 files changed +82 -19
cmd/ipfs/init.go
+47 -12
@@ -5,6 +5,8 @@ import (
5 "errors"
6 "fmt"
7 "io"
8 + "os"
9 + "path"
10
11 context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
12 assets "github.com/ipfs/go-ipfs/assets"
@@ -36,7 +38,10 @@ var initCmd = &cmds.Command{
38 // TODO cmds.StringOption("event-logs", "l", "Location for machine-readable event logs"),
39 },
40 PreRun: func(req cmds.Request) error {
39 - daemonLocked := fsrepo.LockedByOtherProcess(req.Context().ConfigRoot)
41 + daemonLocked, err := fsrepo.LockedByOtherProcess(req.Context().ConfigRoot)
42 + if err != nil {
43 + return err
44 + }
45
46 log.Info("checking if daemon is running...")
47 if daemonLocked {
@@ -47,6 +52,10 @@ var initCmd = &cmds.Command{
52 return nil
53 },
54 Run: func(req cmds.Request, res cmds.Response) {
55 + if req.Context().Online {
56 + res.SetError(errors.New("init must be run offline only!"), cmds.ErrNormal)
57 + return
58 + }
59
60 force, _, err := req.Option("f").Bool() // if !found, it's okay force == false
61 if err != nil {
@@ -64,15 +73,10 @@ var initCmd = &cmds.Command{
73 nBitsForKeypair = nBitsForKeypairDefault
74 }
75
67 - rpipe, wpipe := io.Pipe()
68 - go func() {
69 - defer wpipe.Close()
70 - if err := doInit(wpipe, req.Context().ConfigRoot, force, nBitsForKeypair); err != nil {
71 - res.SetError(err, cmds.ErrNormal)
72 - return
73 - }
74 - }()
75 - res.SetOutput(rpipe)
76 + if err := doInit(os.Stdout, req.Context().ConfigRoot, force, nBitsForKeypair); err != nil {
77 + res.SetError(err, cmds.ErrNormal)
78 + return
79 + }
80 },
81 }
82
@@ -82,8 +86,7 @@ Reinitializing would overwrite your keys.
86 `)
87
88 func initWithDefaults(out io.Writer, repoRoot string) error {
85 - err := doInit(out, repoRoot, false, nBitsForKeypairDefault)
86 - return err
89 + return doInit(out, repoRoot, false, nBitsForKeypairDefault)
90 }
91
92 func doInit(out io.Writer, repoRoot string, force bool, nBitsForKeypair int) error {
@@ -91,6 +94,10 @@ func doInit(out io.Writer, repoRoot string, force bool, nBitsForKeypair int) err
94 return err
95 }
96
97 + if err := checkWriteable(repoRoot); err != nil {
98 + return err
99 + }
100 +
101 if fsrepo.IsInitialized(repoRoot) && !force {
102 return errRepoExists
103 }
@@ -117,6 +124,34 @@ func doInit(out io.Writer, repoRoot string, force bool, nBitsForKeypair int) err
124 return initializeIpnsKeyspace(repoRoot)
125 }
126
127 +func checkWriteable(dir string) error {
128 + _, err := os.Stat(dir)
129 + if err == nil {
130 + // dir exists, make sure we can write to it
131 + testfile := path.Join(dir, "test")
132 + fi, err := os.Create(testfile)
133 + if err != nil {
134 + if os.IsPermission(err) {
135 + return fmt.Errorf("%s is not writeable by the current user", dir)
136 + }
137 + return fmt.Errorf("unexpected error while checking writeablility of repo root: %s", err)
138 + }
139 + fi.Close()
140 + return os.Remove(testfile)
141 + }
142 +
143 + if os.IsNotExist(err) {
144 + // dir doesnt exist, check that we can create it
145 + return os.Mkdir(dir, 0775)
146 + }
147 +
148 + if os.IsPermission(err) {
149 + return fmt.Errorf("cannot write to %s, incorrect permissions", err)
150 + }
151 +
152 + return err
153 +}
154 +
155 func addDefaultAssets(out io.Writer, repoRoot string) error {
156 ctx, cancel := context.WithCancel(context.Background())
157 defer cancel()
cmd/ipfs/main.go
+4 -1
@@ -387,7 +387,10 @@ func commandShouldRunOnDaemon(details cmdDetails, req cmds.Request, root *cmds.C
387
388 // at this point need to know whether daemon is running. we defer
389 // to this point so that some commands dont open files unnecessarily.
390 - daemonLocked := fsrepo.LockedByOtherProcess(req.Context().ConfigRoot)
390 + daemonLocked, err := fsrepo.LockedByOtherProcess(req.Context().ConfigRoot)
391 + if err != nil {
392 + return false, err
393 + }
394
395 if daemonLocked {
396
repo/fsrepo/fsrepo.go
+1 -1
@@ -283,7 +283,7 @@ func Remove(repoPath string) error {
283
284 // LockedByOtherProcess returns true if the FSRepo is locked by another
285 // process. If true, then the repo cannot be opened by this process.
286 -func LockedByOtherProcess(repoPath string) bool {
286 +func LockedByOtherProcess(repoPath string) (bool, error) {
287 repoPath = path.Clean(repoPath)
288
289 // TODO replace this with the "api" file
repo/fsrepo/lock/lock.go
+8 -4
@@ -2,6 +2,7 @@ package lock
2
3 import (
4 "io"
5 + "os"
6 "path"
7
8 lock "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/camlistore/lock"
@@ -17,14 +18,17 @@ func Lock(confdir string) (io.Closer, error) {
18 return c, err
19 }
20
20 -func Locked(confdir string) bool {
21 +func Locked(confdir string) (bool, error) {
22 if !util.FileExists(path.Join(confdir, LockFile)) {
22 - return false
23 + return false, nil
24 }
25 if lk, err := Lock(confdir); err != nil {
25 - return true
26 + if os.IsPermission(err) {
27 + return false, err
28 + }
29 + return true, nil
30 } else {
31 lk.Close()
28 - return false
32 + return false, nil
33 }
34 }
test/sharness/t0020-init.sh
+22 -1
@@ -8,6 +8,22 @@ test_description="Test init command"
8
9 . lib/test-lib.sh
10
11 +# test that ipfs fails to init if IPFS_PATH isnt writeable
12 +test_expect_success "create dir and change perms succeeds" '
13 + export IPFS_PATH="$(pwd)/.badipfs" &&
14 + mkdir "$IPFS_PATH" &&
15 + chmod 000 "$IPFS_PATH"
16 +'
17 +
18 +test_expect_success "ipfs init fails" '
19 + test_must_fail ipfs init 2> init_fail_out
20 +'
21 +
22 +test_expect_success "ipfs init output looks good" '
23 + echo "Error: open $IPFS_PATH/repo.lock: permission denied" > init_fail_exp &&
24 + test_cmp init_fail_out init_fail_exp
25 +'
26 +
27 test_expect_success "ipfs init succeeds" '
28 export IPFS_PATH="$(pwd)/.ipfs" &&
29 BITS="2048" &&
@@ -17,7 +33,8 @@ test_expect_success "ipfs init succeeds" '
33 test_expect_success ".ipfs/ has been created" '
34 test -d ".ipfs" &&
35 test -f ".ipfs/config" &&
20 - test -d ".ipfs/datastore" ||
36 + test -d ".ipfs/datastore" &&
37 + test -d ".ipfs/blocks" ||
38 test_fsh ls -al .ipfs
39 '
40
@@ -44,6 +61,10 @@ test_expect_success "ipfs init output looks good" '
61 test_cmp expected actual_init
62 '
63
64 +test_expect_success "clean up ipfs dir" '
65 + rm -rf "$IPFS_PATH"
66 +'
67 +
68 test_init_ipfs
69
70 test_launch_ipfs_daemon