github.com/zignig/go-ipfs@v0.0.0-20141111235910-c9e5fdf55a52/core/commands2/mount_unix.go (about)

     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  	Description: "Mounts IPFS to the filesystem (read-only)",
    21  	Help: `Mount ipfs at a read-only mountpoint on the OS. All ipfs objects
    22  will be accessible under that directory. Note that the root will
    23  not be listable, as it is virtual. Accessing known paths directly.
    24  `,
    25  
    26  	Options: []cmds.Option{
    27  		// TODO longform
    28  		cmds.StringOption("f", "The path where IPFS should be mounted\n(default is '/ipfs')"),
    29  
    30  		// TODO longform
    31  		cmds.StringOption("n", "The path where IPNS should be mounted\n(default is '/ipns')"),
    32  	},
    33  	Run: func(req cmds.Request) (interface{}, error) {
    34  		ctx := req.Context()
    35  
    36  		// error if we aren't running node in online mode
    37  		if ctx.Node.Network == nil {
    38  			return nil, errNotOnline
    39  		}
    40  
    41  		if err := platformFuseChecks(); err != nil {
    42  			return nil, err
    43  		}
    44  
    45  		// update fsdir with flag.
    46  		fsdir := ctx.Config.Mounts.IPFS
    47  		if req.Option("f").Found() {
    48  			fsdir, _ = req.Option("f").String()
    49  		}
    50  		fsdone := mountIpfs(ctx.Node, fsdir)
    51  
    52  		// get default mount points
    53  		nsdir := ctx.Config.Mounts.IPNS
    54  		if req.Option("n").Found() {
    55  			nsdir, _ = req.Option("n").String()
    56  		}
    57  		nsdone := mountIpns(ctx.Node, nsdir, fsdir)
    58  
    59  		// wait until mounts return an error (or timeout if successful)
    60  		var err error
    61  		select {
    62  		case err = <-fsdone:
    63  		case err = <-nsdone:
    64  
    65  		// mounted successfully, we timed out with no errors
    66  		case <-time.After(mountTimeout):
    67  			output := ctx.Config.Mounts
    68  			return &output, nil
    69  		}
    70  
    71  		return nil, err
    72  	},
    73  	Type: &config.Mounts{},
    74  	Marshallers: map[cmds.EncodingType]cmds.Marshaller{
    75  		cmds.Text: func(res cmds.Response) ([]byte, error) {
    76  			v := res.Output().(*config.Mounts)
    77  			s := fmt.Sprintf("IPFS mounted at: %s\n", v.IPFS)
    78  			s += fmt.Sprintf("IPNS mounted at: %s\n", v.IPNS)
    79  			return []byte(s), nil
    80  		},
    81  	},
    82  }
    83  
    84  func mountIpfs(node *core.IpfsNode, fsdir string) <-chan error {
    85  	done := make(chan error)
    86  	log.Info("Mounting IPFS at ", fsdir)
    87  
    88  	go func() {
    89  		err := rofs.Mount(node, fsdir)
    90  		done <- err
    91  		close(done)
    92  	}()
    93  
    94  	return done
    95  }
    96  
    97  func mountIpns(node *core.IpfsNode, nsdir, fsdir string) <-chan error {
    98  	if nsdir == "" {
    99  		return nil
   100  	}
   101  	done := make(chan error)
   102  	log.Info("Mounting IPNS at ", nsdir)
   103  
   104  	go func() {
   105  		err := ipns.Mount(node, nsdir, fsdir)
   106  		done <- err
   107  		close(done)
   108  	}()
   109  
   110  	return done
   111  }
   112  
   113  var platformFuseChecks = func() error {
   114  	return nil
   115  }