Skip to content

Commit bd8de8d

Browse files
committed
Restore stack deploy integration test with dab
Signed-off-by: Daniel Nephin <dnephin@docker.com>
1 parent aa5e7d0 commit bd8de8d

File tree

3 files changed

+144
-87
lines changed

3 files changed

+144
-87
lines changed

cli/command/stack/deploy.go

Lines changed: 5 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -58,100 +58,18 @@ func newDeployCommand(dockerCli *command.DockerCli) *cobra.Command {
5858
}
5959

6060
func runDeploy(dockerCli *command.DockerCli, opts deployOptions) error {
61-
if opts.bundlefile == "" && opts.composefile == "" {
61+
switch {
62+
case opts.bundlefile == "" && opts.composefile == "":
6263
return fmt.Errorf("Please specify either a bundle file (with --bundle-file) or a Compose file (with --compose-file).")
63-
}
64-
65-
if opts.bundlefile != "" && opts.composefile != "" {
64+
case opts.bundlefile != "" && opts.composefile != "":
6665
return fmt.Errorf("You cannot specify both a bundle file and a Compose file.")
67-
}
68-
69-
info, err := dockerCli.Client().Info(context.Background())
70-
if err != nil {
71-
return err
72-
}
73-
if !info.Swarm.ControlAvailable {
74-
return fmt.Errorf("This node is not a swarm manager. Use \"docker swarm init\" or \"docker swarm join\" to connect this node to swarm and try again.")
75-
}
76-
77-
if opts.bundlefile != "" {
66+
case opts.bundlefile != "":
7867
return deployBundle(dockerCli, opts)
79-
} else {
68+
default:
8069
return deployCompose(dockerCli, opts)
8170
}
8271
}
8372

84-
func deployBundle(dockerCli *command.DockerCli, opts deployOptions) error {
85-
bundle, err := loadBundlefile(dockerCli.Err(), opts.namespace, opts.bundlefile)
86-
if err != nil {
87-
return err
88-
}
89-
90-
namespace := namespace{name: opts.namespace}
91-
92-
networks := make(map[string]types.NetworkCreate)
93-
for _, service := range bundle.Services {
94-
for _, networkName := range service.Networks {
95-
networks[networkName] = types.NetworkCreate{
96-
Labels: getStackLabels(namespace.name, nil),
97-
}
98-
}
99-
}
100-
101-
services := make(map[string]swarm.ServiceSpec)
102-
for internalName, service := range bundle.Services {
103-
name := namespace.scope(internalName)
104-
105-
var ports []swarm.PortConfig
106-
for _, portSpec := range service.Ports {
107-
ports = append(ports, swarm.PortConfig{
108-
Protocol: swarm.PortConfigProtocol(portSpec.Protocol),
109-
TargetPort: portSpec.Port,
110-
})
111-
}
112-
113-
nets := []swarm.NetworkAttachmentConfig{}
114-
for _, networkName := range service.Networks {
115-
nets = append(nets, swarm.NetworkAttachmentConfig{
116-
Target: namespace.scope(networkName),
117-
Aliases: []string{networkName},
118-
})
119-
}
120-
121-
serviceSpec := swarm.ServiceSpec{
122-
Annotations: swarm.Annotations{
123-
Name: name,
124-
Labels: getStackLabels(namespace.name, service.Labels),
125-
},
126-
TaskTemplate: swarm.TaskSpec{
127-
ContainerSpec: swarm.ContainerSpec{
128-
Image: service.Image,
129-
Command: service.Command,
130-
Args: service.Args,
131-
Env: service.Env,
132-
// Service Labels will not be copied to Containers
133-
// automatically during the deployment so we apply
134-
// it here.
135-
Labels: getStackLabels(namespace.name, nil),
136-
},
137-
},
138-
EndpointSpec: &swarm.EndpointSpec{
139-
Ports: ports,
140-
},
141-
Networks: nets,
142-
}
143-
144-
services[internalName] = serviceSpec
145-
}
146-
147-
ctx := context.Background()
148-
149-
if err := createNetworks(ctx, dockerCli, namespace, networks); err != nil {
150-
return err
151-
}
152-
return deployServices(ctx, dockerCli, services, namespace, opts.sendRegistryAuth)
153-
}
154-
15573
func deployCompose(dockerCli *command.DockerCli, opts deployOptions) error {
15674
configDetails, err := getConfigDetails(opts)
15775
if err != nil {
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package stack
2+
3+
import (
4+
"golang.org/x/net/context"
5+
6+
"github.com/docker/docker/api/types"
7+
"github.com/docker/docker/api/types/swarm"
8+
"github.com/docker/docker/cli/command"
9+
)
10+
11+
func deployBundle(dockerCli *command.DockerCli, opts deployOptions) error {
12+
bundle, err := loadBundlefile(dockerCli.Err(), opts.namespace, opts.bundlefile)
13+
if err != nil {
14+
return err
15+
}
16+
17+
namespace := namespace{name: opts.namespace}
18+
19+
networks := make(map[string]types.NetworkCreate)
20+
for _, service := range bundle.Services {
21+
for _, networkName := range service.Networks {
22+
networks[networkName] = types.NetworkCreate{
23+
Labels: getStackLabels(namespace.name, nil),
24+
}
25+
}
26+
}
27+
28+
services := make(map[string]swarm.ServiceSpec)
29+
for internalName, service := range bundle.Services {
30+
name := namespace.scope(internalName)
31+
32+
var ports []swarm.PortConfig
33+
for _, portSpec := range service.Ports {
34+
ports = append(ports, swarm.PortConfig{
35+
Protocol: swarm.PortConfigProtocol(portSpec.Protocol),
36+
TargetPort: portSpec.Port,
37+
})
38+
}
39+
40+
nets := []swarm.NetworkAttachmentConfig{}
41+
for _, networkName := range service.Networks {
42+
nets = append(nets, swarm.NetworkAttachmentConfig{
43+
Target: namespace.scope(networkName),
44+
Aliases: []string{networkName},
45+
})
46+
}
47+
48+
serviceSpec := swarm.ServiceSpec{
49+
Annotations: swarm.Annotations{
50+
Name: name,
51+
Labels: getStackLabels(namespace.name, service.Labels),
52+
},
53+
TaskTemplate: swarm.TaskSpec{
54+
ContainerSpec: swarm.ContainerSpec{
55+
Image: service.Image,
56+
Command: service.Command,
57+
Args: service.Args,
58+
Env: service.Env,
59+
// Service Labels will not be copied to Containers
60+
// automatically during the deployment so we apply
61+
// it here.
62+
Labels: getStackLabels(namespace.name, nil),
63+
},
64+
},
65+
EndpointSpec: &swarm.EndpointSpec{
66+
Ports: ports,
67+
},
68+
Networks: nets,
69+
}
70+
71+
services[internalName] = serviceSpec
72+
}
73+
74+
ctx := context.Background()
75+
76+
if err := createNetworks(ctx, dockerCli, namespace, networks); err != nil {
77+
return err
78+
}
79+
return deployServices(ctx, dockerCli, services, namespace, opts.sendRegistryAuth)
80+
}

integration-cli/docker_cli_stack_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package main
22

33
import (
4+
"io/ioutil"
5+
"os"
6+
47
"github.com/docker/docker/pkg/integration/checker"
58
"github.com/go-check/check"
69
)
@@ -61,3 +64,59 @@ func (s *DockerSwarmSuite) TestStackDeployComposeFile(c *check.C) {
6164
c.Assert(err, checker.IsNil)
6265
c.Assert(out, check.Equals, "NAME SERVICES\n")
6366
}
67+
68+
// testDAB is the DAB JSON used for testing.
69+
// TODO: Use template/text and substitute "Image" with the result of
70+
// `docker inspect --format '{{index .RepoDigests 0}}' busybox:latest`
71+
const testDAB = `{
72+
"Version": "0.1",
73+
"Services": {
74+
"srv1": {
75+
"Image": "busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0",
76+
"Command": ["top"]
77+
},
78+
"srv2": {
79+
"Image": "busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0",
80+
"Command": ["tail"],
81+
"Args": ["-f", "/dev/null"]
82+
}
83+
}
84+
}`
85+
86+
func (s *DockerSwarmSuite) TestStackDeployWithDAB(c *check.C) {
87+
testRequires(c, ExperimentalDaemon)
88+
// setup
89+
testStackName := "test"
90+
testDABFileName := testStackName + ".dab"
91+
defer os.RemoveAll(testDABFileName)
92+
err := ioutil.WriteFile(testDABFileName, []byte(testDAB), 0444)
93+
c.Assert(err, checker.IsNil)
94+
d := s.AddDaemon(c, true, true)
95+
// deploy
96+
stackArgs := []string{
97+
"stack", "deploy",
98+
"--bundle-file", testDABFileName,
99+
testStackName,
100+
}
101+
out, err := d.Cmd(stackArgs...)
102+
c.Assert(err, checker.IsNil)
103+
c.Assert(out, checker.Contains, "Loading bundle from test.dab\n")
104+
c.Assert(out, checker.Contains, "Creating service test_srv1\n")
105+
c.Assert(out, checker.Contains, "Creating service test_srv2\n")
106+
// ls
107+
stackArgs = []string{"stack", "ls"}
108+
out, err = d.Cmd(stackArgs...)
109+
c.Assert(err, checker.IsNil)
110+
c.Assert(out, check.Equals, "NAME SERVICES\n"+"test 2\n")
111+
// rm
112+
stackArgs = []string{"stack", "rm", testStackName}
113+
out, err = d.Cmd(stackArgs...)
114+
c.Assert(err, checker.IsNil)
115+
c.Assert(out, checker.Contains, "Removing service test_srv1\n")
116+
c.Assert(out, checker.Contains, "Removing service test_srv2\n")
117+
// ls (empty)
118+
stackArgs = []string{"stack", "ls"}
119+
out, err = d.Cmd(stackArgs...)
120+
c.Assert(err, checker.IsNil)
121+
c.Assert(out, check.Equals, "NAME SERVICES\n")
122+
}

0 commit comments

Comments
 (0)