mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 10:27:46 +08:00
mount: switch over to the CoreAPI
1. Fix resolution of sharded directories. 2. Slowly kill off users of the IpfsNode object.
This commit is contained in:
parent
083ef47ce8
commit
76b1546211
@ -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)
|
||||
}
|
||||
|
||||
@ -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{
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user