Files
portainer/api/exec/swarm_stack.go
T
2026-05-14 10:13:19 +12:00

94 lines
2.3 KiB
Go

package exec
import (
"context"
"fmt"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/http/proxy"
"github.com/portainer/portainer/api/stacks/stackutils"
"github.com/portainer/portainer/pkg/libstack/swarm"
)
// SwarmStackManager represents a service for managing stacks.
type SwarmStackManager struct {
deployer swarm.Deployer
proxyManager *proxy.Manager
}
// NewSwarmStackManager creates a new SwarmStackManager.
func NewSwarmStackManager(
deployer swarm.Deployer,
proxyManager *proxy.Manager,
) *SwarmStackManager {
return &SwarmStackManager{
deployer: deployer,
proxyManager: proxyManager,
}
}
// Deploy creates or updates a Docker Swarm stack.
func (manager *SwarmStackManager) Deploy(
ctx context.Context,
stack *portainer.Stack,
prune bool,
pullImage bool,
endpoint *portainer.Endpoint,
registries []portainer.Registry,
) error {
url, proxy, err := fetchEndpointProxy(manager.proxyManager, endpoint)
if err != nil {
return fmt.Errorf("failed to fetch environment proxy: %w", err)
}
if proxy != nil {
defer proxy.Close()
}
filePaths := stackutils.GetStackFilePaths(stack, true)
env := make([]string, 0, len(stack.Env))
for _, ev := range stack.Env {
env = append(env, ev.Name+"="+ev.Value)
}
return manager.deployer.Deploy(context.TODO(), filePaths, swarm.DeployOptions{
Options: swarm.Options{
ProjectName: stack.Name,
Host: url,
Env: env,
WorkingDir: stack.ProjectPath,
Registries: portainerRegistriesToAuthConfigs(registries),
},
RemoveOrphans: prune,
PullImage: pullImage,
})
}
// Remove deletes all resources belonging to a Swarm stack.
func (manager *SwarmStackManager) Remove(
ctx context.Context,
stack *portainer.Stack,
endpoint *portainer.Endpoint,
) error {
url, proxy, err := fetchEndpointProxy(manager.proxyManager, endpoint)
if err != nil {
return fmt.Errorf("failed to fetch environment proxy: %w", err)
}
if proxy != nil {
defer proxy.Close()
}
return manager.deployer.Remove(context.TODO(), stack.Name, swarm.RemoveOptions{
Options: swarm.Options{
Host: url,
},
})
}
// NormalizeStackName returns a new stack name with unsupported characters replaced.
func (manager *SwarmStackManager) NormalizeStackName(name string) string {
return normalizeStackName(name)
}