feat(core): use repo.Repo in core constructor
Brian Tiger Chow committed
Jan 15, 2015 at 11:28 UTC
4b5ff960c93ae478cbf174cea175fdd5924d76ac
8 files changed
+79
-48
cmd/ipfs/init.go
+8
-4
@@ -106,7 +106,7 @@ func doInit(repoRoot string, force bool, nBitsForKeypair int) (interface{}, erro
106
if err := repo.ConfigureEventLogger(conf.Logs); err != nil {
107
return nil, err
108
}
109
- err = addTheWelcomeFile(conf)
109
+ err = addTheWelcomeFile(repoRoot)
110
if err != nil {
111
return nil, err
112
}
@@ -116,15 +116,19 @@ func doInit(repoRoot string, force bool, nBitsForKeypair int) (interface{}, erro
116
117
// addTheWelcomeFile adds a file containing the welcome message to the newly
118
// minted node. On success, it calls onSuccess
119
-func addTheWelcomeFile(conf *config.Config) error {
119
+func addTheWelcomeFile(repoRoot string) error {
120
// TODO extract this file creation operation into a function
121
ctx, cancel := context.WithCancel(context.Background())
122
- nd, err := core.NewIPFSNode(ctx, core.Offline(conf))
122
+ defer cancel()
123
+ r := fsrepo.At(repoRoot)
124
+ if err := r.Open(); err != nil { // NB: repo is owned by the node
125
+ return err
126
+ }
127
+ nd, err := core.NewIPFSNode(ctx, core.Offline(r))
128
if err != nil {
129
return err
130
}
131
defer nd.Close()
127
- defer cancel()
132
133
// Set up default file
134
reader := bytes.NewBufferString(welcomeMsg)
cmd/ipfs/main.go
+9
-5
@@ -181,15 +181,19 @@ func (i *cmdInvocation) constructNodeFunc(ctx context.Context) func() (*core.Ipf
181
return nil, errors.New("constructing node without a request context")
182
}
183
184
- cfg, err := cmdctx.GetConfig()
185
- if err != nil {
186
- return nil, fmt.Errorf("constructing node without a config: %s", err)
184
+ r := fsrepo.At(i.req.Context().ConfigRoot)
185
+ if err := r.Open(); err != nil {
186
+ return nil, err
187
}
188
189
// ok everything is good. set it on the invocation (for ownership)
190
// and return it.
191
- i.node, err = core.NewIPFSNode(ctx, core.Standard(cfg, cmdctx.Online))
192
- return i.node, err
191
+ n, err := core.NewIPFSNode(ctx, core.Standard(r, cmdctx.Online))
192
+ if err != nil {
193
+ return nil, err
194
+ }
195
+ i.node = n
196
+ return i.node, nil
197
}
198
}
199
core/core.go
+19
-26
@@ -29,11 +29,11 @@ import (
29
peer "github.com/jbenet/go-ipfs/p2p/peer"
30
path "github.com/jbenet/go-ipfs/path"
31
pin "github.com/jbenet/go-ipfs/pin"
32
+ repo "github.com/jbenet/go-ipfs/repo"
33
config "github.com/jbenet/go-ipfs/repo/config"
34
routing "github.com/jbenet/go-ipfs/routing"
35
dht "github.com/jbenet/go-ipfs/routing/dht"
36
util "github.com/jbenet/go-ipfs/util"
36
- ds2 "github.com/jbenet/go-ipfs/util/datastore2"
37
debugerror "github.com/jbenet/go-ipfs/util/debugerror"
38
eventlog "github.com/jbenet/go-ipfs/thirdparty/eventlog"
39
lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"
@@ -59,9 +59,7 @@ type IpfsNode struct {
59
// Self
60
Identity peer.ID // the local node's identity
61
62
- // TODO abstract as repo.Repo
63
- Config *config.Config // the node's configuration
64
- Datastore ds2.ThreadSafeDatastoreCloser // the local datastore
62
+ Repo repo.Repo
63
64
// Local node
65
Pinning pin.Pinner // the pinning manager
@@ -120,24 +118,24 @@ func NewIPFSNode(ctx context.Context, option ConfigOption) (*IpfsNode, error) {
118
node.Peerstore = peer.NewPeerstore()
119
}
120
node.DAG = merkledag.NewDAGService(node.Blocks)
123
- node.Pinning, err = pin.LoadPinner(node.Datastore, node.DAG)
121
+ node.Pinning, err = pin.LoadPinner(node.Repo.Datastore(), node.DAG)
122
if err != nil {
125
- node.Pinning = pin.NewPinner(node.Datastore, node.DAG)
123
+ node.Pinning = pin.NewPinner(node.Repo.Datastore(), node.DAG)
124
}
125
node.Resolver = &path.Resolver{DAG: node.DAG}
126
return node, nil
127
}
128
131
-func Offline(cfg *config.Config) ConfigOption {
132
- return Standard(cfg, false)
129
+func Offline(r repo.Repo) ConfigOption {
130
+ return Standard(r, false)
131
}
132
135
-func Online(cfg *config.Config) ConfigOption {
136
- return Standard(cfg, true)
133
+func Online(r repo.Repo) ConfigOption {
134
+ return Standard(r, true)
135
}
136
137
// DEPRECATED: use Online, Offline functions
140
-func Standard(cfg *config.Config, online bool) ConfigOption {
138
+func Standard(r repo.Repo, online bool) ConfigOption {
139
return func(ctx context.Context) (n *IpfsNode, err error) {
140
141
success := false // flip to true after all sub-system inits succeed
@@ -147,8 +145,8 @@ func Standard(cfg *config.Config, online bool) ConfigOption {
145
}
146
}()
147
150
- if cfg == nil {
151
- return nil, debugerror.Errorf("configuration required")
148
+ if r == nil {
149
+ return nil, debugerror.Errorf("repo required")
150
}
151
n = &IpfsNode{
152
mode: func() mode {
@@ -157,7 +155,7 @@ func Standard(cfg *config.Config, online bool) ConfigOption {
155
}
156
return offlineMode
157
}(),
160
- Config: cfg,
158
+ Repo: r,
159
}
160
161
n.ContextGroup = ctxgroup.WithContextAndTeardown(ctx, n.teardown)
@@ -166,17 +164,12 @@ func Standard(cfg *config.Config, online bool) ConfigOption {
164
// setup Peerstore
165
n.Peerstore = peer.NewPeerstore()
166
169
- // setup datastore.
170
- if n.Datastore, err = makeDatastore(cfg.Datastore); err != nil {
171
- return nil, debugerror.Wrap(err)
172
- }
173
-
167
// setup local peer ID (private key is loaded in online setup)
168
if err := n.loadID(); err != nil {
169
return nil, err
170
}
171
179
- n.Blockstore, err = bstore.WriteCached(bstore.NewBlockstore(n.Datastore), kSizeBlockstoreWriteCache)
172
+ n.Blockstore, err = bstore.WriteCached(bstore.NewBlockstore(n.Repo.Datastore()), kSizeBlockstoreWriteCache)
173
if err != nil {
174
return nil, debugerror.Wrap(err)
175
}
@@ -207,7 +200,7 @@ func (n *IpfsNode) StartOnlineServices() error {
200
return err
201
}
202
210
- peerhost, err := constructPeerHost(ctx, n.ContextGroup, n.Config, n.Identity, n.Peerstore)
203
+ peerhost, err := constructPeerHost(ctx, n.ContextGroup, n.Repo.Config(), n.Identity, n.Peerstore)
204
if err != nil {
205
return debugerror.Wrap(err)
206
}
@@ -217,7 +210,7 @@ func (n *IpfsNode) StartOnlineServices() error {
210
n.Diagnostics = diag.NewDiagnostics(n.Identity, n.PeerHost)
211
212
// setup routing service
220
- dhtRouting, err := constructDHTRouting(ctx, n.ContextGroup, n.PeerHost, n.Datastore)
213
+ dhtRouting, err := constructDHTRouting(ctx, n.ContextGroup, n.PeerHost, n.Repo.Datastore())
214
if err != nil {
215
return debugerror.Wrap(err)
216
}
@@ -240,7 +233,7 @@ func (n *IpfsNode) StartOnlineServices() error {
233
// manage the wiring. In that scenario, this dangling function is a bit
234
// awkward.
235
var bootstrapPeers []peer.PeerInfo
243
- for _, bootstrap := range n.Config.Bootstrap {
236
+ for _, bootstrap := range n.Repo.Config().Bootstrap {
237
p, err := toPeer(bootstrap)
238
if err != nil {
239
log.Event(ctx, "bootstrapError", n.Identity, lgbl.Error(err))
@@ -258,7 +251,7 @@ func (n *IpfsNode) StartOnlineServices() error {
251
}
252
253
func (n *IpfsNode) teardown() error {
261
- if err := n.Datastore.Close(); err != nil {
254
+ if err := n.Repo.Close(); err != nil {
255
return err
256
}
257
return nil
@@ -293,7 +286,7 @@ func (n *IpfsNode) loadID() error {
286
return debugerror.New("identity already loaded")
287
}
288
296
- cid := n.Config.Identity.PeerID
289
+ cid := n.Repo.Config().Identity.PeerID
290
if cid == "" {
291
return debugerror.New("Identity was not set in config (was ipfs init run?)")
292
}
@@ -314,7 +307,7 @@ func (n *IpfsNode) loadPrivateKey() error {
307
return debugerror.New("private key already loaded")
308
}
309
317
- sk, err := loadPrivateKey(&n.Config.Identity, n.Identity)
310
+ sk, err := loadPrivateKey(&n.Repo.Config().Identity, n.Identity)
311
if err != nil {
312
return err
313
}
core/core_test.go
+12
-2
@@ -4,7 +4,9 @@ import (
4
"testing"
5
6
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
7
+ "github.com/jbenet/go-ipfs/repo"
8
config "github.com/jbenet/go-ipfs/repo/config"
9
+ "github.com/jbenet/go-ipfs/util/testutil"
10
)
11
12
func TestInitialization(t *testing.T) {
@@ -42,14 +44,22 @@ func TestInitialization(t *testing.T) {
44
}
45
46
for i, c := range good {
45
- n, err := NewIPFSNode(ctx, Standard(c, false))
47
+ r := &repo.Mock{
48
+ C: *c,
49
+ D: testutil.ThreadSafeCloserMapDatastore(),
50
+ }
51
+ n, err := NewIPFSNode(ctx, Standard(r, false))
52
if n == nil || err != nil {
53
t.Error("Should have constructed.", i, err)
54
}
55
}
56
57
for i, c := range bad {
52
- n, err := NewIPFSNode(ctx, Standard(c, false))
58
+ r := &repo.Mock{
59
+ C: *c,
60
+ D: testutil.ThreadSafeCloserMapDatastore(),
61
+ }
62
+ n, err := NewIPFSNode(ctx, Standard(r, false))
63
if n != nil || err == nil {
64
t.Error("Should have failed to construct.", i)
65
}
core/mock.go
+7
-5
@@ -2,8 +2,7 @@ package core
2
3
import (
4
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
5
-
6
- ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
5
+ "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
6
syncds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/sync"
7
"github.com/jbenet/go-ipfs/blocks/blockstore"
8
blockservice "github.com/jbenet/go-ipfs/blockservice"
@@ -13,6 +12,7 @@ import (
12
mocknet "github.com/jbenet/go-ipfs/p2p/net/mock"
13
peer "github.com/jbenet/go-ipfs/p2p/peer"
14
path "github.com/jbenet/go-ipfs/path"
15
+ "github.com/jbenet/go-ipfs/repo"
16
mockrouting "github.com/jbenet/go-ipfs/routing/mock"
17
ds2 "github.com/jbenet/go-ipfs/util/datastore2"
18
testutil "github.com/jbenet/go-ipfs/util/testutil"
@@ -46,14 +46,16 @@ func NewMockNode() (*IpfsNode, error) {
46
}
47
48
// Temp Datastore
49
- dstore := ds.NewMapDatastore()
50
- nd.Datastore = ds2.CloserWrap(syncds.MutexWrap(dstore))
49
+ nd.Repo = &repo.Mock{
50
+ // TODO C: conf,
51
+ D: ds2.CloserWrap(syncds.MutexWrap(datastore.NewMapDatastore())),
52
+ }
53
54
// Routing
55
nd.Routing = mockrouting.NewServer().Client(ident)
56
57
// Bitswap
56
- bstore := blockstore.NewBlockstore(nd.Datastore)
58
+ bstore := blockstore.NewBlockstore(nd.Repo.Datastore())
59
bserv, err := blockservice.New(bstore, offline.Exchange(bstore))
60
if err != nil {
61
return nil, err
repo/repo.go
+4
@@ -1,6 +1,8 @@
1
package repo
2
3
import (
4
+ "io"
5
+
6
datastore "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
7
config "github.com/jbenet/go-ipfs/repo/config"
8
util "github.com/jbenet/go-ipfs/util"
@@ -14,6 +16,8 @@ type Repo interface {
16
GetConfigKey(key string) (interface{}, error)
17
18
Datastore() datastore.ThreadSafeDatastore
19
+
20
+ io.Closer
21
}
22
23
// IsInitialized returns true if the path is home to an initialized IPFS
test/epictest/core.go
+9
-6
@@ -2,19 +2,19 @@ package epictest
2
3
import (
4
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
5
- datastore "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
6
- sync "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/sync"
7
-
5
+ "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
6
+ syncds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/sync"
7
blockstore "github.com/jbenet/go-ipfs/blocks/blockstore"
8
core "github.com/jbenet/go-ipfs/core"
9
bitswap "github.com/jbenet/go-ipfs/exchange/bitswap"
10
bsnet "github.com/jbenet/go-ipfs/exchange/bitswap/network"
11
host "github.com/jbenet/go-ipfs/p2p/host"
12
peer "github.com/jbenet/go-ipfs/p2p/peer"
13
+ "github.com/jbenet/go-ipfs/repo"
14
dht "github.com/jbenet/go-ipfs/routing/dht"
15
delay "github.com/jbenet/go-ipfs/thirdparty/delay"
16
eventlog "github.com/jbenet/go-ipfs/thirdparty/eventlog"
17
- "github.com/jbenet/go-ipfs/util/datastore2"
17
+ ds2 "github.com/jbenet/go-ipfs/util/datastore2"
18
testutil "github.com/jbenet/go-ipfs/util/testutil"
19
)
20
@@ -25,7 +25,10 @@ func MocknetTestRepo(p peer.ID, h host.Host, conf testutil.LatencyConfig) core.C
25
const kWriteCacheElems = 100
26
const alwaysSendToPeer = true
27
dsDelay := delay.Fixed(conf.BlockstoreLatency)
28
- ds := datastore2.CloserWrap(sync.MutexWrap(datastore2.WithDelay(datastore.NewMapDatastore(), dsDelay)))
28
+ r := &repo.Mock{
29
+ D: ds2.CloserWrap(syncds.MutexWrap(ds2.WithDelay(datastore.NewMapDatastore(), dsDelay))),
30
+ }
31
+ ds := r.Datastore()
32
33
log.Debugf("MocknetTestRepo: %s %s %s", p, h.ID(), h)
34
dhtt := dht.NewDHT(ctx, h, ds)
@@ -39,7 +42,7 @@ func MocknetTestRepo(p peer.ID, h host.Host, conf testutil.LatencyConfig) core.C
42
Peerstore: h.Peerstore(),
43
Blockstore: bstore,
44
Exchange: exch,
42
- Datastore: ds,
45
+ Repo: r,
46
PeerHost: h,
47
Routing: dhtt,
48
Identity: p,
util/testutil/datastore.go
new
+11
@@ -0,0 +1,11 @@
1
+package testutil
2
+
3
+import (
4
+ "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
5
+ syncds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/sync"
6
+ ds2 "github.com/jbenet/go-ipfs/util/datastore2"
7
+)
8
+
9
+func ThreadSafeCloserMapDatastore() ds2.ThreadSafeDatastoreCloser {
10
+ return ds2.CloserWrap(syncds.MutexWrap(datastore.NewMapDatastore()))
11
+}