Commit 1c5979e5 authored by Matt Bell's avatar Matt Bell Committed by Juan Batiz-Benet

core/commands2: Added 'mount' command

parent 16c584ce
package commands
import (
"fmt"
"runtime"
"strings"
"syscall"
)
func init() {
// this is a hack, but until we need to do it another way, this works.
platformFuseChecks = darwinFuseCheckVersion
}
func darwinFuseCheckVersion() error {
// on OSX, check FUSE version.
if runtime.GOOS != "darwin" {
return nil
}
ov, err := syscall.Sysctl("osxfuse.version.number")
if err != nil {
return err
}
if strings.HasPrefix(ov, "2.7.") || strings.HasPrefix(ov, "2.8.") {
return nil
}
return fmt.Errorf("osxfuse version %s not supported.\n%s\n%s", ov,
"Older versions of osxfuse have kernel panic bugs; please upgrade!",
"https://github.com/jbenet/go-ipfs/issues/177")
}
// +build linux darwin freebsd
package commands
import (
"fmt"
"time"
cmds "github.com/jbenet/go-ipfs/commands"
"github.com/jbenet/go-ipfs/config"
core "github.com/jbenet/go-ipfs/core"
ipns "github.com/jbenet/go-ipfs/fuse/ipns"
rofs "github.com/jbenet/go-ipfs/fuse/readonly"
)
// amount of time to wait for mount errors
const mountTimeout = time.Second
var mountCmd = &cmds.Command{
Options: []cmds.Option{
cmds.Option{[]string{"f"}, cmds.String},
cmds.Option{[]string{"n"}, cmds.String},
},
Help: `ipfs mount <os-path> - Mount an ipfs read-only mountpoint.
Mount ipfs at a read-only mountpoint on the OS. All ipfs objects
will be accessible under that directory. Note that the root will
not be listable, as it is virtual. Accessing known paths directly.
`,
Run: func(res cmds.Response, req cmds.Request) {
ctx := req.Context()
// error if we aren't running node in online mode
if ctx.Node.Network == nil {
res.SetError(errNotOnline, cmds.ErrNormal)
return
}
if err := platformFuseChecks(); err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
// update fsdir with flag.
fsdir := ctx.Config.Mounts.IPFS
opt, _ := req.Option("f")
if val, ok := opt.(string); ok && val != "" {
fsdir = val
}
fsdone := mountIpfs(ctx.Node, fsdir)
// get default mount points
nsdir := ctx.Config.Mounts.IPNS
opt, _ = req.Option("f")
if val, ok := opt.(string); ok && val != "" {
nsdir = val
}
nsdone := mountIpns(ctx.Node, nsdir, fsdir)
// wait until mounts return an error (or timeout if successful)
var err error
select {
case err = <-fsdone:
case err = <-nsdone:
// mounted successfully, we timed out with no errors
case <-time.After(mountTimeout):
output := ctx.Config.Mounts
res.SetOutput(&output)
return
}
res.SetError(err, cmds.ErrNormal)
},
Type: &config.Mounts{},
Marshallers: map[cmds.EncodingType]cmds.Marshaller{
cmds.Text: func(res cmds.Response) ([]byte, error) {
v := res.Output().(*config.Mounts)
s := fmt.Sprintf("IPFS mounted at: %s\n", v.IPFS)
s += fmt.Sprintf("IPNS mounted at: %s\n", v.IPNS)
return []byte(s), nil
},
},
}
func mountIpfs(node *core.IpfsNode, fsdir string) <-chan error {
done := make(chan error)
log.Info("Mounting IPFS at ", fsdir)
go func() {
err := rofs.Mount(node, fsdir)
done <- err
close(done)
}()
return done
}
func mountIpns(node *core.IpfsNode, nsdir, fsdir string) <-chan error {
if nsdir == "" {
return nil
}
done := make(chan error)
log.Info("Mounting IPNS at ", nsdir)
go func() {
err := ipns.Mount(node, nsdir, fsdir)
done <- err
close(done)
}()
return done
}
var platformFuseChecks = func() error {
return nil
}
package commands
import (
"errors"
cmds "github.com/jbenet/go-ipfs/commands"
)
var ipfsMount = &cmds.Command{
Help: `Not yet implemented on Windows.`,
Run: func(res cmds.Response, req cmds.Request) {
res.SetError(errors.New("Mount isn't compatible with Windows yet"), cmds.ErrNormal)
},
}
......@@ -68,6 +68,7 @@ var rootSubcommands = map[string]*cmds.Command{
"version": versionCmd,
"config": configCmd,
"bootstrap": bootstrapCmd,
"mount": mountCmd,
// test subcommands
// TODO: remove these when we don't need them anymore
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment