From 76b1546211ad618cf0d2740380d41dab84750cc0 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 21 Aug 2019 19:17:01 -0700 Subject: [PATCH] mount: switch over to the CoreAPI 1. Fix resolution of sharded directories. 2. Slowly kill off users of the IpfsNode object. --- fuse/ipns/ipns_test.go | 8 +++- fuse/ipns/ipns_unix.go | 102 +++++++++++++++------------------------- fuse/ipns/mount_unix.go | 8 +++- 3 files changed, 51 insertions(+), 67 deletions(-) diff --git a/fuse/ipns/ipns_test.go b/fuse/ipns/ipns_test.go index a9406670e..8b749f74d 100644 --- a/fuse/ipns/ipns_test.go +++ b/fuse/ipns/ipns_test.go @@ -16,6 +16,7 @@ import ( "bazil.org/fuse" core "github.com/ipfs/go-ipfs/core" + coreapi "github.com/ipfs/go-ipfs/core/coreapi" fstest "bazil.org/fuse/fs/fstestutil" racedet "github.com/ipfs/go-detect-race" @@ -115,7 +116,12 @@ func setupIpnsTest(t *testing.T, node *core.IpfsNode) (*core.IpfsNode, *mountWra } } - fs, err := NewFileSystem(node, node.PrivateKey, "", "") + coreApi, err := coreapi.NewCoreAPI(node) + if err != nil { + t.Fatal(err) + } + + fs, err := NewFileSystem(node.Context(), coreApi, "", "") if err != nil { t.Fatal(err) } diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index 6b18b716d..64233a3be 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -10,22 +10,19 @@ import ( "fmt" "io" "os" - - core "github.com/ipfs/go-ipfs/core" - namesys "github.com/ipfs/go-ipfs/namesys" - resolve "github.com/ipfs/go-ipfs/namesys/resolve" + "strings" dag "github.com/ipfs/go-merkledag" - path "github.com/ipfs/go-path" ft "github.com/ipfs/go-unixfs" + path "github.com/ipfs/interface-go-ipfs-core/path" fuse "bazil.org/fuse" fs "bazil.org/fuse/fs" cid "github.com/ipfs/go-cid" logging "github.com/ipfs/go-log" mfs "github.com/ipfs/go-mfs" - ci "github.com/libp2p/go-libp2p-core/crypto" - peer "github.com/libp2p/go-libp2p-core/peer" + iface "github.com/ipfs/interface-go-ipfs-core" + options "github.com/ipfs/interface-go-ipfs-core/options" ) func init() { @@ -40,17 +37,17 @@ var log = logging.Logger("fuse/ipns") // FileSystem is the readwrite IPNS Fuse Filesystem. type FileSystem struct { - Ipfs *core.IpfsNode + Ipfs iface.CoreAPI RootNode *Root } // NewFileSystem constructs new fs using given core.IpfsNode instance. -func NewFileSystem(ipfs *core.IpfsNode, sk ci.PrivKey, ipfspath, ipnspath string) (*FileSystem, error) { - - kmap := map[string]ci.PrivKey{ - "local": sk, +func NewFileSystem(ctx context.Context, ipfs iface.CoreAPI, ipfspath, ipnspath string) (*FileSystem, error) { + key, err := ipfs.Key().Self(ctx) + if err != nil { + return nil, err } - root, err := CreateRoot(ipfs, kmap, ipfspath, ipnspath) + root, err := CreateRoot(ctx, ipfs, map[string]iface.Key{"local": key}, ipfspath, ipnspath) if err != nil { return nil, err } @@ -73,80 +70,62 @@ func (f *FileSystem) Destroy() { // Root is the root object of the filesystem tree. type Root struct { - Ipfs *core.IpfsNode - Keys map[string]ci.PrivKey + Ipfs iface.CoreAPI + Keys map[string]iface.Key // Used for symlinking into ipfs IpfsRoot string IpnsRoot string LocalDirs map[string]fs.Node - Roots map[string]*keyRoot + Roots map[string]*mfs.Root LocalLinks map[string]*Link } -func ipnsPubFunc(ipfs *core.IpfsNode, k ci.PrivKey) mfs.PubFunc { +func ipnsPubFunc(ipfs iface.CoreAPI, key iface.Key) mfs.PubFunc { return func(ctx context.Context, c cid.Cid) error { - return ipfs.Namesys.Publish(ctx, k, path.FromCid(c)) + _, err := ipfs.Name().Publish(ctx, path.IpfsPath(c), options.Name.Key(key.Name())) + return err } } -func loadRoot(ctx context.Context, rt *keyRoot, ipfs *core.IpfsNode, name string) (fs.Node, error) { - p, err := path.ParsePath("/ipns/" + name) - if err != nil { - log.Errorf("mkpath %s: %s", name, err) - return nil, err - } - - node, err := resolve.Resolve(ctx, ipfs.Namesys, ipfs.Resolver, p) +func loadRoot(ctx context.Context, ipfs iface.CoreAPI, key iface.Key) (*mfs.Root, fs.Node, error) { + node, err := ipfs.ResolveNode(ctx, key.Path()) switch err { case nil: - case namesys.ErrResolveFailed: + case iface.ErrResolveFailed: node = ft.EmptyDirNode() default: - log.Errorf("looking up %s: %s", p, err) - return nil, err + log.Errorf("looking up %s: %s", key.Path(), err) + return nil, nil, err } pbnode, ok := node.(*dag.ProtoNode) if !ok { - return nil, dag.ErrNotProtobuf + return nil, nil, dag.ErrNotProtobuf } - root, err := mfs.NewRoot(ctx, ipfs.DAG, pbnode, ipnsPubFunc(ipfs, rt.k)) + root, err := mfs.NewRoot(ctx, ipfs.Dag(), pbnode, ipnsPubFunc(ipfs, key)) if err != nil { - return nil, err + return nil, nil, err } - rt.root = root - - return &Directory{dir: root.GetDirectory()}, nil + return root, &Directory{dir: root.GetDirectory()}, nil } -type keyRoot struct { - k ci.PrivKey - alias string - root *mfs.Root -} - -func CreateRoot(ipfs *core.IpfsNode, keys map[string]ci.PrivKey, ipfspath, ipnspath string) (*Root, error) { +func CreateRoot(ctx context.Context, ipfs iface.CoreAPI, keys map[string]iface.Key, ipfspath, ipnspath string) (*Root, error) { ldirs := make(map[string]fs.Node) - roots := make(map[string]*keyRoot) + roots := make(map[string]*mfs.Root) links := make(map[string]*Link) for alias, k := range keys { - pid, err := peer.IDFromPrivateKey(k) - if err != nil { - return nil, err - } - name := pid.Pretty() - - kr := &keyRoot{k: k, alias: alias} - fsn, err := loadRoot(ipfs.Context(), kr, ipfs, name) + root, fsn, err := loadRoot(ctx, ipfs, k) if err != nil { return nil, err } - roots[name] = kr + name := k.ID().String() + + roots[name] = root ldirs[name] = fsn // set up alias symlink @@ -199,25 +178,22 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) { // other links go through ipns resolution and are symlinked into the ipfs mountpoint ipnsName := "/ipns/" + name - resolved, err := s.Ipfs.Namesys.Resolve(s.Ipfs.Context(), ipnsName) + resolved, err := s.Ipfs.Name().Resolve(ctx, ipnsName) if err != nil { log.Warnf("ipns: namesys resolve error: %s", err) return nil, fuse.ENOENT } - segments := resolved.Segments() - if segments[0] == "ipfs" { - p := path.Join(resolved.Segments()[1:]) - return &Link{s.IpfsRoot + "/" + p}, nil + if resolved.Namespace() != "ipfs" { + return nil, errors.New("invalid path from ipns record") } - log.Error("Invalid path.Path: ", resolved) - return nil, errors.New("invalid path from ipns record") + return &Link{s.IpfsRoot + "/" + strings.TrimPrefix("/ipfs/", resolved.String())}, nil } func (r *Root) Close() error { for _, mr := range r.Roots { - err := mr.root.Close() + err := mr.Close() if err != nil { return err } @@ -241,12 +217,8 @@ func (r *Root) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { var listing []fuse.Dirent for alias, k := range r.Keys { - pid, err := peer.IDFromPrivateKey(k) - if err != nil { - continue - } ent := fuse.Dirent{ - Name: pid.Pretty(), + Name: k.ID().Pretty(), Type: fuse.DT_Dir, } link := fuse.Dirent{ diff --git a/fuse/ipns/mount_unix.go b/fuse/ipns/mount_unix.go index 54e62df60..7c24e53be 100644 --- a/fuse/ipns/mount_unix.go +++ b/fuse/ipns/mount_unix.go @@ -5,11 +5,17 @@ package ipns import ( core "github.com/ipfs/go-ipfs/core" + coreapi "github.com/ipfs/go-ipfs/core/coreapi" mount "github.com/ipfs/go-ipfs/fuse/mount" ) // Mount mounts ipns at a given location, and returns a mount.Mount instance. func Mount(ipfs *core.IpfsNode, ipnsmp, ipfsmp string) (mount.Mount, error) { + coreApi, err := coreapi.NewCoreAPI(ipfs) + if err != nil { + return nil, err + } + cfg, err := ipfs.Repo.Config() if err != nil { return nil, err @@ -17,7 +23,7 @@ func Mount(ipfs *core.IpfsNode, ipnsmp, ipfsmp string) (mount.Mount, error) { allow_other := cfg.Mounts.FuseAllowOther - fsys, err := NewFileSystem(ipfs, ipfs.PrivateKey, ipfsmp, ipnsmp) + fsys, err := NewFileSystem(ipfs.Context(), coreApi, ipfsmp, ipnsmp) if err != nil { return nil, err }