Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[experiment] First approach to extensible shell with plugins #1416

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

marc-gr
Copy link
Contributor

@marc-gr marc-gr commented Aug 29, 2023

For some time there have been discussions about how to extend elastic-package capabilities in a way that does not require changes in elastic-package codebase (ref #479).

I have explored this approach of an interactive shell that can be extended with Go plugins, for example to extend it with adhoc commands to do bulk operations, or to add other experimental capabilities to be tested.

This first experimental approach:

1- Describes a Command interface that the plugins need to follow.
2- Adds a shell command that starts an interactive shell with autocomplete and history capabilities that will load dynamically any commands found in ~./elastic-package/shell_plugins
3- Adds some example commands under pkg/shell/plugins.

The idea behind that would be to, if moved forward, have a new ie plugins repository that could be built independently and which artifacts would be placed in the before mentioned directory.

A requirement for this would be to move from internal to ie pkg some of the most used packages that can interact with packages to allow importing them from the plugins repository.

This setup would allow for much faster experimentation of new functionalities and to have it more isolated. If at some point we want to move some of this plugins to be builtin it should be a straightforward process since they will be using the elastic-package dependencies.

How to test it:

1- Fetch this branch
2- Install elastic-package $ make install or create the shell_plugins directory if already installed mkdir ~/.elastic-package/shell_plugins
3- Build the test plugins cd pkg/shell/plugins; go build -buildmode=plugin ./...; mv plugins.so ~/.elastic-package/shell_plugins
4- In integrations, run elastic-package shell
5- Play with the provided commands

image
github.com/elastic/integrations  main ✔                                                                                                                                                                                                                                  21h21m  
▶ elastic-package shell
Loaded 4 plugins
> shell initdb
Initializing database...
Loaded 236 packages
> shell where "json_extract(manifest, '$.owner.github') = 'elastic/security-external-integrations'"
Found 146 packages
> shell write-file --path "kibana/tags.yml" --contents '- text: Security Solution\n  asset_types:\n    - dashboard\n    - search\n'
> shell changelog --next minor --type enhancement --link https://github.com/elastic/integrations/pull/9999999 --description "Add tags.yml file."
> shell 
image

@marc-gr marc-gr force-pushed the mvp-shell branch 4 times, most recently from 61a3a51 to bb6a0e7 Compare August 30, 2023 07:38
@marc-gr
Copy link
Contributor Author

marc-gr commented Aug 31, 2023

I also experimented with https://github.com/hashicorp/go-plugin to avoid some of the brittleness issues native plugins have.

Pros from RPC plugins:

1- less brittle (no need to be compiled with same versions of toolchain and dependencies)
2- more portable, since native plugins are not available in windows
3- safer, since they are safe to crash on their own without affecting the original application

Cons:

1- The usable interface for the commands is much more limited. No possibility to send any types over RCP, meaning no context.Context, pflags.Flags, etc can be used since they return or expect any parameters. We would need to define a more limited scope for what a plugin can do.

Native plugins are more convenient if we find reliable automation to solve their issues and we acknowledge the lack of WIndows support, and RPC ones are easier to maintain if we get to a good middle ground for the commands interfaces at use.

@marc-gr
Copy link
Contributor Author

marc-gr commented Sep 1, 2023

Added one more commit with an RPC implementation.

Currently it has several limitations compared with the original one:

1- Shared context.Context is limited only to the commands belonging to the same Plugin. I do not see this as an issue in the future but if so, we can come with some RPC implementation for context.Context or similar.
2- Flags are parsed on the plugin, meaning no autocomplete for flags in the shell. Again, no big deal.

After building the boilerplate creating new commands is straightforward, and overall I think this is a much more robust approach.

How to try it:

1- Fetch this branch
2- Install elastic-package $ make install or create the shell_plugins directory if already installed mkdir ~/.elastic-package/shell_plugins
3- Build the test plugins cd pkg/shell/plugins; go build ./...; mv plugins ~/.elastic-package/shell_plugins
4- In integrations, run elastic-package shell
5- Play with the provided commands

@marc-gr marc-gr force-pushed the mvp-shell branch 3 times, most recently from 0d7f732 to 9bd70c6 Compare September 4, 2023 10:21
@marc-gr
Copy link
Contributor Author

marc-gr commented Sep 4, 2023

Extracted the required internal packages to pkg and created https://github.com/elastic/ep-shell-plugins to prove the final setup.

@P1llus
Copy link
Member

P1llus commented Sep 14, 2023

This addition is great! really looking forward to see something like this getting merged at some point :)

@elasticmachine
Copy link
Collaborator

💚 Build Succeeded

History

cc @marc-gr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants