mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-30 09:59:13 +08:00
3
Makefile
3
Makefile
@ -16,6 +16,9 @@ install:
|
||||
build:
|
||||
cd cmd/ipfs && go build -i
|
||||
|
||||
nofuse:
|
||||
cd cmd/ipfs && go install -tags nofuse
|
||||
|
||||
##############################################################
|
||||
# tests targets
|
||||
|
||||
|
28
core/commands/mount_nofuse.go
Normal file
28
core/commands/mount_nofuse.go
Normal file
@ -0,0 +1,28 @@
|
||||
// +build (linux darwin freebsd) and nofuse
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
cmds "github.com/jbenet/go-ipfs/commands"
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
)
|
||||
|
||||
var MountCmd = &cmds.Command{
|
||||
Helptext: cmds.HelpText{
|
||||
Tagline: "Mounts IPFS to the filesystem (disabled)",
|
||||
ShortDescription: `
|
||||
This version of ipfs is compiled without fuse support, which is required
|
||||
for mounting. If you'd like to be able to mount, please use a version of
|
||||
ipfs compiled with fuse.
|
||||
|
||||
For the latest instructions, please check the project's repository:
|
||||
http://github.com/jbenet/go-ipfs
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
func Mount(node *core.IpfsNode, fsdir, nsdir string) error {
|
||||
return errors.New("not compiled in")
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// +build linux darwin freebsd
|
||||
// +build (linux darwin freebsd) and !nofuse
|
||||
|
||||
package commands
|
||||
|
||||
|
37
fuse/ipns/common.go
Normal file
37
fuse/ipns/common.go
Normal file
@ -0,0 +1,37 @@
|
||||
package ipns
|
||||
|
||||
import (
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
mdag "github.com/jbenet/go-ipfs/merkledag"
|
||||
nsys "github.com/jbenet/go-ipfs/namesys"
|
||||
ci "github.com/jbenet/go-ipfs/p2p/crypto"
|
||||
ft "github.com/jbenet/go-ipfs/unixfs"
|
||||
)
|
||||
|
||||
// InitializeKeyspace sets the ipns record for the given key to
|
||||
// point to an empty directory.
|
||||
func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error {
|
||||
emptyDir := &mdag.Node{Data: ft.FolderPBData()}
|
||||
nodek, err := n.DAG.Add(emptyDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = n.Pinning.Pin(emptyDir, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = n.Pinning.Flush()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pub := nsys.NewRoutingPublisher(n.Routing)
|
||||
err = pub.Publish(n.Context(), key, nodek)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -1,15 +1,17 @@
|
||||
// +build !nofuse
|
||||
|
||||
package ipns
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
fstest "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil"
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
|
||||
|
||||
core "github.com/jbenet/go-ipfs/core"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
|
@ -1,3 +1,5 @@
|
||||
// +build !nofuse
|
||||
|
||||
// package fuse/ipns implements a fuse filesystem that interfaces
|
||||
// with ipns, the naming system for ipfs.
|
||||
package ipns
|
||||
@ -18,7 +20,6 @@ import (
|
||||
core "github.com/jbenet/go-ipfs/core"
|
||||
chunk "github.com/jbenet/go-ipfs/importer/chunk"
|
||||
mdag "github.com/jbenet/go-ipfs/merkledag"
|
||||
nsys "github.com/jbenet/go-ipfs/namesys"
|
||||
ci "github.com/jbenet/go-ipfs/p2p/crypto"
|
||||
path "github.com/jbenet/go-ipfs/path"
|
||||
ft "github.com/jbenet/go-ipfs/unixfs"
|
||||
@ -37,34 +38,6 @@ var (
|
||||
longRepublishTimeout = time.Millisecond * 500
|
||||
)
|
||||
|
||||
// InitializeKeyspace sets the ipns record for the given key to
|
||||
// point to an empty directory.
|
||||
func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error {
|
||||
emptyDir := &mdag.Node{Data: ft.FolderPBData()}
|
||||
nodek, err := n.DAG.Add(emptyDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = n.Pinning.Pin(emptyDir, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = n.Pinning.Flush()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pub := nsys.NewRoutingPublisher(n.Routing)
|
||||
err = pub.Publish(n.Context(), key, nodek)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FileSystem is the readwrite IPNS Fuse Filesystem.
|
||||
type FileSystem struct {
|
||||
Ipfs *core.IpfsNode
|
||||
|
@ -1,3 +1,5 @@
|
||||
// +build !nofuse
|
||||
|
||||
package ipns
|
||||
|
||||
import (
|
||||
|
@ -1,4 +1,4 @@
|
||||
// +build linux darwin freebsd
|
||||
// +build (linux darwin freebsd) and !nofuse
|
||||
|
||||
package ipns
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
// +build !nofuse
|
||||
|
||||
package ipns
|
||||
|
||||
import "time"
|
||||
|
121
fuse/mount/fuse.go
Normal file
121
fuse/mount/fuse.go
Normal file
@ -0,0 +1,121 @@
|
||||
// +build !nofuse
|
||||
|
||||
package mount
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
|
||||
)
|
||||
|
||||
// mount implements go-ipfs/fuse/mount
|
||||
type mount struct {
|
||||
mpoint string
|
||||
filesys fs.FS
|
||||
fuseConn *fuse.Conn
|
||||
// closeErr error
|
||||
|
||||
cg ctxgroup.ContextGroup
|
||||
}
|
||||
|
||||
// Mount mounts a fuse fs.FS at a given location, and returns a Mount instance.
|
||||
// parent is a ContextGroup to bind the mount's ContextGroup to.
|
||||
func NewMount(p ctxgroup.ContextGroup, fsys fs.FS, mountpoint string) (Mount, error) {
|
||||
conn, err := fuse.Mount(mountpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m := &mount{
|
||||
mpoint: mountpoint,
|
||||
fuseConn: conn,
|
||||
filesys: fsys,
|
||||
cg: ctxgroup.WithParent(p), // link it to parent.
|
||||
}
|
||||
m.cg.SetTeardown(m.unmount)
|
||||
|
||||
// launch the mounting process.
|
||||
if err := m.mount(); err != nil {
|
||||
m.Unmount() // just in case.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m *mount) mount() error {
|
||||
log.Infof("Mounting %s", m.MountPoint())
|
||||
|
||||
errs := make(chan error, 1)
|
||||
go func() {
|
||||
err := fs.Serve(m.fuseConn, m.filesys)
|
||||
log.Debugf("Mounting %s -- fs.Serve returned (%s)", err)
|
||||
errs <- err
|
||||
close(errs)
|
||||
}()
|
||||
|
||||
// wait for the mount process to be done, or timed out.
|
||||
select {
|
||||
case <-time.After(MountTimeout):
|
||||
return fmt.Errorf("Mounting %s timed out.", m.MountPoint())
|
||||
case err := <-errs:
|
||||
return err
|
||||
case <-m.fuseConn.Ready:
|
||||
}
|
||||
|
||||
// check if the mount process has an error to report
|
||||
if err := m.fuseConn.MountError; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("Mounted %s", m.MountPoint())
|
||||
return nil
|
||||
}
|
||||
|
||||
// umount is called exactly once to unmount this service.
|
||||
// note that closing the connection will not always unmount
|
||||
// properly. If that happens, we bring out the big guns
|
||||
// (mount.ForceUnmountManyTimes, exec unmount).
|
||||
func (m *mount) unmount() error {
|
||||
log.Infof("Unmounting %s", m.MountPoint())
|
||||
|
||||
// try unmounting with fuse lib
|
||||
err := fuse.Unmount(m.MountPoint())
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
log.Debug("fuse unmount err: %s", err)
|
||||
|
||||
// try closing the fuseConn
|
||||
err = m.fuseConn.Close()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
log.Debug("fuse conn error: %s", err)
|
||||
}
|
||||
|
||||
// try mount.ForceUnmountManyTimes
|
||||
if err := ForceUnmountManyTimes(m, 10); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("Seemingly unmounted %s", m.MountPoint())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mount) CtxGroup() ctxgroup.ContextGroup {
|
||||
return m.cg
|
||||
}
|
||||
|
||||
func (m *mount) MountPoint() string {
|
||||
return m.mpoint
|
||||
}
|
||||
|
||||
func (m *mount) Unmount() error {
|
||||
// call ContextCloser Close(), which calls unmount() exactly once.
|
||||
return m.cg.Close()
|
||||
}
|
@ -7,8 +7,6 @@ import (
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
fuse "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
|
||||
fs "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs"
|
||||
ctxgroup "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
|
||||
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
@ -31,115 +29,6 @@ type Mount interface {
|
||||
CtxGroup() ctxgroup.ContextGroup
|
||||
}
|
||||
|
||||
// mount implements go-ipfs/fuse/mount
|
||||
type mount struct {
|
||||
mpoint string
|
||||
filesys fs.FS
|
||||
fuseConn *fuse.Conn
|
||||
// closeErr error
|
||||
|
||||
cg ctxgroup.ContextGroup
|
||||
}
|
||||
|
||||
// Mount mounts a fuse fs.FS at a given location, and returns a Mount instance.
|
||||
// parent is a ContextGroup to bind the mount's ContextGroup to.
|
||||
func NewMount(p ctxgroup.ContextGroup, fsys fs.FS, mountpoint string) (Mount, error) {
|
||||
conn, err := fuse.Mount(mountpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m := &mount{
|
||||
mpoint: mountpoint,
|
||||
fuseConn: conn,
|
||||
filesys: fsys,
|
||||
cg: ctxgroup.WithParent(p), // link it to parent.
|
||||
}
|
||||
m.cg.SetTeardown(m.unmount)
|
||||
|
||||
// launch the mounting process.
|
||||
if err := m.mount(); err != nil {
|
||||
m.Unmount() // just in case.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m *mount) mount() error {
|
||||
log.Infof("Mounting %s", m.MountPoint())
|
||||
|
||||
errs := make(chan error, 1)
|
||||
go func() {
|
||||
err := fs.Serve(m.fuseConn, m.filesys)
|
||||
log.Debugf("Mounting %s -- fs.Serve returned (%s)", err)
|
||||
errs <- err
|
||||
close(errs)
|
||||
}()
|
||||
|
||||
// wait for the mount process to be done, or timed out.
|
||||
select {
|
||||
case <-time.After(MountTimeout):
|
||||
return fmt.Errorf("Mounting %s timed out.", m.MountPoint())
|
||||
case err := <-errs:
|
||||
return err
|
||||
case <-m.fuseConn.Ready:
|
||||
}
|
||||
|
||||
// check if the mount process has an error to report
|
||||
if err := m.fuseConn.MountError; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("Mounted %s", m.MountPoint())
|
||||
return nil
|
||||
}
|
||||
|
||||
// umount is called exactly once to unmount this service.
|
||||
// note that closing the connection will not always unmount
|
||||
// properly. If that happens, we bring out the big guns
|
||||
// (mount.ForceUnmountManyTimes, exec unmount).
|
||||
func (m *mount) unmount() error {
|
||||
log.Infof("Unmounting %s", m.MountPoint())
|
||||
|
||||
// try unmounting with fuse lib
|
||||
err := fuse.Unmount(m.MountPoint())
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
log.Debug("fuse unmount err: %s", err)
|
||||
|
||||
// try closing the fuseConn
|
||||
err = m.fuseConn.Close()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
log.Debug("fuse conn error: %s", err)
|
||||
}
|
||||
|
||||
// try mount.ForceUnmountManyTimes
|
||||
if err := ForceUnmountManyTimes(m, 10); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("Seemingly unmounted %s", m.MountPoint())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mount) CtxGroup() ctxgroup.ContextGroup {
|
||||
return m.cg
|
||||
}
|
||||
|
||||
func (m *mount) MountPoint() string {
|
||||
return m.mpoint
|
||||
}
|
||||
|
||||
func (m *mount) Unmount() error {
|
||||
// call ContextCloser Close(), which calls unmount() exactly once.
|
||||
return m.cg.Close()
|
||||
}
|
||||
|
||||
// ForceUnmount attempts to forcibly unmount a given mount.
|
||||
// It does so by calling diskutil or fusermount directly.
|
||||
func ForceUnmount(m Mount) error {
|
||||
|
@ -1,3 +1,5 @@
|
||||
// +build !nofuse
|
||||
|
||||
package readonly
|
||||
|
||||
import (
|
||||
|
@ -1,4 +1,4 @@
|
||||
// +build linux darwin freebsd
|
||||
// +build (linux darwin freebsd) and !nofuse
|
||||
|
||||
package readonly
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// +build linux darwin freebsd
|
||||
// +build (linux darwin freebsd) and !nofuse
|
||||
|
||||
// package fuse/readonly implements a fuse filesystem to access files
|
||||
// stored inside of ipfs.
|
||||
|
Reference in New Issue
Block a user