@cryptotaxi247 / kubo / commits / 1c5979e54

core/commands2: Added 'mount' command

Matt Bell committed Nov 6, 2014 at 00:36 UTC 1c5979e549a647a9be71f878244b6b6d6c9a44da
4 files changed +165
core/commands2/mount_darwin.go new
+33
@@ -0,0 +1,33 @@
1 +package commands
2 +
3 +import (
4 + "fmt"
5 + "runtime"
6 + "strings"
7 + "syscall"
8 +)
9 +
10 +func init() {
11 + // this is a hack, but until we need to do it another way, this works.
12 + platformFuseChecks = darwinFuseCheckVersion
13 +}
14 +
15 +func darwinFuseCheckVersion() error {
16 + // on OSX, check FUSE version.
17 + if runtime.GOOS != "darwin" {
18 + return nil
19 + }
20 +
21 + ov, err := syscall.Sysctl("osxfuse.version.number")
22 + if err != nil {
23 + return err
24 + }
25 +
26 + if strings.HasPrefix(ov, "2.7.") || strings.HasPrefix(ov, "2.8.") {
27 + return nil
28 + }
29 +
30 + return fmt.Errorf("osxfuse version %s not supported.\n%s\n%s", ov,
31 + "Older versions of osxfuse have kernel panic bugs; please upgrade!",
32 + "https://github.com/jbenet/go-ipfs/issues/177")
33 +}
core/commands2/mount_unix.go new
+117
@@ -0,0 +1,117 @@
1 +// +build linux darwin freebsd
2 +
3 +package commands
4 +
5 +import (
6 + "fmt"
7 + "time"
8 +
9 + cmds "github.com/jbenet/go-ipfs/commands"
10 + "github.com/jbenet/go-ipfs/config"
11 + core "github.com/jbenet/go-ipfs/core"
12 + ipns "github.com/jbenet/go-ipfs/fuse/ipns"
13 + rofs "github.com/jbenet/go-ipfs/fuse/readonly"
14 +)
15 +
16 +// amount of time to wait for mount errors
17 +const mountTimeout = time.Second
18 +
19 +var mountCmd = &cmds.Command{
20 + Options: []cmds.Option{
21 + cmds.Option{[]string{"f"}, cmds.String},
22 + cmds.Option{[]string{"n"}, cmds.String},
23 + },
24 + Help: `ipfs mount <os-path> - Mount an ipfs read-only mountpoint.
25 +
26 + Mount ipfs at a read-only mountpoint on the OS. All ipfs objects
27 + will be accessible under that directory. Note that the root will
28 + not be listable, as it is virtual. Accessing known paths directly.
29 +`,
30 + Run: func(res cmds.Response, req cmds.Request) {
31 + ctx := req.Context()
32 +
33 + // error if we aren't running node in online mode
34 + if ctx.Node.Network == nil {
35 + res.SetError(errNotOnline, cmds.ErrNormal)
36 + return
37 + }
38 +
39 + if err := platformFuseChecks(); err != nil {
40 + res.SetError(err, cmds.ErrNormal)
41 + return
42 + }
43 +
44 + // update fsdir with flag.
45 + fsdir := ctx.Config.Mounts.IPFS
46 + opt, _ := req.Option("f")
47 + if val, ok := opt.(string); ok && val != "" {
48 + fsdir = val
49 + }
50 + fsdone := mountIpfs(ctx.Node, fsdir)
51 +
52 + // get default mount points
53 + nsdir := ctx.Config.Mounts.IPNS
54 + opt, _ = req.Option("f")
55 + if val, ok := opt.(string); ok && val != "" {
56 + nsdir = val
57 + }
58 + nsdone := mountIpns(ctx.Node, nsdir, fsdir)
59 +
60 + // wait until mounts return an error (or timeout if successful)
61 + var err error
62 + select {
63 + case err = <-fsdone:
64 + case err = <-nsdone:
65 +
66 + // mounted successfully, we timed out with no errors
67 + case <-time.After(mountTimeout):
68 + output := ctx.Config.Mounts
69 + res.SetOutput(&output)
70 + return
71 + }
72 +
73 + res.SetError(err, cmds.ErrNormal)
74 + },
75 + Type: &config.Mounts{},
76 + Marshallers: map[cmds.EncodingType]cmds.Marshaller{
77 + cmds.Text: func(res cmds.Response) ([]byte, error) {
78 + v := res.Output().(*config.Mounts)
79 + s := fmt.Sprintf("IPFS mounted at: %s\n", v.IPFS)
80 + s += fmt.Sprintf("IPNS mounted at: %s\n", v.IPNS)
81 + return []byte(s), nil
82 + },
83 + },
84 +}
85 +
86 +func mountIpfs(node *core.IpfsNode, fsdir string) <-chan error {
87 + done := make(chan error)
88 + log.Info("Mounting IPFS at ", fsdir)
89 +
90 + go func() {
91 + err := rofs.Mount(node, fsdir)
92 + done <- err
93 + close(done)
94 + }()
95 +
96 + return done
97 +}
98 +
99 +func mountIpns(node *core.IpfsNode, nsdir, fsdir string) <-chan error {
100 + if nsdir == "" {
101 + return nil
102 + }
103 + done := make(chan error)
104 + log.Info("Mounting IPNS at ", nsdir)
105 +
106 + go func() {
107 + err := ipns.Mount(node, nsdir, fsdir)
108 + done <- err
109 + close(done)
110 + }()
111 +
112 + return done
113 +}
114 +
115 +var platformFuseChecks = func() error {
116 + return nil
117 +}
core/commands2/mount_windows.go new
+14
@@ -0,0 +1,14 @@
1 +package commands
2 +
3 +import (
4 + "errors"
5 +
6 + cmds "github.com/jbenet/go-ipfs/commands"
7 +)
8 +
9 +var ipfsMount = &cmds.Command{
10 + Help: `Not yet implemented on Windows.`,
11 + Run: func(res cmds.Response, req cmds.Request) {
12 + res.SetError(errors.New("Mount isn't compatible with Windows yet"), cmds.ErrNormal)
13 + },
14 +}
core/commands2/root.go
+1
@@ -68,6 +68,7 @@ var rootSubcommands = map[string]*cmds.Command{
68 "version": versionCmd,
69 "config": configCmd,
70 "bootstrap": bootstrapCmd,
71 + "mount": mountCmd,
72
73 // test subcommands
74 // TODO: remove these when we don't need them anymore