fix(stacks): pass prune option through the deploy pipeline [BE-12738] (#2098)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -70,6 +70,7 @@ func (manager *ComposeStackManager) Up(ctx context.Context, stack *portainer.Sta
|
||||
},
|
||||
ForceRecreate: options.ForceRecreate,
|
||||
AbortOnContainerExit: options.AbortOnContainerExit,
|
||||
RemoveOrphans: options.Prune,
|
||||
})
|
||||
return errors.Wrap(err, "failed to deploy a stack")
|
||||
}
|
||||
|
||||
@@ -199,6 +199,7 @@ func (handler *Handler) migrateComposeStack(r *http.Request, stack *portainer.St
|
||||
handler.DataStore,
|
||||
handler.FileService,
|
||||
handler.StackDeployer,
|
||||
true,
|
||||
false,
|
||||
false)
|
||||
if err != nil {
|
||||
|
||||
@@ -26,6 +26,8 @@ type updateComposeStackPayload struct {
|
||||
Env []portainer.Pair
|
||||
// RepullImageAndRedeploy indicates whether to force repulling images and redeploying the stack
|
||||
RepullImageAndRedeploy bool
|
||||
// Prune services that are no longer referenced
|
||||
Prune bool `example:"true"`
|
||||
|
||||
// Deprecated(2.36): use RepullImageAndRedeploy instead for cleaner responsibility
|
||||
// Force a pulling to current image with the original tag though the image is already the latest
|
||||
@@ -45,7 +47,7 @@ type updateSwarmStackPayload struct {
|
||||
StackFileContent string `example:"version: 3\n services:\n web:\n image:nginx"`
|
||||
// A list of environment(endpoint) variables used during stack deployment
|
||||
Env []portainer.Pair
|
||||
// Prune services that are no longer referenced (only available for Swarm stacks)
|
||||
// Prune services that are no longer referenced
|
||||
Prune bool `example:"true"`
|
||||
// RepullImageAndRedeploy indicates whether to force repulling images and redeploying the stack
|
||||
RepullImageAndRedeploy bool
|
||||
@@ -242,6 +244,7 @@ func (handler *Handler) updateComposeStack(tx dataservices.DataStoreTx, r *http.
|
||||
endpoint,
|
||||
handler.FileService,
|
||||
handler.StackDeployer,
|
||||
payload.Prune,
|
||||
payload.RepullImageAndRedeploy,
|
||||
payload.RepullImageAndRedeploy)
|
||||
if err != nil {
|
||||
@@ -252,6 +255,14 @@ func (handler *Handler) updateComposeStack(tx dataservices.DataStoreTx, r *http.
|
||||
return httperror.InternalServerError(err.Error(), err)
|
||||
}
|
||||
|
||||
if stack.Option != nil {
|
||||
stack.Option.Prune = payload.Prune
|
||||
} else {
|
||||
stack.Option = &portainer.StackOption{
|
||||
Prune: payload.Prune,
|
||||
}
|
||||
}
|
||||
|
||||
// Deploy the stack
|
||||
if err := composeDeploymentConfig.Deploy(); err != nil {
|
||||
if rollbackErr := handler.FileService.RollbackStackFile(stackFolder, stack.EntryPoint); rollbackErr != nil {
|
||||
|
||||
@@ -130,8 +130,11 @@ func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request)
|
||||
payload.RepullImageAndRedeploy = payload.RepullImageAndRedeploy || payload.PullImage
|
||||
stack.GitConfig.ReferenceName = payload.RepositoryReferenceName
|
||||
stack.Env = payload.Env
|
||||
if stack.Type == portainer.DockerSwarmStack {
|
||||
stack.Option = &portainer.StackOption{Prune: payload.Prune}
|
||||
if stack.Type == portainer.DockerSwarmStack || stack.Type == portainer.DockerComposeStack {
|
||||
if stack.Option == nil {
|
||||
stack.Option = &portainer.StackOption{}
|
||||
}
|
||||
stack.Option.Prune = payload.Prune
|
||||
}
|
||||
|
||||
if stack.Type == portainer.KubernetesStack {
|
||||
@@ -233,7 +236,9 @@ func (handler *Handler) deployStack(r *http.Request, stack *portainer.Stack, pul
|
||||
return httperror.InternalServerError("Unable to retrieve info from request context", err)
|
||||
}
|
||||
|
||||
deploymentConfiger, err = deployments.CreateComposeStackDeploymentConfig(securityContext, stack, endpoint, handler.DataStore, handler.FileService, handler.StackDeployer, pullImage, true)
|
||||
prune := stack.Option != nil && stack.Option.Prune
|
||||
|
||||
deploymentConfiger, err = deployments.CreateComposeStackDeploymentConfig(securityContext, stack, endpoint, handler.DataStore, handler.FileService, handler.StackDeployer, prune, pullImage, true)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError(err.Error(), err)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
"github.com/portainer/portainer/api/datastore"
|
||||
"github.com/portainer/portainer/api/filesystem"
|
||||
"github.com/portainer/portainer/api/internal/testhelpers"
|
||||
"github.com/portainer/portainer/api/stacks/deployments"
|
||||
"github.com/portainer/portainer/api/stacks/stackutils"
|
||||
"github.com/portainer/portainer/pkg/fips"
|
||||
httperror "github.com/portainer/portainer/pkg/libhttp/error"
|
||||
@@ -248,7 +247,7 @@ func TestStackUpdate(t *testing.T) {
|
||||
handler := NewHandler(testhelpers.NewTestRequestBouncer())
|
||||
handler.DataStore = store
|
||||
handler.FileService = fileService
|
||||
handler.StackDeployer = testStackDeployer{}
|
||||
handler.StackDeployer = testhelpers.NewTestStackDeployer()
|
||||
handler.ComposeStackManager = testhelpers.NewComposeStackManager()
|
||||
handler.SwarmStackManager = swarmStackManager{}
|
||||
|
||||
@@ -318,7 +317,11 @@ type updateStackInTxTestSetup struct {
|
||||
req *http.Request
|
||||
}
|
||||
|
||||
func setupUpdateStackInTxTest(t *testing.T, stack *portainer.Stack, payload *updateComposeStackPayload) *updateStackInTxTestSetup {
|
||||
type testUpdateStackPayload interface {
|
||||
*updateComposeStackPayload | *updateSwarmStackPayload
|
||||
}
|
||||
|
||||
func setupUpdateStackInTxTest[T testUpdateStackPayload](t *testing.T, stack *portainer.Stack, payload T) *updateStackInTxTestSetup {
|
||||
t.Helper()
|
||||
|
||||
_, store := datastore.MustNewTestStore(t, true, true)
|
||||
@@ -364,7 +367,7 @@ func setupUpdateStackInTxTest(t *testing.T, stack *portainer.Stack, payload *upd
|
||||
handler := NewHandler(testhelpers.NewTestRequestBouncer())
|
||||
handler.DataStore = store
|
||||
handler.FileService = fileService
|
||||
handler.StackDeployer = testStackDeployer{}
|
||||
handler.StackDeployer = testhelpers.NewTestStackDeployer()
|
||||
handler.ComposeStackManager = testhelpers.NewComposeStackManager()
|
||||
|
||||
// Create mock request with security context
|
||||
@@ -398,22 +401,73 @@ func (manager swarmStackManager) NormalizeStackName(name string) string {
|
||||
return name
|
||||
}
|
||||
|
||||
type testStackDeployer struct {
|
||||
deployments.StackDeployer
|
||||
func Test_updateSwarmStack_Prune(t *testing.T) {
|
||||
fips.InitFIPS(false)
|
||||
|
||||
payload := &updateSwarmStackPayload{
|
||||
StackFileContent: "version: '3'\nservices:\n web:\n image: nginx:latest",
|
||||
Prune: true,
|
||||
}
|
||||
stack := &portainer.Stack{
|
||||
ID: 1,
|
||||
Name: "test-stack-prune",
|
||||
EntryPoint: "docker-compose.yml",
|
||||
Type: portainer.DockerSwarmStack,
|
||||
}
|
||||
setup := setupUpdateStackInTxTest(t, stack, payload)
|
||||
setup.handler.SwarmStackManager = swarmStackManager{}
|
||||
deployer := testhelpers.NewTestStackDeployer()
|
||||
setup.handler.StackDeployer = deployer
|
||||
|
||||
err := setup.store.UpdateTx(func(tx dataservices.DataStoreTx) error {
|
||||
_, handlerErr := setup.handler.updateStackInTx(tx, setup.req, setup.stack.ID, setup.endpoint.ID)
|
||||
if handlerErr != nil {
|
||||
return handlerErr
|
||||
}
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err, "handler should accept Prune=true and succeed")
|
||||
|
||||
stored, err := setup.store.Stack().Read(setup.stack.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, stored.Option, "stack.Option should not be nil")
|
||||
assert.True(t, stored.Option.Prune, "stack.Option.Prune should be persisted as true")
|
||||
|
||||
assert.Equal(t, 1, deployer.DeploySwarmCallCount, "DeploySwarmStack should be called exactly once")
|
||||
assert.True(t, deployer.LastPrune, "deployer should be invoked with prune=true")
|
||||
}
|
||||
|
||||
func (testStackDeployer) DeployComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, forcePullImage, forceRecreate bool) error {
|
||||
return nil
|
||||
}
|
||||
func Test_updateComposeStack_Prune(t *testing.T) {
|
||||
fips.InitFIPS(false)
|
||||
|
||||
func (testStackDeployer) DeploySwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune, pullImage bool) error {
|
||||
return nil
|
||||
}
|
||||
payload := &updateComposeStackPayload{
|
||||
StackFileContent: "version: '3'\nservices:\n web:\n image: nginx:latest",
|
||||
Prune: true,
|
||||
}
|
||||
stack := &portainer.Stack{
|
||||
ID: 1,
|
||||
Name: "test-stack-prune",
|
||||
EntryPoint: "docker-compose.yml",
|
||||
Type: portainer.DockerComposeStack,
|
||||
}
|
||||
setup := setupUpdateStackInTxTest(t, stack, payload)
|
||||
deployer := testhelpers.NewTestStackDeployer()
|
||||
setup.handler.StackDeployer = deployer
|
||||
|
||||
func (testStackDeployer) DeployRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, forcePullImage, forceRecreate bool) error {
|
||||
return nil
|
||||
}
|
||||
err := setup.store.UpdateTx(func(tx dataservices.DataStoreTx) error {
|
||||
_, handlerErr := setup.handler.updateStackInTx(tx, setup.req, setup.stack.ID, setup.endpoint.ID)
|
||||
if handlerErr != nil {
|
||||
return handlerErr
|
||||
}
|
||||
return nil
|
||||
})
|
||||
require.NoError(t, err, "handler should accept Prune=true and succeed")
|
||||
|
||||
func (testStackDeployer) DeployRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune, pullImage bool) error {
|
||||
return nil
|
||||
stored, err := setup.store.Stack().Read(setup.stack.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, stored.Option, "stack.Option should not be nil")
|
||||
assert.True(t, stored.Option.Prune, "stack.Option.Prune should be persisted as true")
|
||||
|
||||
assert.Equal(t, 1, deployer.DeployComposeCallCount, "DeployComposeStack should be called exactly once")
|
||||
assert.True(t, deployer.LastPrune, "deployer should be invoked with prune=true")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package testhelpers
|
||||
|
||||
import portainer "github.com/portainer/portainer/api"
|
||||
|
||||
type TestStackDeployer struct {
|
||||
DeployComposeCallCount int
|
||||
DeploySwarmCallCount int
|
||||
LastPrune bool
|
||||
}
|
||||
|
||||
func NewTestStackDeployer() *TestStackDeployer {
|
||||
return &TestStackDeployer{}
|
||||
}
|
||||
|
||||
func (d *TestStackDeployer) DeployComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune, forcePullImage, forceRecreate bool) error {
|
||||
d.DeployComposeCallCount++
|
||||
d.LastPrune = prune
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *TestStackDeployer) DeploySwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune, pullImage bool) error {
|
||||
d.DeploySwarmCallCount++
|
||||
d.LastPrune = prune
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *TestStackDeployer) DeployKubernetesStack(stack *portainer.Stack, endpoint *portainer.Endpoint, user *portainer.User) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *TestStackDeployer) DeployRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune, forcePullImage, forceRecreate bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *TestStackDeployer) UndeployRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *TestStackDeployer) StartRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *TestStackDeployer) StopRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *TestStackDeployer) DeployRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune, pullImage bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *TestStackDeployer) UndeployRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *TestStackDeployer) StartRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *TestStackDeployer) StopRemoteSwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
||||
return nil
|
||||
}
|
||||
@@ -62,12 +62,17 @@ func (d *stackDeployer) buildUnpackerCmdForStack(stack *portainer.Stack, operati
|
||||
return fn(stack, opts, registriesStrings, envStrings), nil
|
||||
}
|
||||
|
||||
// deploy [-u username -p password] [--skip-tls-verify] [--force-recreate] [-k] [--env KEY1=VALUE1 --env KEY2=VALUE2] <git-repo-url> <ref> <project-name> <destination> <compose-file-path> [<more-file-paths>...]
|
||||
// deploy [-u username -p password] [--skip-tls-verify] [--force-recreate] [-r] [-k] [--env KEY1=VALUE1 --env KEY2=VALUE2] <git-repo-url> <ref> <project-name> <destination> <compose-file-path> [<more-file-paths>...]
|
||||
func buildDeployCmd(stack *portainer.Stack, opts unpackerCmdBuilderOptions, registries []string, env []string) []string {
|
||||
cmd := []string{UnpackerCmdDeploy}
|
||||
cmd = appendGitAuthIfNeeded(cmd, stack)
|
||||
cmd = appendSkipTLSVerifyIfNeeded(cmd, stack)
|
||||
cmd = appendForceRecreateIfNeeded(cmd, opts.forceRecreate)
|
||||
|
||||
if opts.prune {
|
||||
cmd = append(cmd, "-r")
|
||||
}
|
||||
|
||||
cmd = append(cmd, env...)
|
||||
cmd = append(cmd, registries...)
|
||||
cmd = append(cmd,
|
||||
|
||||
@@ -159,9 +159,9 @@ func redeployWhenChangedSecondStage(
|
||||
switch stack.Type {
|
||||
case portainer.DockerComposeStack:
|
||||
if stackutils.IsRelativePathStack(stack) {
|
||||
err = deployer.DeployRemoteComposeStack(stack, endpoint, registries, true, false)
|
||||
err = deployer.DeployRemoteComposeStack(stack, endpoint, registries, true, true, false)
|
||||
} else {
|
||||
err = deployer.DeployComposeStack(stack, endpoint, registries, true, false)
|
||||
err = deployer.DeployComposeStack(stack, endpoint, registries, true, true, false)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -82,7 +82,7 @@ func (s noopDeployer) DeploySwarmStack(stack *portainer.Stack, endpoint *portain
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s noopDeployer) DeployComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, forcePullImage, forceRecreate bool) error {
|
||||
func (s noopDeployer) DeployComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune, forcePullImage, forceRecreate bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ func (s noopDeployer) DeployKubernetesStack(stack *portainer.Stack, endpoint *po
|
||||
}
|
||||
|
||||
// with unpacker
|
||||
func (s noopDeployer) DeployRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, forcePullImage, forceRecreate bool) error {
|
||||
func (s noopDeployer) DeployRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune, forcePullImage, forceRecreate bool) error {
|
||||
return nil
|
||||
}
|
||||
func (s noopDeployer) UndeployRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
type BaseStackDeployer interface {
|
||||
DeploySwarmStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune, pullImage bool) error
|
||||
DeployComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, forcePullImage, forceRecreate bool) error
|
||||
DeployComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune, forcePullImage, forceRecreate bool) error
|
||||
DeployKubernetesStack(stack *portainer.Stack, endpoint *portainer.Endpoint, user *portainer.User) error
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ func (d *stackDeployer) DeploySwarmStack(stack *portainer.Stack, endpoint *porta
|
||||
return d.swarmStackManager.Deploy(stack, prune, pullImage, endpoint)
|
||||
}
|
||||
|
||||
func (d *stackDeployer) DeployComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, forcePullImage, forceRecreate bool) error {
|
||||
func (d *stackDeployer) DeployComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune, forcePullImage, forceRecreate bool) error {
|
||||
d.lock.Lock()
|
||||
defer d.lock.Unlock()
|
||||
|
||||
@@ -77,6 +77,7 @@ func (d *stackDeployer) DeployComposeStack(stack *portainer.Stack, endpoint *por
|
||||
return d.composeStackManager.Up(context.TODO(), stack, endpoint, portainer.ComposeUpOptions{
|
||||
ComposeOptions: options,
|
||||
ForceRecreate: forceRecreate,
|
||||
Prune: prune,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ const (
|
||||
|
||||
type RemoteStackDeployer interface {
|
||||
// compose
|
||||
DeployRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, forcePullImage bool, forceRecreate bool) error
|
||||
DeployRemoteComposeStack(stack *portainer.Stack, endpoint *portainer.Endpoint, registries []portainer.Registry, prune bool, forcePullImage bool, forceRecreate bool) error
|
||||
UndeployRemoteComposeStack(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
|
||||
@@ -50,6 +50,7 @@ func (d *stackDeployer) DeployRemoteComposeStack(
|
||||
stack *portainer.Stack,
|
||||
endpoint *portainer.Endpoint,
|
||||
registries []portainer.Registry,
|
||||
prune bool,
|
||||
forcePullImage bool,
|
||||
forceRecreate bool,
|
||||
) error {
|
||||
@@ -72,6 +73,7 @@ func (d *stackDeployer) DeployRemoteComposeStack(
|
||||
unpackerCmdBuilderOptions{
|
||||
forceRecreate: forceRecreate,
|
||||
registries: registries,
|
||||
prune: prune,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -22,16 +22,17 @@ type ComposeStackDeploymentConfig struct {
|
||||
ForceCreate bool
|
||||
FileService portainer.FileService
|
||||
StackDeployer StackDeployer
|
||||
prune bool
|
||||
}
|
||||
|
||||
func CreateComposeStackDeploymentConfig(securityContext *security.RestrictedRequestContext, stack *portainer.Stack, endpoint *portainer.Endpoint, dataStore dataservices.DataStore, fileService portainer.FileService, deployer StackDeployer, forcePullImage, forceCreate bool) (*ComposeStackDeploymentConfig, error) {
|
||||
return CreateComposeStackDeploymentConfigTx(dataStore, securityContext, stack, endpoint, fileService, deployer, forcePullImage, forceCreate)
|
||||
func CreateComposeStackDeploymentConfig(securityContext *security.RestrictedRequestContext, stack *portainer.Stack, endpoint *portainer.Endpoint, dataStore dataservices.DataStore, fileService portainer.FileService, deployer StackDeployer, prune, forcePullImage, forceCreate bool) (*ComposeStackDeploymentConfig, error) {
|
||||
return CreateComposeStackDeploymentConfigTx(dataStore, securityContext, stack, endpoint, fileService, deployer, prune, forcePullImage, forceCreate)
|
||||
}
|
||||
|
||||
// Alternate function that works within a transaction
|
||||
// We didn't update the original function to use a transaction because it would be a breaking change for many other files.
|
||||
// Let's do this only where necessary for now. This is also planed to be refactored in the future, but not prioritized right now.
|
||||
func CreateComposeStackDeploymentConfigTx(tx dataservices.DataStoreTx, securityContext *security.RestrictedRequestContext, stack *portainer.Stack, endpoint *portainer.Endpoint, fileService portainer.FileService, deployer StackDeployer, forcePullImage, forceCreate bool) (*ComposeStackDeploymentConfig, error) {
|
||||
func CreateComposeStackDeploymentConfigTx(tx dataservices.DataStoreTx, securityContext *security.RestrictedRequestContext, stack *portainer.Stack, endpoint *portainer.Endpoint, fileService portainer.FileService, deployer StackDeployer, prune, forcePullImage, forceCreate bool) (*ComposeStackDeploymentConfig, error) {
|
||||
user, err := tx.User().Read(securityContext.UserID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to load user information from the database: %w", err)
|
||||
@@ -48,6 +49,7 @@ func CreateComposeStackDeploymentConfigTx(tx dataservices.DataStoreTx, securityC
|
||||
stack: stack,
|
||||
endpoint: endpoint,
|
||||
registries: filteredRegistries,
|
||||
prune: prune,
|
||||
isAdmin: securityContext.IsAdmin,
|
||||
user: user,
|
||||
forcePullImage: forcePullImage,
|
||||
@@ -86,10 +88,10 @@ func (config *ComposeStackDeploymentConfig) Deploy() error {
|
||||
}
|
||||
|
||||
if stackutils.IsRelativePathStack(config.stack) {
|
||||
return config.StackDeployer.DeployRemoteComposeStack(config.stack, config.endpoint, config.registries, config.forcePullImage, config.ForceCreate)
|
||||
return config.StackDeployer.DeployRemoteComposeStack(config.stack, config.endpoint, config.registries, config.prune, config.forcePullImage, config.ForceCreate)
|
||||
}
|
||||
|
||||
return config.StackDeployer.DeployComposeStack(config.stack, config.endpoint, config.registries, config.forcePullImage, config.ForceCreate)
|
||||
return config.StackDeployer.DeployComposeStack(config.stack, config.endpoint, config.registries, config.prune, config.forcePullImage, config.ForceCreate)
|
||||
}
|
||||
|
||||
func (config *ComposeStackDeploymentConfig) GetResponse() string {
|
||||
|
||||
@@ -68,7 +68,7 @@ func (b *ComposeStackFileContentBuilder) Deploy(payload *StackPayload, endpoint
|
||||
return b
|
||||
}
|
||||
|
||||
composeDeploymentConfig, err := deployments.CreateComposeStackDeploymentConfig(b.SecurityContext, b.stack, endpoint, b.dataStore, b.fileService, b.stackDeployer, false, false)
|
||||
composeDeploymentConfig, err := deployments.CreateComposeStackDeploymentConfig(b.SecurityContext, b.stack, endpoint, b.dataStore, b.fileService, b.stackDeployer, false, false, false)
|
||||
if err != nil {
|
||||
b.err = err
|
||||
return b
|
||||
|
||||
@@ -58,7 +58,7 @@ func (b *ComposeStackFileUploadBuilder) Deploy(payload *StackPayload, endpoint *
|
||||
return b
|
||||
}
|
||||
|
||||
composeDeploymentConfig, err := deployments.CreateComposeStackDeploymentConfig(b.SecurityContext, b.stack, endpoint, b.dataStore, b.fileService, b.stackDeployer, false, false)
|
||||
composeDeploymentConfig, err := deployments.CreateComposeStackDeploymentConfig(b.SecurityContext, b.stack, endpoint, b.dataStore, b.fileService, b.stackDeployer, false, false, false)
|
||||
if err != nil {
|
||||
b.err = err
|
||||
return b
|
||||
|
||||
@@ -58,7 +58,7 @@ func (b *ComposeStackGitBuilder) Deploy(payload *StackPayload, endpoint *portain
|
||||
return b
|
||||
}
|
||||
|
||||
composeDeploymentConfig, err := deployments.CreateComposeStackDeploymentConfig(b.SecurityContext, b.stack, endpoint, b.dataStore, b.fileService, b.stackDeployer, false, false)
|
||||
composeDeploymentConfig, err := deployments.CreateComposeStackDeploymentConfig(b.SecurityContext, b.stack, endpoint, b.dataStore, b.fileService, b.stackDeployer, false, false, false)
|
||||
if err != nil {
|
||||
b.err = err
|
||||
return b
|
||||
|
||||
Reference in New Issue
Block a user