mount: switch over to the CoreAPI
1. Fix resolution of sharded directories. 2. Slowly kill off users of the IpfsNode object.
Steven Allen committed
Aug 21, 2019 at 19:17 UTC
76b1546211ad618cf0d2740380d41dab84750cc0
3 files changed
+50
-66
fuse/ipns/ipns_test.go
+7
-1
@@ -16,6 +16,7 @@ import (
16
"bazil.org/fuse"
17
18
core "github.com/ipfs/go-ipfs/core"
19
+ coreapi "github.com/ipfs/go-ipfs/core/coreapi"
20
21
fstest "bazil.org/fuse/fs/fstestutil"
22
racedet "github.com/ipfs/go-detect-race"
@@ -115,7 +116,12 @@ func setupIpnsTest(t *testing.T, node *core.IpfsNode) (*core.IpfsNode, *mountWra
116
}
117
}
118
118
- fs, err := NewFileSystem(node, node.PrivateKey, "", "")
119
+ coreApi, err := coreapi.NewCoreAPI(node)
120
+ if err != nil {
121
+ t.Fatal(err)
122
+ }
123
+
124
+ fs, err := NewFileSystem(node.Context(), coreApi, "", "")
125
if err != nil {
126
t.Fatal(err)
127
}
fuse/ipns/ipns_unix.go
+36
-64
@@ -10,22 +10,19 @@ import (
10
"fmt"
11
"io"
12
"os"
13
-
14
- core "github.com/ipfs/go-ipfs/core"
15
- namesys "github.com/ipfs/go-ipfs/namesys"
16
- resolve "github.com/ipfs/go-ipfs/namesys/resolve"
13
+ "strings"
14
15
dag "github.com/ipfs/go-merkledag"
19
- path "github.com/ipfs/go-path"
16
ft "github.com/ipfs/go-unixfs"
17
+ path "github.com/ipfs/interface-go-ipfs-core/path"
18
19
fuse "bazil.org/fuse"
20
fs "bazil.org/fuse/fs"
21
cid "github.com/ipfs/go-cid"
22
logging "github.com/ipfs/go-log"
23
mfs "github.com/ipfs/go-mfs"
27
- ci "github.com/libp2p/go-libp2p-core/crypto"
28
- peer "github.com/libp2p/go-libp2p-core/peer"
24
+ iface "github.com/ipfs/interface-go-ipfs-core"
25
+ options "github.com/ipfs/interface-go-ipfs-core/options"
26
)
27
28
func init() {
@@ -40,17 +37,17 @@ var log = logging.Logger("fuse/ipns")
37
38
// FileSystem is the readwrite IPNS Fuse Filesystem.
39
type FileSystem struct {
43
- Ipfs *core.IpfsNode
40
+ Ipfs iface.CoreAPI
41
RootNode *Root
42
}
43
44
// NewFileSystem constructs new fs using given core.IpfsNode instance.
48
-func NewFileSystem(ipfs *core.IpfsNode, sk ci.PrivKey, ipfspath, ipnspath string) (*FileSystem, error) {
49
-
50
- kmap := map[string]ci.PrivKey{
51
- "local": sk,
45
+func NewFileSystem(ctx context.Context, ipfs iface.CoreAPI, ipfspath, ipnspath string) (*FileSystem, error) {
46
+ key, err := ipfs.Key().Self(ctx)
47
+ if err != nil {
48
+ return nil, err
49
}
53
- root, err := CreateRoot(ipfs, kmap, ipfspath, ipnspath)
50
+ root, err := CreateRoot(ctx, ipfs, map[string]iface.Key{"local": key}, ipfspath, ipnspath)
51
if err != nil {
52
return nil, err
53
}
@@ -73,80 +70,62 @@ func (f *FileSystem) Destroy() {
70
71
// Root is the root object of the filesystem tree.
72
type Root struct {
76
- Ipfs *core.IpfsNode
77
- Keys map[string]ci.PrivKey
73
+ Ipfs iface.CoreAPI
74
+ Keys map[string]iface.Key
75
76
// Used for symlinking into ipfs
77
IpfsRoot string
78
IpnsRoot string
79
LocalDirs map[string]fs.Node
83
- Roots map[string]*keyRoot
80
+ Roots map[string]*mfs.Root
81
82
LocalLinks map[string]*Link
83
}
84
88
-func ipnsPubFunc(ipfs *core.IpfsNode, k ci.PrivKey) mfs.PubFunc {
85
+func ipnsPubFunc(ipfs iface.CoreAPI, key iface.Key) mfs.PubFunc {
86
return func(ctx context.Context, c cid.Cid) error {
90
- return ipfs.Namesys.Publish(ctx, k, path.FromCid(c))
87
+ _, err := ipfs.Name().Publish(ctx, path.IpfsPath(c), options.Name.Key(key.Name()))
88
+ return err
89
}
90
}
91
94
-func loadRoot(ctx context.Context, rt *keyRoot, ipfs *core.IpfsNode, name string) (fs.Node, error) {
95
- p, err := path.ParsePath("/ipns/" + name)
96
- if err != nil {
97
- log.Errorf("mkpath %s: %s", name, err)
98
- return nil, err
99
- }
100
-
101
- node, err := resolve.Resolve(ctx, ipfs.Namesys, ipfs.Resolver, p)
92
+func loadRoot(ctx context.Context, ipfs iface.CoreAPI, key iface.Key) (*mfs.Root, fs.Node, error) {
93
+ node, err := ipfs.ResolveNode(ctx, key.Path())
94
switch err {
95
case nil:
104
- case namesys.ErrResolveFailed:
96
+ case iface.ErrResolveFailed:
97
node = ft.EmptyDirNode()
98
default:
107
- log.Errorf("looking up %s: %s", p, err)
108
- return nil, err
99
+ log.Errorf("looking up %s: %s", key.Path(), err)
100
+ return nil, nil, err
101
}
102
103
pbnode, ok := node.(*dag.ProtoNode)
104
if !ok {
113
- return nil, dag.ErrNotProtobuf
105
+ return nil, nil, dag.ErrNotProtobuf
106
}
107
116
- root, err := mfs.NewRoot(ctx, ipfs.DAG, pbnode, ipnsPubFunc(ipfs, rt.k))
108
+ root, err := mfs.NewRoot(ctx, ipfs.Dag(), pbnode, ipnsPubFunc(ipfs, key))
109
if err != nil {
118
- return nil, err
110
+ return nil, nil, err
111
}
112
121
- rt.root = root
122
-
123
- return &Directory{dir: root.GetDirectory()}, nil
124
-}
125
-
126
-type keyRoot struct {
127
- k ci.PrivKey
128
- alias string
129
- root *mfs.Root
113
+ return root, &Directory{dir: root.GetDirectory()}, nil
114
}
115
132
-func CreateRoot(ipfs *core.IpfsNode, keys map[string]ci.PrivKey, ipfspath, ipnspath string) (*Root, error) {
116
+func CreateRoot(ctx context.Context, ipfs iface.CoreAPI, keys map[string]iface.Key, ipfspath, ipnspath string) (*Root, error) {
117
ldirs := make(map[string]fs.Node)
134
- roots := make(map[string]*keyRoot)
118
+ roots := make(map[string]*mfs.Root)
119
links := make(map[string]*Link)
120
for alias, k := range keys {
137
- pid, err := peer.IDFromPrivateKey(k)
121
+ root, fsn, err := loadRoot(ctx, ipfs, k)
122
if err != nil {
123
return nil, err
124
}
141
- name := pid.Pretty()
125
143
- kr := &keyRoot{k: k, alias: alias}
144
- fsn, err := loadRoot(ipfs.Context(), kr, ipfs, name)
145
- if err != nil {
146
- return nil, err
147
- }
126
+ name := k.ID().String()
127
149
- roots[name] = kr
128
+ roots[name] = root
129
ldirs[name] = fsn
130
131
// set up alias symlink
@@ -199,25 +178,22 @@ func (s *Root) Lookup(ctx context.Context, name string) (fs.Node, error) {
178
179
// other links go through ipns resolution and are symlinked into the ipfs mountpoint
180
ipnsName := "/ipns/" + name
202
- resolved, err := s.Ipfs.Namesys.Resolve(s.Ipfs.Context(), ipnsName)
181
+ resolved, err := s.Ipfs.Name().Resolve(ctx, ipnsName)
182
if err != nil {
183
log.Warnf("ipns: namesys resolve error: %s", err)
184
return nil, fuse.ENOENT
185
}
186
208
- segments := resolved.Segments()
209
- if segments[0] == "ipfs" {
210
- p := path.Join(resolved.Segments()[1:])
211
- return &Link{s.IpfsRoot + "/" + p}, nil
187
+ if resolved.Namespace() != "ipfs" {
188
+ return nil, errors.New("invalid path from ipns record")
189
}
190
214
- log.Error("Invalid path.Path: ", resolved)
215
- return nil, errors.New("invalid path from ipns record")
191
+ return &Link{s.IpfsRoot + "/" + strings.TrimPrefix("/ipfs/", resolved.String())}, nil
192
}
193
194
func (r *Root) Close() error {
195
for _, mr := range r.Roots {
220
- err := mr.root.Close()
196
+ err := mr.Close()
197
if err != nil {
198
return err
199
}
@@ -241,12 +217,8 @@ func (r *Root) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
217
218
var listing []fuse.Dirent
219
for alias, k := range r.Keys {
244
- pid, err := peer.IDFromPrivateKey(k)
245
- if err != nil {
246
- continue
247
- }
220
ent := fuse.Dirent{
249
- Name: pid.Pretty(),
221
+ Name: k.ID().Pretty(),
222
Type: fuse.DT_Dir,
223
}
224
link := fuse.Dirent{
fuse/ipns/mount_unix.go
+7
-1
@@ -5,11 +5,17 @@ package ipns
5
6
import (
7
core "github.com/ipfs/go-ipfs/core"
8
+ coreapi "github.com/ipfs/go-ipfs/core/coreapi"
9
mount "github.com/ipfs/go-ipfs/fuse/mount"
10
)
11
12
// Mount mounts ipns at a given location, and returns a mount.Mount instance.
13
func Mount(ipfs *core.IpfsNode, ipnsmp, ipfsmp string) (mount.Mount, error) {
14
+ coreApi, err := coreapi.NewCoreAPI(ipfs)
15
+ if err != nil {
16
+ return nil, err
17
+ }
18
+
19
cfg, err := ipfs.Repo.Config()
20
if err != nil {
21
return nil, err
@@ -17,7 +23,7 @@ func Mount(ipfs *core.IpfsNode, ipnsmp, ipfsmp string) (mount.Mount, error) {
23
24
allow_other := cfg.Mounts.FuseAllowOther
25
20
- fsys, err := NewFileSystem(ipfs, ipfs.PrivateKey, ipfsmp, ipnsmp)
26
+ fsys, err := NewFileSystem(ipfs.Context(), coreApi, ipfsmp, ipnsmp)
27
if err != nil {
28
return nil, err
29
}