Skip to content

#2090 - Introduce extensibility to Chainloop CLI #2091

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

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

gr0
Copy link
Collaborator

@gr0 gr0 commented Jun 4, 2025

This is an experimental approach to #2090 - the part of the whole solution providing the framework part.

I also created an example plugin that can be used for testing https://github.com/gr0/chainloop_example_plugin - everything that is needed is described in the readme file of the plugin.

Signed-off-by: Rafał Kuć <r.kuc@solr.pl>
@gr0 gr0 requested review from migmartri and jiparis June 4, 2025 14:58
gr0 added 3 commits June 4, 2025 21:13
Signed-off-by: Rafał Kuć <r.kuc@solr.pl>
Signed-off-by: Rafał Kuć <r.kuc@solr.pl>
Signed-off-by: Rafał Kuć <r.kuc@solr.pl>
}

// CommandInfo describes a command provided by the plugin
type CommandInfo struct {
Copy link
Member

@jiparis jiparis Jun 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we can use a Cobra struct here. That way, there's no need to parse this structure in createPluginCommand, just use them natively.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been looking into that and I may be mistaken, but it seems that we can't be sure we will fully serialize and deserialize the cobra.Command - we have pointers there and we have functions there, we could even have unexported variables potentially and that won't be serialized. But maybe I'm missing something?

Copy link
Member

@jiparis jiparis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @gr0 . This is looking great. I've left a couple of comments.

arguments["args"] = args

// Execute plugin command
result, err := plugin.Plugin.Exec(ctx, cmdInfo.Name, arguments)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some variables in root.go that get their values from some persistent flags. They should be passed as well. For example apiToken, flagDebug, flagOutputFormat, cpPanelAPI, etc.
Not sure what's the best pattern, but plugins might need to use them.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I'll review which ones we should pass and if we are missing anything that needs to be added.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now I added the token, CP and CAS API addresses. I'm not sure if there is anything that we need more. If you have anything in mind let me know.

}

// On Unix, check if executable
if runtime.GOOS != "windows" && info.Mode()&0111 == 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it need to be executable? Is this a requirement of the plugin library, I wasn't aware of it.

How did you build the test plugin? I did

go build -o ~/.config/chainloop/plugins/test-plugin main.go

in the test plugin you pasted and it doesn't load it.

 go run main.go plugin ls
WRN API contacted in insecure mode
No plugins installed

if I make it executable I get this error

go run main.go plugin ls
2025-06-05T16:15:53.855+0200 [DEBUG] plugin: starting plugin: path=/Users/miguelmartinez/.config/chainloop/plugins/test-plugin args=["/Users/miguelmartinez/.config/chainloop/plugins/test-plugin"]
2025-06-05T16:15:53.856+0200 [WARN]  plugin: plugin failed to exit gracefully
WRN API contacted in insecure mode
No plugins installed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my case I was just building an example with:

go build -o plugin-one ./cmd/

Let me create an example repository with a plugin, so I can show the whole implementation. I'll prepare something for tomorrow.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw - can you try running the compiled Chainloop binary and listing the plugins - I was testing using the locally compiled binary using goreleased. I'm wondering if that can be the case, I'll try running in a similar way you did.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm I managed to run the code even with the following command:

go run main.go plugin list

And the output was:

┌─────────┬─────────┬─────────────────────────────────────────────────┬──────────────┐
│ NAME    │ VERSION │ DESCRIPTION                                     │ COMMANDS     │
├─────────┼─────────┼─────────────────────────────────────────────────┼──────────────┤
│ example │ 3.0.0   │ GitHub rulesets plugin with JSON output support │ 1 command(s) │
└─────────┴─────────┴─────────────────────────────────────────────────┴──────────────┘
┌─────────┬─────────────────┐
│ PLUGIN  │ COMMAND         │
├─────────┼─────────────────┤
│ example │ example-hello   │
└─────────┴─────────────────┘

I'll create a simple repo with a plugin tomorrow morning, so you can test it on your machine.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@migmartri I created this repository: https://github.com/gr0/chainloop_example_plugin - have a look there, it is a very basic plugin, which in my case works:

$ ./dist/cli_darwin_arm64_v8.0/chainloop plugin list
┌──────────────────────────┬─────────┬───────────────────────────┬──────────────┐
│ NAME                     │ VERSION │ DESCRIPTION               │ COMMANDS     │
├──────────────────────────┼─────────┼───────────────────────────┼──────────────┤
│ example-chainloop-plugin │ 1.0.0   │ GitHub example CLI plugin │ 1 command(s) │
└──────────────────────────┴─────────┴───────────────────────────┴──────────────┘
┌──────────────────────────┬──────────────────────────┐
│ PLUGIN                   │ COMMAND                  │
├──────────────────────────┼──────────────────────────┤
│ example-chainloop-plugin │ example-chainloop-plugin │
$ ./dist/cli_darwin_arm64_v8.0/chainloop plugin describe --name example-chainloop-plugin
┌──────────────────────────┬─────────┬───────────────────────────┬──────────────┐
│ NAME                     │ VERSION │ DESCRIPTION               │ COMMANDS     │
├──────────────────────────┼─────────┼───────────────────────────┼──────────────┤
│ example-chainloop-plugin │ 1.0.0   │ GitHub example CLI plugin │ 1 command(s) │
└──────────────────────────┴─────────┴───────────────────────────┴──────────────┘
┌──────────────────────────┬──────────────────────────┬──────────────────┬────────────────────────────────────┐
│ PLUGIN                   │ COMMAND                  │ DESCRIPTION      │ USAGE                              │
├──────────────────────────┼──────────────────────────┼──────────────────┼────────────────────────────────────┤
│ example-chainloop-plugin │ example-chainloop-plugin │ Greet with hello │ chainloop example-chainloop-plugin │
└──────────────────────────┴──────────────────────────┴──────────────────┴────────────────────────────────────┘
┌────────┬─────────┬──────┬─────────────┬──────┬─────────┬──────────┐
│ PLUGIN │ COMMAND │ FLAG │ DESCRIPTION │ TYPE │ DEFAULT │ REQUIRED │
├────────┼─────────┼──────┼─────────────┼──────┼─────────┼──────────┤
└────────┴─────────┴──────┴─────────────┴──────┴─────────┴──────────┘

And finally:

$ ./dist/cli_darwin_arm64_v8.0/chainloop example-chainloop-plugin
Hello, World!%

gr0 added 3 commits June 9, 2025 22:45
Signed-off-by: Rafał Kuć <r.kuc@solr.pl>
Signed-off-by: Rafał Kuć <r.kuc@solr.pl>
@gr0 gr0 force-pushed the add-experimental-support-for-cli-plugins branch from 67c1add to 3d0f5da Compare June 9, 2025 20:48
Signed-off-by: Rafał Kuć <r.kuc@solr.pl>
@gr0 gr0 force-pushed the add-experimental-support-for-cli-plugins branch from 3d0f5da to 9b9ae91 Compare June 9, 2025 20:48
@gr0 gr0 marked this pull request as draft June 10, 2025 13:19
gr0 added 4 commits June 10, 2025 22:43
Signed-off-by: Rafał Kuć <r.kuc@solr.pl>
Signed-off-by: Rafał Kuć <r.kuc@solr.pl>
Signed-off-by: Rafał Kuć <r.kuc@solr.pl>
Signed-off-by: Rafał Kuć <r.kuc@solr.pl>
@gr0 gr0 force-pushed the add-experimental-support-for-cli-plugins branch from 909a8df to 2366269 Compare June 10, 2025 20:43
@gr0 gr0 marked this pull request as ready for review June 11, 2025 19:44
gr0 added 3 commits June 12, 2025 08:24
Signed-off-by: Rafał Kuć <r.kuc@solr.pl>
Signed-off-by: Rafał Kuć <r.kuc@solr.pl>
@gr0 gr0 force-pushed the add-experimental-support-for-cli-plugins branch from 897a3e6 to d11f296 Compare June 12, 2025 06:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants