Skip to content

Commit 31dfe52

Browse files
committed
plugin: add plugin type for daemon plugins
This allows users to run multiple go-ipfs "clients" in-process. License: MIT Signed-off-by: Steven Allen <[email protected]>
1 parent 0516f13 commit 31dfe52

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

cmd/ipfs/daemon.go

+15
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ import (
1717
oldcmds "github.com/ipfs/go-ipfs/commands"
1818
"github.com/ipfs/go-ipfs/core"
1919
commands "github.com/ipfs/go-ipfs/core/commands"
20+
coreapi "github.com/ipfs/go-ipfs/core/coreapi"
2021
corehttp "github.com/ipfs/go-ipfs/core/corehttp"
2122
corerepo "github.com/ipfs/go-ipfs/core/corerepo"
2223
nodeMount "github.com/ipfs/go-ipfs/fuse/node"
2324
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
2425
migrate "github.com/ipfs/go-ipfs/repo/fsrepo/migrations"
2526

2627
ma "gx/ipfs/QmNTCey11oxhb1AxDnQBRHtdhap6Ctud872NjAYPYYXPuc/go-multiaddr"
28+
goprocess "gx/ipfs/QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP/goprocess"
2729
"gx/ipfs/QmTQuFQWHAWy4wMH6ZyPfGiawA5u9T8rs79FENoV8yXaoS/client_golang/prometheus"
2830
mprome "gx/ipfs/QmVMcMs6duiwLzvhF6xWM3yc4GgjpNoctKFhvtBch5tpgo/go-metrics-prometheus"
2931
cmds "gx/ipfs/QmWGm4AbZEbnmdgVTza52MSNpEmBdFVqzmAysRbjrRyGbH/go-ipfs-cmds"
@@ -355,6 +357,18 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
355357
return node, nil
356358
}
357359

360+
// Start "core" plugins. We want to do this *before* starting the HTTP
361+
// API as the user may be relying on these plugins.
362+
api, err := coreapi.NewCoreAPI(node)
363+
if err != nil {
364+
return err
365+
}
366+
err = cctx.Plugins.Start(api)
367+
if err != nil {
368+
return err
369+
}
370+
node.Process().AddChild(goprocess.WithTeardown(cctx.Plugins.Close))
371+
358372
// construct api endpoint - every time
359373
apiErrc, err := serveHTTPApi(req, cctx)
360374
if err != nil {
@@ -391,6 +405,7 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
391405
// initialize metrics collector
392406
prometheus.MustRegister(&corehttp.IpfsNodeCollector{Node: node})
393407

408+
// The daemon is *finally* ready.
394409
fmt.Printf("Daemon is ready\n")
395410

396411
// Give the user some immediate feedback when they hit C-c

plugin/daemon.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package plugin
2+
3+
import (
4+
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
5+
)
6+
7+
// PluginDaemon is an interface for daemon plugins. These plugins will be run on
8+
// the daemon and will be given access to an implementation of the CoreAPI.
9+
type PluginDaemon interface {
10+
Plugin
11+
12+
Start(coreiface.CoreAPI) error
13+
Close() error
14+
}

plugin/loader/loader.go

+45-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ package loader
22

33
import (
44
"fmt"
5-
"github.com/ipfs/go-ipfs/core/coredag"
6-
"github.com/ipfs/go-ipfs/plugin"
7-
"github.com/ipfs/go-ipfs/repo/fsrepo"
85
"os"
6+
"strings"
7+
8+
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
9+
coredag "github.com/ipfs/go-ipfs/core/coredag"
10+
plugin "github.com/ipfs/go-ipfs/plugin"
11+
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
912

1013
ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format"
1114
opentracing "gx/ipfs/QmWLWmRVSiagqP15jczsGME1qpob6HDbtbHAY2he9W5iUo/opentracing-go"
@@ -106,6 +109,45 @@ func (loader *PluginLoader) Inject() error {
106109
return nil
107110
}
108111

112+
// Start starts all long-running plugins.
113+
func (loader *PluginLoader) Start(iface coreiface.CoreAPI) error {
114+
for i, pl := range loader.plugins {
115+
if pl, ok := pl.(plugin.PluginDaemon); ok {
116+
err := pl.Start(iface)
117+
if err != nil {
118+
closePlugins(loader.plugins[i:])
119+
return err
120+
}
121+
}
122+
}
123+
return nil
124+
}
125+
126+
// StopDaemon stops all long-running plugins.
127+
func (loader *PluginLoader) Close() error {
128+
return closePlugins(loader.plugins)
129+
}
130+
131+
func closePlugins(plugins []plugin.Plugin) error {
132+
var errs []string
133+
for _, pl := range plugins {
134+
if pl, ok := pl.(plugin.PluginDaemon); ok {
135+
err := pl.Close()
136+
if err != nil {
137+
errs = append(errs, fmt.Sprintf(
138+
"error closing plugin %s: %s",
139+
pl.Name(),
140+
err.Error(),
141+
))
142+
}
143+
}
144+
}
145+
if errs != nil {
146+
return fmt.Errorf(strings.Join(errs, "\n"))
147+
}
148+
return nil
149+
}
150+
109151
func injectDatastorePlugin(pl plugin.PluginDatastore) error {
110152
return fsrepo.AddDatastoreConfigHandler(pl.DatastoreTypeName(), pl.DatastoreConfigParser())
111153
}

0 commit comments

Comments
 (0)