-
Notifications
You must be signed in to change notification settings - Fork 67
/
docker_swarm_stack.go
95 lines (78 loc) · 2.72 KB
/
docker_swarm_stack.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package exec
import (
"context"
"errors"
"path"
"runtime"
"github.com/portainer/agent"
libstack "github.com/portainer/portainer/pkg/libstack"
"github.com/portainer/portainer/pkg/libstack/compose"
)
// DockerSwarmStackService represents a service for managing stacks by using the Docker binary.
type DockerSwarmStackService struct {
command string
composeDeployer libstack.Deployer
}
type DockerSwarmDeployOpts struct {
Prune bool
}
// NewDockerSwarmStackService initializes a new DockerStackService service.
// It also updates the configuration of the Docker CLI binary.
func NewDockerSwarmStackService(binaryPath string) (*DockerSwarmStackService, error) {
// Assume Linux as a default
command := path.Join(binaryPath, "docker")
if runtime.GOOS == "windows" {
command = path.Join(binaryPath, "docker.exe")
}
composeDeployer, err := compose.NewComposeDeployer(binaryPath, "")
if err != nil {
return nil, err
}
service := &DockerSwarmStackService{
command: command,
composeDeployer: composeDeployer,
}
return service, nil
}
// Deploy executes the docker stack deploy command.
func (service *DockerSwarmStackService) Deploy(ctx context.Context, name string, filePaths []string, options agent.DeployOptions) error {
if len(filePaths) == 0 {
return errors.New("missing file paths")
}
stackFilePath := filePaths[0]
args := []string{}
if options.Prune {
args = append(args, "stack", "deploy", "--prune", "--with-registry-auth", "--compose-file", stackFilePath, name)
} else {
args = append(args, "stack", "deploy", "--with-registry-auth", "--compose-file", stackFilePath, name)
}
stackFolder := options.WorkingDir
if stackFolder == "" {
stackFolder = path.Dir(stackFilePath)
}
_, err := runCommandAndCaptureStdErr(service.command, args, &cmdOpts{
WorkingDir: stackFolder,
Env: options.Env,
})
return err
}
// Pull is a dummy method for Swarm
func (service *DockerSwarmStackService) Pull(ctx context.Context, name string, filePaths []string, options agent.PullOptions) error {
return nil
}
// Validate uses compose to validate the stack files
func (service *DockerSwarmStackService) Validate(ctx context.Context, name string, filePaths []string, options agent.ValidateOptions) error {
return service.composeDeployer.Validate(ctx, filePaths, libstack.Options{
WorkingDir: options.WorkingDir,
Env: options.Env,
})
}
// Remove executes the docker stack rm command.
func (service *DockerSwarmStackService) Remove(ctx context.Context, name string, filePaths []string, options agent.RemoveOptions) error {
args := []string{"stack", "rm", name}
_, err := runCommandAndCaptureStdErr(service.command, args, &cmdOpts{
WorkingDir: options.WorkingDir,
Env: options.Env,
})
return err
}