From 90522a62df502cb36ed6b9316bc847fccc660a9f Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Tue, 6 May 2025 11:01:43 +0200 Subject: [PATCH] pass provider options as json Signed-off-by: Nicolas De Loof --- docs/extension.md | 12 +++++++++--- pkg/compose/plugins.go | 23 +++++++++++++++-------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/docs/extension.md b/docs/extension.md index f4f15e52124..e6955184077 100644 --- a/docs/extension.md +++ b/docs/extension.md @@ -34,10 +34,16 @@ with subcommands `up` and `down`. ## Up lifecycle To execute an application's `up` lifecycle, Compose executes the provider's `compose up` command, passing -the project name, service name, and additional options. The `provider.options` are translated -into command line flags. For example: +the project name, service name, and additional options. The `provider.options` are marshalled into a JSON +document and set as command line stdin. + +Illustration example will execute: ```console -awesomecloud compose --project-name up --type=mysql --size=256 "database" +awesomecloud compose --project-name up "database" +``` +Command will get stdin set to JSON content: +```json +{"type": "mysql", "size": "256"} ``` > __Note:__ `project-name` _should_ be used by the provider to tag resources diff --git a/pkg/compose/plugins.go b/pkg/compose/plugins.go index fd0b48ff76c..2a4b00f978f 100644 --- a/pkg/compose/plugins.go +++ b/pkg/compose/plugins.go @@ -17,6 +17,7 @@ package compose import ( + "bytes" "context" "encoding/json" "errors" @@ -55,7 +56,10 @@ func (s *composeService) runPlugin(ctx context.Context, project *types.Project, return err } - cmd := s.setupPluginCommand(ctx, project, service, plugin, command) + cmd, err := s.setupPluginCommand(ctx, project, service, plugin, command) + if err != nil { + return err + } variables, err := s.executePlugin(ctx, cmd, command, service) if err != nil { @@ -158,19 +162,22 @@ func (s *composeService) getPluginBinaryPath(provider string) (path string, err return path, err } -func (s *composeService) setupPluginCommand(ctx context.Context, project *types.Project, service types.ServiceConfig, path, command string) *exec.Cmd { +func (s *composeService) setupPluginCommand(ctx context.Context, project *types.Project, service types.ServiceConfig, path, command string) (*exec.Cmd, error) { provider := *service.Provider - args := []string{"compose", "--project-name", project.Name, command} - for k, v := range provider.Options { - args = append(args, fmt.Sprintf("--%s=%s", k, v)) - } - args = append(args, service.Name) + args := []string{"compose", "--project-name", project.Name, command, service.Name} cmd := exec.CommandContext(ctx, path, args...) // Remove DOCKER_CLI_PLUGIN... variable so plugin can detect it run standalone cmd.Env = filter(os.Environ(), manager.ReexecEnvvar) + opts, err := json.Marshal(provider.Options) + if err != nil { + return nil, err + } + + cmd.Stdin = bytes.NewBuffer(opts) + // Use docker/cli mechanism to propagate termination signal to child process server, err := socket.NewPluginServer(nil) if err == nil { @@ -185,5 +192,5 @@ func (s *composeService) setupPluginCommand(ctx context.Context, project *types. carrier := propagation.MapCarrier{} otel.GetTextMapPropagator().Inject(ctx, &carrier) cmd.Env = append(cmd.Env, types.Mapping(carrier).Values()...) - return cmd + return cmd, nil }