fix fuse mounting issues this time, without loading the private key on every startup
fix fuse mounting issues this time, without loading the private key on every startup
Jeromy committed
Jan 16, 2015 at 22:46 UTC
feeada0d90ee911dcadd36217c71da437f32c88d
8 files changed
+186
-11
cmd/ipfs/init.go
+29
@@ -11,6 +11,7 @@ import (
11
core "github.com/jbenet/go-ipfs/core"
12
corecmds "github.com/jbenet/go-ipfs/core/commands"
13
coreunix "github.com/jbenet/go-ipfs/core/coreunix"
14
+ ipns "github.com/jbenet/go-ipfs/fuse/ipns"
15
ci "github.com/jbenet/go-ipfs/p2p/crypto"
16
peer "github.com/jbenet/go-ipfs/p2p/peer"
17
repo "github.com/jbenet/go-ipfs/repo"
@@ -110,6 +111,11 @@ func doInit(repoRoot string, force bool, nBitsForKeypair int) (interface{}, erro
111
return nil, err
112
}
113
114
+ err = initializeIpnsKeyspace(repoRoot)
115
+ if err != nil {
116
+ return nil, err
117
+ }
118
+
119
return nil, nil
120
}
121
@@ -138,6 +144,29 @@ func addTheWelcomeFile(repoRoot string) error {
144
return nil
145
}
146
147
+func initializeIpnsKeyspace(repoRoot string) error {
148
+ ctx, cancel := context.WithCancel(context.Background())
149
+ defer cancel()
150
+
151
+ r := fsrepo.At(repoRoot)
152
+ if err := r.Open(); err != nil { // NB: repo is owned by the node
153
+ return err
154
+ }
155
+
156
+ nd, err := core.NewIPFSNode(ctx, core.Offline(r))
157
+ if err != nil {
158
+ return err
159
+ }
160
+ defer nd.Close()
161
+
162
+ err = nd.SetupOfflineRouting()
163
+ if err != nil {
164
+ return err
165
+ }
166
+
167
+ return ipns.InitializeKeyspace(nd, nd.PrivateKey)
168
+}
169
+
170
func datastoreConfig() (*config.Datastore, error) {
171
dspath, err := config.DataStorePath("")
172
if err != nil {
core/core.go
+13
-1
@@ -34,9 +34,10 @@ import (
34
config "github.com/jbenet/go-ipfs/repo/config"
35
routing "github.com/jbenet/go-ipfs/routing"
36
dht "github.com/jbenet/go-ipfs/routing/dht"
37
+ offroute "github.com/jbenet/go-ipfs/routing/offline"
38
+ eventlog "github.com/jbenet/go-ipfs/thirdparty/eventlog"
39
util "github.com/jbenet/go-ipfs/util"
40
debugerror "github.com/jbenet/go-ipfs/util/debugerror"
39
- eventlog "github.com/jbenet/go-ipfs/thirdparty/eventlog"
41
lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
42
)
43
@@ -350,6 +351,17 @@ func (n *IpfsNode) loadPrivateKey() error {
351
352
n.PrivateKey = sk
353
n.Peerstore.AddPrivKey(n.Identity, n.PrivateKey)
354
+ n.Peerstore.AddPubKey(n.Identity, sk.GetPublic())
355
+ return nil
356
+}
357
+
358
+func (n *IpfsNode) SetupOfflineRouting() error {
359
+ err := n.loadPrivateKey()
360
+ if err != nil {
361
+ return err
362
+ }
363
+
364
+ n.Routing = offroute.NewOfflineRouter(n.Repo.Datastore(), n.PrivateKey)
365
return nil
366
}
367
fuse/ipns/ipns_unix.go
+17
@@ -16,6 +16,7 @@ import (
16
core "github.com/jbenet/go-ipfs/core"
17
chunk "github.com/jbenet/go-ipfs/importer/chunk"
18
mdag "github.com/jbenet/go-ipfs/merkledag"
19
+ nsys "github.com/jbenet/go-ipfs/namesys"
20
ci "github.com/jbenet/go-ipfs/p2p/crypto"
21
ft "github.com/jbenet/go-ipfs/unixfs"
22
uio "github.com/jbenet/go-ipfs/unixfs/io"
@@ -32,6 +33,22 @@ var (
33
longRepublishTimeout = time.Millisecond * 500
34
)
35
36
+func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error {
37
+ emptyDir := &mdag.Node{Data: ft.FolderPBData()}
38
+ k, err := n.DAG.Add(emptyDir)
39
+ if err != nil {
40
+ return err
41
+ }
42
+
43
+ pub := nsys.NewRoutingPublisher(n.Routing)
44
+ err = pub.Publish(key, k.B58String())
45
+ if err != nil {
46
+ return err
47
+ }
48
+
49
+ return nil
50
+}
51
+
52
// FileSystem is the readwrite IPNS Fuse Filesystem.
53
type FileSystem struct {
54
Ipfs *core.IpfsNode
routing/dht/dht.go
+16
-1
@@ -10,6 +10,7 @@ import (
10
"sync"
11
"time"
12
13
+ ci "github.com/jbenet/go-ipfs/p2p/crypto"
14
host "github.com/jbenet/go-ipfs/p2p/host"
15
peer "github.com/jbenet/go-ipfs/p2p/peer"
16
protocol "github.com/jbenet/go-ipfs/p2p/protocol"
@@ -234,9 +235,23 @@ func (dht *IpfsDHT) getLocal(key u.Key) ([]byte, error) {
235
return rec.GetValue(), nil
236
}
237
238
+func (dht *IpfsDHT) getOwnPrivateKey() (ci.PrivKey, error) {
239
+ sk := dht.peerstore.PrivKey(dht.self)
240
+ if sk == nil {
241
+ log.Errorf("%s dht cannot get own private key!", dht.self)
242
+ return nil, fmt.Errorf("cannot get private key to sign record!")
243
+ }
244
+ return sk, nil
245
+}
246
+
247
// putLocal stores the key value pair in the datastore
248
func (dht *IpfsDHT) putLocal(key u.Key, value []byte) error {
239
- rec, err := dht.makePutRecord(key, value)
249
+ sk, err := dht.getOwnPrivateKey()
250
+ if err != nil {
251
+ return err
252
+ }
253
+
254
+ rec, err := MakePutRecord(sk, key, value)
255
if err != nil {
256
return err
257
}
routing/dht/ext_test.go
+7
-1
@@ -98,7 +98,13 @@ func TestGetFailures(t *testing.T) {
98
{
99
typ := pb.Message_GET_VALUE
100
str := "hello"
101
- rec, err := d.makePutRecord(u.Key(str), []byte("blah"))
101
+
102
+ sk, err := d.getOwnPrivateKey()
103
+ if err != nil {
104
+ t.Fatal(err)
105
+ }
106
+
107
+ rec, err := MakePutRecord(sk, u.Key(str), []byte("blah"))
108
if err != nil {
109
t.Fatal(err)
110
}
routing/dht/records.go
+7
-7
@@ -43,20 +43,20 @@ func RecordBlobForSig(r *pb.Record) []byte {
43
}
44
45
// creates and signs a dht record for the given key/value pair
46
-func (dht *IpfsDHT) makePutRecord(key u.Key, value []byte) (*pb.Record, error) {
46
+func MakePutRecord(sk ci.PrivKey, key u.Key, value []byte) (*pb.Record, error) {
47
record := new(pb.Record)
48
49
record.Key = proto.String(string(key))
50
record.Value = value
51
- record.Author = proto.String(string(dht.self))
52
- blob := RecordBlobForSig(record)
51
54
- sk := dht.peerstore.PrivKey(dht.self)
55
- if sk == nil {
56
- log.Errorf("%s dht cannot get own private key!", dht.self)
57
- return nil, fmt.Errorf("cannot get private key to sign record!")
52
+ pkh, err := sk.GetPublic().Hash()
53
+ if err != nil {
54
+ return nil, err
55
}
56
57
+ record.Author = proto.String(string(pkh))
58
+ blob := RecordBlobForSig(record)
59
+
60
sig, err := sk.Sign(blob)
61
if err != nil {
62
return nil, err
routing/dht/routing.go
+8
-1
@@ -36,7 +36,12 @@ func (dht *IpfsDHT) PutValue(ctx context.Context, key u.Key, value []byte) error
36
return err
37
}
38
39
- rec, err := dht.makePutRecord(key, value)
39
+ sk, err := dht.getOwnPrivateKey()
40
+ if err != nil {
41
+ return err
42
+ }
43
+
44
+ rec, err := MakePutRecord(sk, key, value)
45
if err != nil {
46
log.Error("Creation of record failed!")
47
return err
@@ -75,6 +80,8 @@ func (dht *IpfsDHT) GetValue(ctx context.Context, key u.Key) ([]byte, error) {
80
if err == nil {
81
log.Debug("have it locally")
82
return val, nil
83
+ } else {
84
+ log.Debug("failed to get value locally: %s", err)
85
}
86
87
// get closest peers in the routing table
routing/offline/offline.go
new
+89
@@ -0,0 +1,89 @@
1
+package offline
2
+
3
+import (
4
+ "errors"
5
+ "time"
6
+
7
+ context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
8
+ "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
9
+ ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
10
+ ci "github.com/jbenet/go-ipfs/p2p/crypto"
11
+ "github.com/jbenet/go-ipfs/p2p/peer"
12
+ routing "github.com/jbenet/go-ipfs/routing"
13
+ dht "github.com/jbenet/go-ipfs/routing/dht"
14
+ pb "github.com/jbenet/go-ipfs/routing/dht/pb"
15
+ eventlog "github.com/jbenet/go-ipfs/thirdparty/eventlog"
16
+ u "github.com/jbenet/go-ipfs/util"
17
+)
18
+
19
+var log = eventlog.Logger("offlinerouting")
20
+
21
+var ErrOffline = errors.New("routing system in offline mode")
22
+
23
+func NewOfflineRouter(dstore ds.Datastore, privkey ci.PrivKey) routing.IpfsRouting {
24
+ return &offlineRouting{
25
+ datastore: dstore,
26
+ sk: privkey,
27
+ }
28
+}
29
+
30
+type offlineRouting struct {
31
+ datastore ds.Datastore
32
+ sk ci.PrivKey
33
+}
34
+
35
+func (c *offlineRouting) PutValue(ctx context.Context, key u.Key, val []byte) error {
36
+ rec, err := dht.MakePutRecord(c.sk, key, val)
37
+ if err != nil {
38
+ return err
39
+ }
40
+ data, err := proto.Marshal(rec)
41
+ if err != nil {
42
+ return err
43
+ }
44
+
45
+ return c.datastore.Put(key.DsKey(), data)
46
+}
47
+
48
+func (c *offlineRouting) GetValue(ctx context.Context, key u.Key) ([]byte, error) {
49
+ v, err := c.datastore.Get(key.DsKey())
50
+ if err != nil {
51
+ return nil, err
52
+ }
53
+
54
+ byt, ok := v.([]byte)
55
+ if !ok {
56
+ return nil, errors.New("value stored in datastore not []byte")
57
+ }
58
+ rec := new(pb.Record)
59
+ err = proto.Unmarshal(byt, rec)
60
+ if err != nil {
61
+ return nil, err
62
+ }
63
+
64
+ return rec.GetValue(), nil
65
+}
66
+
67
+func (c *offlineRouting) FindProviders(ctx context.Context, key u.Key) ([]peer.PeerInfo, error) {
68
+ return nil, ErrOffline
69
+}
70
+
71
+func (c *offlineRouting) FindPeer(ctx context.Context, pid peer.ID) (peer.PeerInfo, error) {
72
+ return peer.PeerInfo{}, ErrOffline
73
+}
74
+
75
+func (c *offlineRouting) FindProvidersAsync(ctx context.Context, k u.Key, max int) <-chan peer.PeerInfo {
76
+ out := make(chan peer.PeerInfo)
77
+ close(out)
78
+ return out
79
+}
80
+
81
+func (c *offlineRouting) Provide(_ context.Context, key u.Key) error {
82
+ return ErrOffline
83
+}
84
+
85
+func (c *offlineRouting) Ping(ctx context.Context, p peer.ID) (time.Duration, error) {
86
+ return 0, ErrOffline
87
+}
88
+
89
+var _ routing.IpfsRouting = &offlineRouting{}