@cryptotaxi247 / kubo / commits / a1e654cd3

plugin: wire in plugin loader for node creation

License: MIT Signed-off-by: Kacper Łukawski <kacluk98@gmail.com>

Kacper Łukawski committed Mar 10, 2018 at 21:40 UTC a1e654cd38ce63a108b0f110e4f88222a3dd073b
6 files changed +175 -147
cmd/ipfs/main.go
+33 -15
@@ -51,6 +51,33 @@ const (
51 heapProfile = "ipfs.memprof"
52 )
53
54 +func loadPlugins(repoPath string) (*loader.PluginLoader, error) {
55 + pluginpath := filepath.Join(repoPath, "plugins")
56 +
57 + // check if repo is accessible before loading plugins
58 + var plugins *loader.PluginLoader
59 + ok, err := checkPermissions(repoPath)
60 + if err != nil {
61 + return nil, err
62 + }
63 + if !ok {
64 + pluginpath = ""
65 + }
66 + plugins, err = loader.NewPluginLoader(pluginpath)
67 + if err != nil {
68 + log.Error("error loading plugins: ", err)
69 + }
70 +
71 + if err := plugins.Initialize(); err != nil {
72 + log.Error("error initializing plugins: ", err)
73 + }
74 +
75 + if err := plugins.Run(); err != nil {
76 + log.Error("error running plugins: ", err)
77 + }
78 + return plugins, nil
79 +}
80 +
81 // main roadmap:
82 // - parse the commandline to get a cmdInvocation
83 // - if user requests help, print it and exit.
@@ -116,12 +143,18 @@ func mainRet() int {
143 }
144 log.Debugf("config path is %s", repoPath)
145
146 + plugins, err := loadPlugins(repoPath)
147 + if err != nil {
148 + return nil, err
149 + }
150 +
151 // this sets up the function that will initialize the node
152 // this is so that we can construct the node lazily.
153 return &oldcmds.Context{
154 ConfigRoot: repoPath,
155 LoadConfig: loadConfig,
156 ReqLog: &oldcmds.ReqLog{},
157 + Plugins: plugins,
158 ConstructNode: func() (n *core.IpfsNode, err error) {
159 if req == nil {
160 return nil, errors.New("constructing node without a request")
@@ -179,21 +212,6 @@ func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) {
212 if client != nil && !req.Command.External {
213 exctr = client.(cmds.Executor)
214 } else {
182 - cctx := env.(*oldcmds.Context)
183 - pluginpath := filepath.Join(cctx.ConfigRoot, "plugins")
184 -
185 - // check if repo is accessible before loading plugins
186 - ok, err := checkPermissions(cctx.ConfigRoot)
187 - if err != nil {
188 - return nil, err
189 - }
190 - if !ok {
191 - pluginpath = ""
192 - }
193 - if _, err := loader.LoadPlugins(pluginpath); err != nil {
194 - log.Error("error loading plugins: ", err)
195 - }
196 -
215 exctr = cmds.NewExecutor(req.Root)
216 }
217
commands/context.go
+4 -1
@@ -6,9 +6,10 @@ import (
6 "strings"
7 "time"
8
9 - "github.com/ipfs/go-ipfs/core"
9 + core "github.com/ipfs/go-ipfs/core"
10 coreapi "github.com/ipfs/go-ipfs/core/coreapi"
11 coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
12 + loader "github.com/ipfs/go-ipfs/plugin/loader"
13
14 "gx/ipfs/QmPdvMtgpnMuU68mWhGtzCxnddXJoV96tT9aPcNbQsqPaM/go-ipfs-cmds"
15 config "gx/ipfs/QmYyzmMnhNTtoXx5ttgUaRdHHckYnQWjPL98hgLAR2QLDD/go-ipfs-config"
@@ -23,6 +24,8 @@ type Context struct {
24 ConfigRoot string
25 ReqLog *ReqLog
26
27 + Plugins *loader.PluginLoader
28 +
29 config *config.Config
30 LoadConfig func(path string) (*config.Config, error)
31
plugin/loader/initializer.go deleted
-63
@@ -1,63 +0,0 @@
1 -package loader
2 -
3 -import (
4 - "github.com/ipfs/go-ipfs/core/coredag"
5 - "github.com/ipfs/go-ipfs/plugin"
6 - "github.com/ipfs/go-ipfs/repo/fsrepo"
7 -
8 - "gx/ipfs/QmWLWmRVSiagqP15jczsGME1qpob6HDbtbHAY2he9W5iUo/opentracing-go"
9 - ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format"
10 -)
11 -
12 -func initialize(plugins []plugin.Plugin) error {
13 - for _, p := range plugins {
14 - err := p.Init()
15 - if err != nil {
16 - return err
17 - }
18 - }
19 -
20 - return nil
21 -}
22 -
23 -func run(plugins []plugin.Plugin) error {
24 - for _, pl := range plugins {
25 - switch pl := pl.(type) {
26 - case plugin.PluginIPLD:
27 - err := runIPLDPlugin(pl)
28 - if err != nil {
29 - return err
30 - }
31 - case plugin.PluginTracer:
32 - err := runTracerPlugin(pl)
33 - if err != nil {
34 - return err
35 - }
36 - case plugin.PluginDatastore:
37 - err := fsrepo.AddDatastoreConfigHandler(pl.DatastoreTypeName(), pl.DatastoreConfigParser())
38 - if err != nil {
39 - return err
40 - }
41 - default:
42 - panic(pl)
43 - }
44 - }
45 - return nil
46 -}
47 -
48 -func runIPLDPlugin(pl plugin.PluginIPLD) error {
49 - err := pl.RegisterBlockDecoders(ipld.DefaultBlockDecoder)
50 - if err != nil {
51 - return err
52 - }
53 - return pl.RegisterInputEncParsers(coredag.DefaultInputEncParsers)
54 -}
55 -
56 -func runTracerPlugin(pl plugin.PluginTracer) error {
57 - tracer, err := pl.InitTracer()
58 - if err != nil {
59 - return err
60 - }
61 - opentracing.SetGlobalTracer(tracer)
62 - return nil
63 -}
plugin/loader/load.go deleted
-67
@@ -1,67 +0,0 @@
1 -package loader
2 -
3 -import (
4 - "fmt"
5 - "os"
6 -
7 - "github.com/ipfs/go-ipfs/plugin"
8 -
9 - logging "gx/ipfs/QmcuXC5cxs79ro2cUuHs4HQ2bkDLJUYokwL8aivcX6HW3C/go-log"
10 -)
11 -
12 -var log = logging.Logger("plugin/loader")
13 -
14 -var loadPluginsFunc = func(string) ([]plugin.Plugin, error) {
15 - return nil, nil
16 -}
17 -
18 -// LoadPlugins loads and initializes plugins.
19 -func LoadPlugins(pluginDir string) ([]plugin.Plugin, error) {
20 - plMap := make(map[string]plugin.Plugin)
21 - for _, v := range preloadPlugins {
22 - plMap[v.Name()] = v
23 - }
24 -
25 - if pluginDir != "" {
26 - newPls, err := loadDynamicPlugins(pluginDir)
27 - if err != nil {
28 - return nil, err
29 - }
30 -
31 - for _, pl := range newPls {
32 - if ppl, ok := plMap[pl.Name()]; ok {
33 - // plugin is already preloaded
34 - return nil, fmt.Errorf(
35 - "plugin: %s, is duplicated in version: %s, "+
36 - "while trying to load dynamically: %s",
37 - ppl.Name(), ppl.Version(), pl.Version())
38 - }
39 - plMap[pl.Name()] = pl
40 - }
41 - }
42 -
43 - pls := make([]plugin.Plugin, 0, len(plMap))
44 - for _, v := range plMap {
45 - pls = append(pls, v)
46 - }
47 -
48 - err := initialize(pls)
49 - if err != nil {
50 - return nil, err
51 - }
52 -
53 - err = run(pls)
54 - return nil, err
55 -}
56 -
57 -func loadDynamicPlugins(pluginDir string) ([]plugin.Plugin, error) {
58 - _, err := os.Stat(pluginDir)
59 - if os.IsNotExist(err) {
60 - return nil, nil
61 - }
62 - if err != nil {
63 - return nil, err
64 - }
65 -
66 - return loadPluginsFunc(pluginDir)
67 -}
plugin/loader/loader.go new
+125
@@ -0,0 +1,125 @@
1 +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"
8 + "os"
9 +
10 + opentracing "gx/ipfs/QmWLWmRVSiagqP15jczsGME1qpob6HDbtbHAY2he9W5iUo/opentracing-go"
11 + ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format"
12 + logging "gx/ipfs/QmcuXC5cxs79ro2cUuHs4HQ2bkDLJUYokwL8aivcX6HW3C/go-log"
13 +)
14 +
15 +var log = logging.Logger("plugin/loader")
16 +
17 +var loadPluginsFunc = func(string) ([]plugin.Plugin, error) {
18 + return nil, nil
19 +}
20 +
21 +// PluginLoader keeps track of loaded plugins
22 +type PluginLoader struct {
23 + plugins []plugin.Plugin
24 +}
25 +
26 +// NewPluginLoader creates new plugin loader
27 +func NewPluginLoader(pluginDir string) (*PluginLoader, error) {
28 + plMap := make(map[string]plugin.Plugin)
29 + for _, v := range preloadPlugins {
30 + plMap[v.Name()] = v
31 + }
32 +
33 + if pluginDir != "" {
34 + newPls, err := loadDynamicPlugins(pluginDir)
35 + if err != nil {
36 + return nil, err
37 + }
38 +
39 + for _, pl := range newPls {
40 + if ppl, ok := plMap[pl.Name()]; ok {
41 + // plugin is already preloaded
42 + return nil, fmt.Errorf(
43 + "plugin: %s, is duplicated in version: %s, "+
44 + "while trying to load dynamically: %s",
45 + ppl.Name(), ppl.Version(), pl.Version())
46 + }
47 + plMap[pl.Name()] = pl
48 + }
49 + }
50 +
51 + loader := &PluginLoader{plugins: make([]plugin.Plugin, 0, len(plMap))}
52 +
53 + for _, v := range plMap {
54 + loader.plugins = append(loader.plugins, v)
55 + }
56 +
57 + return loader, nil
58 +}
59 +
60 +func loadDynamicPlugins(pluginDir string) ([]plugin.Plugin, error) {
61 + _, err := os.Stat(pluginDir)
62 + if os.IsNotExist(err) {
63 + return nil, nil
64 + }
65 + if err != nil {
66 + return nil, err
67 + }
68 +
69 + return loadPluginsFunc(pluginDir)
70 +}
71 +
72 +//Initialize all loaded plugins
73 +func (loader *PluginLoader) Initialize() error {
74 + for _, p := range loader.plugins {
75 + err := p.Init()
76 + if err != nil {
77 + return err
78 + }
79 + }
80 +
81 + return nil
82 +}
83 +
84 +//Run the plugins
85 +func (loader *PluginLoader) Run() error {
86 + for _, pl := range loader.plugins {
87 + switch pl := pl.(type) {
88 + case plugin.PluginIPLD:
89 + err := runIPLDPlugin(pl)
90 + if err != nil {
91 + return err
92 + }
93 + case plugin.PluginTracer:
94 + err := runTracerPlugin(pl)
95 + if err != nil {
96 + return err
97 + }
98 + case plugin.PluginDatastore:
99 + err := fsrepo.AddDatastoreConfigHandler(pl.DatastoreTypeName(), pl.DatastoreConfigParser())
100 + if err != nil {
101 + return err
102 + }
103 + default:
104 + panic(pl)
105 + }
106 + }
107 + return nil
108 +}
109 +
110 +func runIPLDPlugin(pl plugin.PluginIPLD) error {
111 + err := pl.RegisterBlockDecoders(ipld.DefaultBlockDecoder)
112 + if err != nil {
113 + return err
114 + }
115 + return pl.RegisterInputEncParsers(coredag.DefaultInputEncParsers)
116 +}
117 +
118 +func runTracerPlugin(pl plugin.PluginTracer) error {
119 + tracer, err := pl.InitTracer()
120 + if err != nil {
121 + return err
122 + }
123 + opentracing.SetGlobalTracer(tracer)
124 + return nil
125 +}
repo/fsrepo/config_test.go
+13 -1
@@ -75,7 +75,19 @@ var measureConfig = []byte(`{
75 }`)
76
77 func TestDefaultDatastoreConfig(t *testing.T) {
78 - loader.LoadPlugins("")
78 + loader, err := loader.NewPluginLoader("")
79 + if err != nil {
80 + t.Fatal(err)
81 + }
82 + err = loader.Initialize()
83 + if err != nil {
84 + t.Fatal(err)
85 + }
86 +
87 + err = loader.Run()
88 + if err != nil {
89 + t.Fatal(err)
90 + }
91
92 dir, err := ioutil.TempDir("", "ipfs-datastore-config-test")
93 if err != nil {