Skip to content

Commit 7c603b4

Browse files
tbruyelleAlex JohnsonJerónimo Albi
authored
feat: plugin system (rebased) (ignite#2877)
* feat: plugin system A plugin is a binary that can communicate with ignite using github.com/hashicorp/go-plugin. When ignite is executed under a chain configuration, it checks if the config contains plugins. If yes the plugins are fetched, compiled and ran, which will add more commands to the existing ones. Fetching and compilation are cached under .ignite/plugins folder. A new command `ignite plugin` has been added to manage plugins and make new ones. To give plugins the ability to load the chain, the function `cmd.NewChainWithHomeFlags` is now public. * update plugin go.mod use hashicorp/go-plugin 1.4.4 to skip warning message * add plugin go.sum * git init and commit scaffolded plugins * update CL * fix dependecy issue * fix missing commit author when no default config CI doesn't have any default git config. * fix linter * Update ignite/services/plugin/template/main.go.plush Co-authored-by: Alex Johnson <alex@shmeeload.xyz> * remove plugin go.sum and use gocmd * Update ignite/services/plugin/plugin.go Co-authored-by: Jerónimo Albi <jeronimo.albi@tendermint.com> * remove commented line * fix cannot use cmd.Context() there bc it's nil * kill plugin client at the end of execution * fix comment * improve error handling in LoadPlugins * remove plugin.Name The field has no real usage, it was here to have a shorter name than the path but dealing with the path is actually less confusing. * fix readme for plugins * fix: ensure plugin instances are killed * update main so defer funcs are honored * use const exit codes * go mod tidy * fix due to plushgen removal * add PR id to CL * change CL version * fix CL Co-authored-by: Alex Johnson <alex@shmeeload.xyz> Co-authored-by: Jerónimo Albi <jeronimo.albi@tendermint.com>
1 parent f968e05 commit 7c603b4

33 files changed

+1781
-46
lines changed

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Features
66

77
- [#2955](https://github.com/ignite/cli/pull/2955/) Add `ignite network request add-account` command.
8+
- [#2877](https://github.com/ignite/cli/pull/2877) Plugin system
89
- [#2995](https://github.com/ignite/cli/pull/2995/) Add `ignite network request remove-validator` command.
910
- [#2999](https://github.com/ignite/cli/pull/2999/) Add `ignite network request remove-account` command.
1011

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ require (
3232
github.com/gookit/color v1.5.2
3333
github.com/gorilla/mux v1.8.0
3434
github.com/gorilla/rpc v1.2.0
35+
github.com/hashicorp/go-hclog v1.2.0
36+
github.com/hashicorp/go-plugin v1.4.4
3537
github.com/iancoleman/strcase v0.2.0
3638
github.com/ignite/web v0.3.10
3739
github.com/imdario/mergo v0.3.13
@@ -216,6 +218,7 @@ require (
216218
github.com/hashicorp/go-version v1.6.0 // indirect
217219
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
218220
github.com/hashicorp/hcl v1.0.0 // indirect
221+
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect
219222
github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect
220223
github.com/hexops/gotextdiff v1.0.3 // indirect
221224
github.com/improbable-eng/grpc-web v0.15.0 // indirect
@@ -263,6 +266,7 @@ require (
263266
github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect
264267
github.com/minio/highwayhash v1.0.2 // indirect
265268
github.com/mitchellh/go-homedir v1.1.0 // indirect
269+
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
266270
github.com/moby/sys/mount v0.3.1 // indirect
267271
github.com/moby/sys/mountinfo v0.6.0 // indirect
268272
github.com/moricho/tparallel v0.2.1 // indirect
@@ -276,6 +280,7 @@ require (
276280
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect
277281
github.com/nishanths/exhaustive v0.8.3 // indirect
278282
github.com/nishanths/predeclared v0.2.2 // indirect
283+
github.com/oklog/run v1.0.0 // indirect
279284
github.com/olekukonko/tablewriter v0.0.5 // indirect
280285
github.com/opencontainers/go-digest v1.0.0 // indirect
281286
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect

go.sum

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,8 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng
984984
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
985985
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
986986
github.com/hashicorp/go-getter v1.6.1 h1:NASsgP4q6tL94WH6nJxKWj8As2H/2kop/bB1d8JMyRY=
987+
github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM=
988+
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
987989
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
988990
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
989991
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
@@ -992,6 +994,8 @@ github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:
992994
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
993995
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
994996
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
997+
github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ=
998+
github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
995999
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
9961000
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
9971001
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
@@ -1015,6 +1019,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
10151019
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
10161020
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
10171021
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
1022+
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
1023+
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
10181024
github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 h1:aSVUgRRRtOrZOC1fYmY9gV0e9z/Iu+xNVSASWjsuyGU=
10191025
github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3/go.mod h1:5PC6ZNPde8bBqU/ewGZig35+UIZtw9Ytxez8/q5ZyFE=
10201026
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
@@ -1211,6 +1217,7 @@ github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwM
12111217
github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
12121218
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
12131219
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
1220+
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
12141221
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
12151222
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
12161223
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
@@ -1222,6 +1229,7 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
12221229
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
12231230
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
12241231
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
1232+
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
12251233
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
12261234
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
12271235
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
@@ -1352,6 +1360,7 @@ github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3L
13521360
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
13531361
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
13541362
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
1363+
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
13551364
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
13561365
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
13571366
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
@@ -2077,6 +2086,7 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w
20772086
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
20782087
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
20792088
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
2089+
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
20802090
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
20812091
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
20822092
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

ignite/chainconfig/chainconfig.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ var (
3737
// Config defines the latest config.
3838
type Config = v1.Config
3939

40+
// Plugin defines the latest plugin config
41+
type Plugin = v1.Plugin
42+
4043
// DefaultConfig returns a config for the latest version initialized with default values.
4144
func DefaultConfig() *Config {
4245
return v1.DefaultConfig()

ignite/chainconfig/convert_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ func TestConvertLatest(t *testing.T) {
2121
// Assert
2222
require.NoError(t, err)
2323
require.Equal(t, chainconfig.LatestVersion, cfgLatest.GetVersion())
24+
require.Equal(t, testdata.GetLatestConfig(t), cfgLatest)
2425
}
2526

2627
func TestMigrateLatest(t *testing.T) {

ignite/chainconfig/v1/config.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,30 @@ type Config struct {
2222
config.BaseConfig `yaml:",inline"`
2323

2424
Validators []Validator `yaml:"validators"`
25+
Plugins []Plugin `yaml:"plugins,omitempty"`
26+
}
27+
28+
// Plugin keeps plugin name and location.
29+
type Plugin struct {
30+
// Path holds the location of the plugin.
31+
// A path can be local, in that case it must start with a `/`.
32+
// A remote path on the other hand, is an URL to a public remote git
33+
// repository. For example:
34+
//
35+
// path: github.com/foo/bar
36+
//
37+
// It can contain a path inside that repository, if for instance the repo
38+
// contains multiple plugins, For example:
39+
//
40+
// path: github.com/foo/bar/plugin1
41+
//
42+
// It can also specify a tag or a branch, by adding a `@` and the branch/tag
43+
// name at the end of the path. For example:
44+
//
45+
// path: github.com/foo/bar/plugin1@v42
46+
Path string `yaml:"path"`
47+
// With holds arguments passed to the plugin interface
48+
With map[string]string `yaml:"with"`
2549
}
2650

2751
func (c *Config) SetDefaults() error {

ignite/chainconfig/v1/config_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,91 @@
11
package v1_test
22

33
import (
4+
"os"
45
"testing"
56

7+
"github.com/stretchr/testify/assert"
68
"github.com/stretchr/testify/require"
79

10+
"github.com/ignite/cli/ignite/chainconfig/config"
811
v1 "github.com/ignite/cli/ignite/chainconfig/v1"
912
"github.com/ignite/cli/ignite/pkg/xnet"
1013
)
1114

15+
func TestConfigDecode(t *testing.T) {
16+
assert := assert.New(t)
17+
require := require.New(t)
18+
f, err := os.Open("testdata/config2.yaml")
19+
require.NoError(err)
20+
defer f.Close()
21+
var cfg v1.Config
22+
23+
err = cfg.Decode(f)
24+
25+
require.NoError(err)
26+
expected := v1.Config{
27+
BaseConfig: config.BaseConfig{
28+
Version: 1,
29+
Build: config.Build{
30+
Binary: "evmosd",
31+
Proto: config.Proto{
32+
Path: "proto",
33+
ThirdPartyPaths: []string{"third_party/proto", "proto_vendor"},
34+
},
35+
},
36+
Accounts: []config.Account{
37+
{
38+
Name: "alice",
39+
Coins: []string{"100000000uatom", "100000000000000000000aevmos"},
40+
Mnemonic: "ozone unfold device pave lemon potato omit insect column wise cover hint narrow large provide kidney episode clay notable milk mention dizzy muffin crazy",
41+
},
42+
{
43+
Name: "bob",
44+
Coins: []string{"5000000000000aevmos"},
45+
Address: "cosmos1adn9gxjmrc3hrsdx5zpc9sj2ra7kgqkmphf8yw",
46+
},
47+
},
48+
Faucet: config.Faucet{
49+
Name: &[]string{"bob"}[0],
50+
Coins: []string{"10aevmos"},
51+
Host: "0.0.0.0:4600",
52+
Port: 4600,
53+
},
54+
Genesis: map[string]any{
55+
"app_state": map[string]any{
56+
"crisis": map[string]any{
57+
"constant_fee": map[string]any{
58+
"denom": "aevmos",
59+
},
60+
},
61+
},
62+
"chain_id": "evmosd_9000-1",
63+
},
64+
},
65+
Validators: []v1.Validator{{
66+
Name: "alice",
67+
Bonded: "100000000000000000000aevmos",
68+
Home: "$HOME/.evmosd",
69+
App: map[string]any{
70+
"evm-rpc": map[string]any{
71+
"address": "0.0.0.0:8545",
72+
"ws-address": "0.0.0.0:8546",
73+
},
74+
},
75+
}},
76+
Plugins: []v1.Plugin{
77+
{
78+
Path: "/path/to/plugin1",
79+
},
80+
{
81+
Path: "/path/to/plugin2",
82+
With: map[string]string{"foo": "bar", "bar": "baz"},
83+
},
84+
},
85+
}
86+
assert.Equal(expected, cfg)
87+
}
88+
1289
func TestConfigValidatorDefaultServers(t *testing.T) {
1390
// Arrange
1491
c := v1.Config{
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
version: 1
2+
build:
3+
binary: evmosd
4+
proto:
5+
path: proto
6+
third_party_paths:
7+
- third_party/proto
8+
- proto_vendor
9+
accounts:
10+
- name: alice
11+
coins:
12+
- 100000000uatom
13+
- 100000000000000000000aevmos
14+
mnemonic: ozone unfold device pave lemon potato omit insect column wise cover hint
15+
narrow large provide kidney episode clay notable milk mention dizzy muffin crazy
16+
- name: bob
17+
coins:
18+
- 5000000000000aevmos
19+
address: cosmos1adn9gxjmrc3hrsdx5zpc9sj2ra7kgqkmphf8yw
20+
faucet:
21+
name: bob
22+
coins:
23+
- 10aevmos
24+
host: 0.0.0.0:4600
25+
port: 4600
26+
genesis:
27+
app_state:
28+
crisis:
29+
constant_fee:
30+
denom: aevmos
31+
chain_id: evmosd_9000-1
32+
validators:
33+
- name: alice
34+
bonded: 100000000000000000000aevmos
35+
app:
36+
evm-rpc:
37+
address: 0.0.0.0:8545
38+
ws-address: 0.0.0.0:8546
39+
home: $HOME/.evmosd
40+
plugins:
41+
- name: plugin1
42+
path: /path/to/plugin1
43+
- name: plugin2
44+
path: /path/to/plugin2
45+
with:
46+
foo: bar
47+
bar: baz

ignite/cmd/chain_build.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func chainBuildHandler(cmd *cobra.Command, _ []string) error {
123123
chainOption = append(chainOption, chain.CheckDependencies())
124124
}
125125

126-
c, err := newChainWithHomeFlags(cmd, chainOption...)
126+
c, err := NewChainWithHomeFlags(cmd, chainOption...)
127127
if err != nil {
128128
return err
129129
}

ignite/cmd/chain_faucet.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func chainFaucetHandler(cmd *cobra.Command, args []string) error {
4343
chain.CollectEvents(session.EventBus()),
4444
}
4545

46-
c, err := newChainWithHomeFlags(cmd, chainOption...)
46+
c, err := NewChainWithHomeFlags(cmd, chainOption...)
4747
if err != nil {
4848
return err
4949
}

0 commit comments

Comments
 (0)