diff --git a/api/http/handler/stacks/stack_start.go b/api/http/handler/stacks/stack_start.go index a5d45bb95..95a92f6b3 100644 --- a/api/http/handler/stacks/stack_start.go +++ b/api/http/handler/stacks/stack_start.go @@ -141,12 +141,24 @@ func (handler *Handler) startStack( endpoint *portainer.Endpoint, securityContext *security.RestrictedRequestContext, ) error { + user, err := handler.DataStore.User().Read(securityContext.UserID) + if err != nil { + return fmt.Errorf("unable to load user information from the database: %w", err) + } + + registries, err := handler.DataStore.Registry().ReadAll() + if err != nil { + return fmt.Errorf("unable to retrieve registries from the database: %w", err) + } + + filteredRegistries := security.FilterRegistries(registries, user, securityContext.UserMemberships, endpoint.ID) + switch stack.Type { case portainer.DockerComposeStack: stack.Name = handler.ComposeStackManager.NormalizeStackName(stack.Name) if stackutils.IsGitStack(stack) { - return handler.StackDeployer.StartRemoteComposeStack(stack, endpoint) + return handler.StackDeployer.StartRemoteComposeStack(stack, endpoint, filteredRegistries) } return handler.ComposeStackManager.Up(context.TODO(), stack, endpoint, false) @@ -154,21 +166,9 @@ func (handler *Handler) startStack( stack.Name = handler.SwarmStackManager.NormalizeStackName(stack.Name) if stackutils.IsGitStack(stack) { - return handler.StackDeployer.StartRemoteSwarmStack(stack, endpoint) + return handler.StackDeployer.StartRemoteSwarmStack(stack, endpoint, filteredRegistries) } - user, err := handler.DataStore.User().Read(securityContext.UserID) - if err != nil { - return fmt.Errorf("unable to load user information from the database: %w", err) - } - - registries, err := handler.DataStore.Registry().ReadAll() - if err != nil { - return fmt.Errorf("unable to retrieve registries from the database: %w", err) - } - - filteredRegistries := security.FilterRegistries(registries, user, securityContext.UserMemberships, endpoint.ID) - return handler.StackDeployer.DeploySwarmStack(stack, endpoint, filteredRegistries, true, true) } diff --git a/api/stacks/deployments/compose_unpacker_cmd_builder.go b/api/stacks/deployments/compose_unpacker_cmd_builder.go index dbf84b13b..20bf56d43 100644 --- a/api/stacks/deployments/compose_unpacker_cmd_builder.go +++ b/api/stacks/deployments/compose_unpacker_cmd_builder.go @@ -100,6 +100,7 @@ func buildComposeStartCmd(stack *portainer.Stack, opts unpackerCmdBuilderOptions cmd = appendSkipTLSVerifyIfNeeded(cmd, stack) cmd = append(cmd, "-k") cmd = append(cmd, env...) + cmd = append(cmd, registries...) cmd = append(cmd, stack.GitConfig.URL) cmd = append(cmd, stack.GitConfig.ReferenceName) cmd = append(cmd, stack.Name) @@ -162,6 +163,7 @@ func buildSwarmStartCmd(stack *portainer.Stack, opts unpackerCmdBuilderOptions, cmd = append(cmd, UnpackerCmdSwarmDeploy, "-f", "-r", "-k") cmd = appendSkipTLSVerifyIfNeeded(cmd, stack) cmd = append(cmd, getEnv(stack.Env)...) + cmd = append(cmd, registries...) cmd = append(cmd, stack.GitConfig.URL) cmd = append(cmd, stack.GitConfig.ReferenceName) cmd = append(cmd, stack.Name) diff --git a/api/stacks/deployments/deploy_test.go b/api/stacks/deployments/deploy_test.go index 3cf9c8b19..bdda029cc 100644 --- a/api/stacks/deployments/deploy_test.go +++ b/api/stacks/deployments/deploy_test.go @@ -35,7 +35,7 @@ func (s *noopDeployer) DeployRemoteComposeStack(stack *portainer.Stack, endpoint func (s *noopDeployer) UndeployRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error { return nil } -func (s *noopDeployer) StartRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error { +func (s *noopDeployer) StartRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry) error { return nil } func (s *noopDeployer) StopRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error { @@ -47,7 +47,7 @@ func (s *noopDeployer) DeployRemoteSwarmStack(stack *portainer.Stack, endpoint * func (s *noopDeployer) UndeployRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error { return nil } -func (s *noopDeployer) StartRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error { +func (s *noopDeployer) StartRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry) error { return nil } func (s *noopDeployer) StopRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error { diff --git a/api/stacks/deployments/deployer_remote.go b/api/stacks/deployments/deployer_remote.go index 0a3c81bd3..8b1ab4c5d 100644 --- a/api/stacks/deployments/deployer_remote.go +++ b/api/stacks/deployments/deployer_remote.go @@ -33,22 +33,29 @@ type RemoteStackDeployer interface { // compose DeployRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, forcePullImage bool, forceRecreate bool) error UndeployRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error - StartRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error + StartRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry) error StopRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error // swarm DeployRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune bool, pullImage bool) error UndeployRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error - StartRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error + StartRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry) error StopRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error } // Deploy a compose stack on remote environment using a https://github.com/portainer/compose-unpacker container -func (d *stackDeployer) DeployRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, forcePullImage bool, forceRecreate bool) error { +func (d *stackDeployer) DeployRemoteComposeStack( + stack *portainer.Stack, + endpoint *portainer.Endpoint, + registries []portainer.Registry, + forcePullImage bool, + forceRecreate bool, +) error { d.lock.Lock() defer d.lock.Unlock() d.swarmStackManager.Login(registries, endpoint) defer d.swarmStackManager.Logout(endpoint) + // --force-recreate doesn't pull updated images if forcePullImage { err := d.composeStackManager.Pull(context.TODO(), stack, endpoint) @@ -57,9 +64,14 @@ func (d *stackDeployer) DeployRemoteComposeStack(stack *portainer.Stack, endpoin } } - return d.remoteStack(stack, endpoint, OperationDeploy, unpackerCmdBuilderOptions{ - registries: registries, - }) + return d.remoteStack( + stack, + endpoint, + OperationDeploy, + unpackerCmdBuilderOptions{ + registries: registries, + }, + ) } // Undeploy a compose stack on remote environment using a https://github.com/portainer/compose-unpacker container @@ -71,8 +83,19 @@ func (d *stackDeployer) UndeployRemoteComposeStack(stack *portainer.Stack, endpo } // Start a compose stack on remote environment using a https://github.com/portainer/compose-unpacker container -func (d *stackDeployer) StartRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error { - return d.remoteStack(stack, endpoint, OperationComposeStart, unpackerCmdBuilderOptions{}) +func (d *stackDeployer) StartRemoteComposeStack( + stack *portainer.Stack, + endpoint *portainer.Endpoint, + registries []portainer.Registry, +) error { + return d.remoteStack( + stack, + endpoint, + OperationComposeStart, + unpackerCmdBuilderOptions{ + registries: registries, + }, + ) } // Stop a compose stack on remote environment using a https://github.com/portainer/compose-unpacker container @@ -81,7 +104,13 @@ func (d *stackDeployer) StopRemoteComposeStack(stack *portainer.Stack, endpoint } // Deploy a swarm stack on remote environment using a https://github.com/portainer/compose-unpacker container -func (d *stackDeployer) DeployRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune bool, pullImage bool) error { +func (d *stackDeployer) DeployRemoteSwarmStack( + stack *portainer.Stack, + endpoint *portainer.Endpoint, + registries []portainer.Registry, + prune bool, + pullImage bool, +) error { d.lock.Lock() defer d.lock.Unlock() @@ -105,8 +134,19 @@ func (d *stackDeployer) UndeployRemoteSwarmStack(stack *portainer.Stack, endpoin } // Start a swarm stack on remote environment using a https://github.com/portainer/compose-unpacker container -func (d *stackDeployer) StartRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error { - return d.remoteStack(stack, endpoint, OperationSwarmStart, unpackerCmdBuilderOptions{}) +func (d *stackDeployer) StartRemoteSwarmStack( + stack *portainer.Stack, + endpoint *portainer.Endpoint, + registries []portainer.Registry, +) error { + return d.remoteStack( + stack, + endpoint, + OperationSwarmStart, + unpackerCmdBuilderOptions{ + registries: registries, + }, + ) } // Stop a swarm stack on remote environment using a https://github.com/portainer/compose-unpacker container