fix panic caused by accessing config after repo closed
License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>
Jeromy committed
Sep 3, 2015 at 09:28 UTC
ab0c668ab8bb4bb91fa497a185debb5d29df6a77
14 files changed
+84
-41
cmd/ipfs/daemon.go
+7
-1
@@ -204,7 +204,13 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
204
return
205
}
206
if routingOption == routingOptionSupernodeKwd {
207
- servers, err := repo.Config().SupernodeRouting.ServerIPFSAddrs()
207
+ rcfg, err := repo.Config()
208
+ if err != nil {
209
+ res.SetError(err, cmds.ErrNormal)
210
+ return
211
+ }
212
+
213
+ servers, err := rcfg.SupernodeRouting.ServerIPFSAddrs()
214
if err != nil {
215
res.SetError(err, cmds.ErrNormal)
216
repo.Close() // because ownership hasn't been transferred to the node
cmd/ipfswatch/main.go
+1
-1
@@ -192,7 +192,7 @@ func cmdCtx(node *core.IpfsNode, repoPath string) commands.Context {
192
Online: true,
193
ConfigRoot: repoPath,
194
LoadConfig: func(path string) (*config.Config, error) {
195
- return node.Repo.Config(), nil
195
+ return node.Repo.Config()
196
},
197
ConstructNode: func() (*core.IpfsNode, error) {
198
return node, nil
core/builder.go
+5
-1
@@ -135,7 +135,11 @@ func setupNode(ctx context.Context, n *IpfsNode, cfg *BuildCfg) error {
135
}
136
137
if cfg.Online {
138
- do := setupDiscoveryOption(n.Repo.Config().Discovery)
138
+ rcfg, err := n.Repo.Config()
139
+ if err != nil {
140
+ return err
141
+ }
142
+ do := setupDiscoveryOption(rcfg.Discovery)
143
if err := n.startOnlineServices(ctx, cfg.Routing, cfg.Host, do); err != nil {
144
return err
145
}
core/commands/bootstrap.go
+15
-3
@@ -72,7 +72,11 @@ in the bootstrap list).
72
return
73
}
74
defer r.Close()
75
- cfg := r.Config()
75
+ cfg, err := r.Config()
76
+ if err != nil {
77
+ res.SetError(err, cmds.ErrNormal)
78
+ return
79
+ }
80
81
deflt, _, err := req.Option("default").Bool()
82
if err != nil {
@@ -148,7 +152,11 @@ var bootstrapRemoveCmd = &cmds.Command{
152
return
153
}
154
defer r.Close()
151
- cfg := r.Config()
155
+ cfg, err := r.Config()
156
+ if err != nil {
157
+ res.SetError(err, cmds.ErrNormal)
158
+ return
159
+ }
160
161
all, _, err := req.Option("all").Bool()
162
if err != nil {
@@ -197,7 +205,11 @@ var bootstrapListCmd = &cmds.Command{
205
return
206
}
207
defer r.Close()
200
- cfg := r.Config()
208
+ cfg, err := r.Config()
209
+ if err != nil {
210
+ res.SetError(err, cmds.ErrNormal)
211
+ return
212
+ }
213
214
peers, err := cfg.BootstrapPeers()
215
if err != nil {
core/core.go
+24
-6
@@ -136,7 +136,10 @@ func (n *IpfsNode) startOnlineServices(ctx context.Context, routingOption Routin
136
n.Reporter = metrics.NewBandwidthCounter()
137
138
// get undialable addrs from config
139
- cfg := n.Repo.Config()
139
+ cfg, err := n.Repo.Config()
140
+ if err != nil {
141
+ return err
142
+ }
143
var addrfilter []*net.IPNet
144
for _, s := range cfg.Swarm.AddrFilters {
145
f, err := mamask.NewMask(s)
@@ -156,7 +159,7 @@ func (n *IpfsNode) startOnlineServices(ctx context.Context, routingOption Routin
159
}
160
161
// Ok, now we're ready to listen.
159
- if err := startListening(ctx, n.PeerHost, n.Repo.Config()); err != nil {
162
+ if err := startListening(ctx, n.PeerHost, cfg); err != nil {
163
return err
164
}
165
@@ -325,7 +328,7 @@ func (n *IpfsNode) Bootstrap(cfg BootstrapConfig) error {
328
cfg.BootstrapPeers = func() []peer.PeerInfo {
329
ps, err := n.loadBootstrapPeers()
330
if err != nil {
328
- log.Warningf("failed to parse bootstrap peers from config: %s", n.Repo.Config().Bootstrap)
331
+ log.Warning("failed to parse bootstrap peers from config")
332
return nil
333
}
334
return ps
@@ -342,7 +345,12 @@ func (n *IpfsNode) loadID() error {
345
return errors.New("identity already loaded")
346
}
347
345
- cid := n.Repo.Config().Identity.PeerID
348
+ cfg, err := n.Repo.Config()
349
+ if err != nil {
350
+ return err
351
+ }
352
+
353
+ cid := cfg.Identity.PeerID
354
if cid == "" {
355
return errors.New("Identity was not set in config (was ipfs init run?)")
356
}
@@ -363,7 +371,12 @@ func (n *IpfsNode) LoadPrivateKey() error {
371
return errors.New("private key already loaded")
372
}
373
366
- sk, err := loadPrivateKey(&n.Repo.Config().Identity, n.Identity)
374
+ cfg, err := n.Repo.Config()
375
+ if err != nil {
376
+ return err
377
+ }
378
+
379
+ sk, err := loadPrivateKey(&cfg.Identity, n.Identity)
380
if err != nil {
381
return err
382
}
@@ -375,7 +388,12 @@ func (n *IpfsNode) LoadPrivateKey() error {
388
}
389
390
func (n *IpfsNode) loadBootstrapPeers() ([]peer.PeerInfo, error) {
378
- parsed, err := n.Repo.Config().BootstrapPeers()
391
+ cfg, err := n.Repo.Config()
392
+ if err != nil {
393
+ return nil, err
394
+ }
395
+
396
+ parsed, err := cfg.BootstrapPeers()
397
if err != nil {
398
return nil, err
399
}
core/corehttp/commands.go
+5
-1
@@ -107,8 +107,12 @@ func commandsOption(cctx commands.Context, command *commands.Command) ServeOptio
107
AllowedMethods: []string{"GET", "POST", "PUT"},
108
},
109
}
110
+ rcfg, err := n.Repo.Config()
111
+ if err != nil {
112
+ return nil, err
113
+ }
114
111
- addHeadersFromConfig(cfg, n.Repo.Config())
115
+ addHeadersFromConfig(cfg, rcfg)
116
addCORSFromEnv(cfg)
117
addCORSDefaults(cfg)
118
patchCORSVars(cfg, l.Addr())
core/corehttp/gateway.go
+6
-1
@@ -30,7 +30,12 @@ func NewGateway(conf GatewayConfig) *Gateway {
30
func (g *Gateway) ServeOption() ServeOption {
31
return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) {
32
// pass user's HTTP headers
33
- g.Config.Headers = n.Repo.Config().Gateway.HTTPHeaders
33
+ cfg, err := n.Repo.Config()
34
+ if err != nil {
35
+ return nil, err
36
+ }
37
+
38
+ g.Config.Headers = cfg.Gateway.HTTPHeaders
39
40
gateway, err := newGatewayHandler(n, g.Config)
41
if err != nil {
fuse/ipns/mount_unix.go
+5
-1
@@ -11,7 +11,11 @@ import (
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
- cfg := ipfs.Repo.Config()
14
+ cfg, err := ipfs.Repo.Config()
15
+ if err != nil {
16
+ return nil, err
17
+ }
18
+
19
allow_other := cfg.Mounts.FuseAllowOther
20
21
if ipfs.IpnsFs == nil {
fuse/readonly/mount_unix.go
+4
-1
@@ -10,7 +10,10 @@ import (
10
11
// Mount mounts ipfs at a given location, and returns a mount.Mount instance.
12
func Mount(ipfs *core.IpfsNode, mountpoint string) (mount.Mount, error) {
13
- cfg := ipfs.Repo.Config()
13
+ cfg, err := ipfs.Repo.Config()
14
+ if err != nil {
15
+ return nil, err
16
+ }
17
allow_other := cfg.Mounts.FuseAllowOther
18
fsys := NewFileSystem(ipfs)
19
return mount.NewMount(ipfs.Process(), fsys, mountpoint, allow_other)
repo/fsrepo/fsrepo.go
+3
-6
@@ -445,11 +445,8 @@ func (r *FSRepo) Close() error {
445
return nil
446
}
447
448
-// Config returns the FSRepo's config. This method must not be called if the
449
-// repo is not open.
450
-//
448
// Result when not Open is undefined. The method may panic if it pleases.
452
-func (r *FSRepo) Config() *config.Config {
449
+func (r *FSRepo) Config() (*config.Config, error) {
450
451
// It is not necessary to hold the package lock since the repo is in an
452
// opened state. The package lock is _not_ meant to ensure that the repo is
@@ -460,9 +457,9 @@ func (r *FSRepo) Config() *config.Config {
457
defer packageLock.Unlock()
458
459
if r.closed {
463
- panic("repo is closed")
460
+ return nil, errors.New("cannot access config, repo not open")
461
}
465
- return r.config
462
+ return r.config, nil
463
}
464
465
// setConfigUnsynced is for private use.
repo/mock.go
+2
-2
@@ -15,8 +15,8 @@ type Mock struct {
15
D ds.ThreadSafeDatastore
16
}
17
18
-func (m *Mock) Config() *config.Config {
19
- return &m.C // FIXME threadsafety
18
+func (m *Mock) Config() (*config.Config, error) {
19
+ return &m.C, nil // FIXME threadsafety
20
}
21
22
func (m *Mock) SetConfig(updated *config.Config) error {
repo/repo.go
+1
-1
@@ -14,7 +14,7 @@ var (
14
)
15
16
type Repo interface {
17
- Config() *config.Config
17
+ Config() (*config.Config, error)
18
SetConfig(*config.Config) error
19
20
SetConfigKey(key string, value interface{}) error
test/supernode_client/main.go
+6
-2
@@ -70,7 +70,11 @@ func run() error {
70
if err != nil { // owned by node
71
return err
72
}
73
- cfg := repo.Config()
73
+ cfg, err := repo.Config()
74
+ if err != nil {
75
+ return err
76
+ }
77
+
78
cfg.Bootstrap = servers
79
if err := repo.SetConfig(cfg); err != nil {
80
return err
@@ -236,7 +240,7 @@ func cmdCtx(node *core.IpfsNode, repoPath string) commands.Context {
240
Online: true,
241
ConfigRoot: repoPath,
242
LoadConfig: func(path string) (*config.Config, error) {
239
- return node.Repo.Config(), nil
243
+ return node.Repo.Config()
244
},
245
ConstructNode: func() (*core.IpfsNode, error) {
246
return node, nil
util/sadhack/godep.go
deleted
-14
@@ -1,14 +0,0 @@
1
-package util
2
-
3
-// FIXME: we need the go-random/random utility for our sharness test wich depends on go-humanize
4
-// Godep will drop it if we dont use it in ipfs. There should be a better way to do this.
5
-import _ "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/dustin/go-humanize"
6
-
7
-// similar to the above, only used in the tests makefile
8
-import _ "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/whyrusleeping/iptb"
9
-
10
-import _ "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/chriscool/go-sleep"
11
-
12
-// imported by chegga/pb on windows, this is here so running godeps on non-windows doesnt
13
-// drop it from our vendoring
14
-import _ "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/olekukonko/ts"