@cryptotaxi247 / kubo / commits / a9f2aee3f

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 <steven@stebalien.com>

Steven Allen committed Jan 29, 2019 at 12:44 UTC a9f2aee3fc94c904e970e3b312e24f4b87e1cf5c
3 files changed +74 -3
cmd/ipfs/daemon.go
+15
@@ -17,6 +17,7 @@ import (
17 oldcmds "github.com/ipfs/go-ipfs/commands"
18 "github.com/ipfs/go-ipfs/core"
19 commands "github.com/ipfs/go-ipfs/core/commands"
20 + coreapi "github.com/ipfs/go-ipfs/core/coreapi"
21 corehttp "github.com/ipfs/go-ipfs/core/corehttp"
22 corerepo "github.com/ipfs/go-ipfs/core/corerepo"
23 nodeMount "github.com/ipfs/go-ipfs/fuse/node"
@@ -25,6 +26,7 @@ import (
26
27 ma "gx/ipfs/QmNTCey11oxhb1AxDnQBRHtdhap6Ctud872NjAYPYYXPuc/go-multiaddr"
28 cmds "gx/ipfs/QmR77mMvvh8mJBBWQmBfQBu8oD38NUN4KE9SL2gDgAQNc6/go-ipfs-cmds"
29 + goprocess "gx/ipfs/QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP/goprocess"
30 "gx/ipfs/QmTQuFQWHAWy4wMH6ZyPfGiawA5u9T8rs79FENoV8yXaoS/client_golang/prometheus"
31 mprome "gx/ipfs/QmVMcMs6duiwLzvhF6xWM3yc4GgjpNoctKFhvtBch5tpgo/go-metrics-prometheus"
32 "gx/ipfs/QmZcLBXKaFe8ND5YHPkJRAwmhJGrVsi1JqDZNyJ4nRK5Mj/go-multiaddr-net"
@@ -355,6 +357,18 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
357 return node, nil
358 }
359
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 +
372 // construct api endpoint - every time
373 apiErrc, err := serveHTTPApi(req, cctx)
374 if err != nil {
@@ -391,6 +405,7 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
405 // initialize metrics collector
406 prometheus.MustRegister(&corehttp.IpfsNodeCollector{Node: node})
407
408 + // The daemon is *finally* ready.
409 fmt.Printf("Daemon is ready\n")
410
411 // Give the user some immediate feedback when they hit C-c
plugin/daemon.go new
+14
@@ -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
@@ -2,10 +2,13 @@ package loader
2
3 import (
4 "fmt"
5 - "github.com/ipfs/go-ipfs/core/coredag"
6 - "github.com/ipfs/go-ipfs/plugin"
7 - "github.com/ipfs/go-ipfs/repo/fsrepo"
5 "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"
12
13 ipld "gx/ipfs/QmRL22E4paat7ky7vx9MLpR97JHHbFPrg3ytFQw6qp1y1s/go-ipld-format"
14 opentracing "gx/ipfs/QmWLWmRVSiagqP15jczsGME1qpob6HDbtbHAY2he9W5iUo/opentracing-go"
@@ -106,6 +109,45 @@ func (loader *PluginLoader) Inject() error {
109 return nil
110 }
111
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 +
151 func injectDatastorePlugin(pl plugin.PluginDatastore) error {
152 return fsrepo.AddDatastoreConfigHandler(pl.DatastoreTypeName(), pl.DatastoreConfigParser())
153 }