diff --git a/api/exec/compose_stack.go b/api/exec/compose_stack.go index 3a2776031..86a4486c4 100644 --- a/api/exec/compose_stack.go +++ b/api/exec/compose_stack.go @@ -13,6 +13,7 @@ import ( "github.com/portainer/portainer/api/http/proxy/factory" "github.com/portainer/portainer/api/stacks/stackutils" "github.com/portainer/portainer/pkg/libstack" + "github.com/rs/zerolog/log" "github.com/pkg/errors" ) @@ -53,6 +54,8 @@ func (manager *ComposeStackManager) Up(ctx context.Context, stack *portainer.Sta return errors.Wrap(err, "failed to create env file") } + log.Debug().Msgf("Deploying stack named: %s", stack.Name) + filePaths := stackutils.GetStackFilePaths(stack, true) err = manager.deployer.Deploy(ctx, filePaths, libstack.DeployOptions{ Options: libstack.Options{ diff --git a/pkg/libstack/compose/internal/composeplugin/composeplugin.go b/pkg/libstack/compose/internal/composeplugin/composeplugin.go index ca98426c0..c1441c044 100644 --- a/pkg/libstack/compose/internal/composeplugin/composeplugin.go +++ b/pkg/libstack/compose/internal/composeplugin/composeplugin.go @@ -55,6 +55,27 @@ func (wrapper *PluginWrapper) Deploy(ctx context.Context, filePaths []string, op return err } +func (wrapper *PluginWrapper) Run(ctx context.Context, filePaths []string, serviceName string, options libstack.RunOptions) error { + + output, err := wrapper.command(newRunCommand(filePaths, serviceName, runOptions{ + remove: options.Remove, + args: options.Args, + }), options.Options) + if len(output) != 0 { + if err != nil { + return err + } + + log.Info().Msg("Stack run successful") + + log.Debug(). + Str("output", string(output)). + Msg("docker compose") + } + + return err +} + // Down stop and remove containers func (wrapper *PluginWrapper) Remove(ctx context.Context, projectName string, filePaths []string, options libstack.Options) error { output, err := wrapper.command(newDownCommand(projectName, filePaths), options) @@ -208,6 +229,24 @@ func newUpCommand(filePaths []string, options upOptions) composeCommand { return newCommand(args, filePaths) } +type runOptions struct { + remove bool + args []string +} + +func newRunCommand(filePaths []string, serviceName string, options runOptions) composeCommand { + args := []string{"run"} + + if options.remove { + args = append(args, "--rm") + } + + args = append(args, serviceName) + args = append(args, options.args...) + + return newCommand(args, filePaths) +} + func newDownCommand(projectName string, filePaths []string) composeCommand { cmd := newCommand([]string{"down", "--remove-orphans"}, filePaths) cmd.WithProjectName(projectName) diff --git a/pkg/libstack/libstack.go b/pkg/libstack/libstack.go index 294eb1c94..6ae2dc8f4 100644 --- a/pkg/libstack/libstack.go +++ b/pkg/libstack/libstack.go @@ -6,6 +6,7 @@ import ( type Deployer interface { Deploy(ctx context.Context, filePaths []string, options DeployOptions) error + Run(ctx context.Context, filePaths []string, serviceName string, options RunOptions) error // Remove stops and removes containers // // projectName or filePaths are required @@ -47,3 +48,11 @@ type DeployOptions struct { // When this is set, docker compose will output its logs to stdout AbortOnContainerExit bool `` } + +type RunOptions struct { + Options + // Automatically remove the container when it exits + Remove bool + // A list of arguments to pass to the container + Args []string +}