Browse code

Restore stack deploy integration test with dab

Signed-off-by: Daniel Nephin <dnephin@docker.com>

Daniel Nephin authored on 2016/11/09 05:20:16
Showing 3 changed files
... ...
@@ -58,100 +58,18 @@ func newDeployCommand(dockerCli *command.DockerCli) *cobra.Command {
58 58
 }
59 59
 
60 60
 func runDeploy(dockerCli *command.DockerCli, opts deployOptions) error {
61
-	if opts.bundlefile == "" && opts.composefile == "" {
61
+	switch {
62
+	case opts.bundlefile == "" && opts.composefile == "":
62 63
 		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 != "":
66 65
 		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 != "":
78 67
 		return deployBundle(dockerCli, opts)
79
-	} else {
68
+	default:
80 69
 		return deployCompose(dockerCli, opts)
81 70
 	}
82 71
 }
83 72
 
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
-
155 73
 func deployCompose(dockerCli *command.DockerCli, opts deployOptions) error {
156 74
 	configDetails, err := getConfigDetails(opts)
157 75
 	if err != nil {
158 76
new file mode 100644
... ...
@@ -0,0 +1,80 @@
0
+package stack
1
+
2
+import (
3
+	"golang.org/x/net/context"
4
+
5
+	"github.com/docker/docker/api/types"
6
+	"github.com/docker/docker/api/types/swarm"
7
+	"github.com/docker/docker/cli/command"
8
+)
9
+
10
+func deployBundle(dockerCli *command.DockerCli, opts deployOptions) error {
11
+	bundle, err := loadBundlefile(dockerCli.Err(), opts.namespace, opts.bundlefile)
12
+	if err != nil {
13
+		return err
14
+	}
15
+
16
+	namespace := namespace{name: opts.namespace}
17
+
18
+	networks := make(map[string]types.NetworkCreate)
19
+	for _, service := range bundle.Services {
20
+		for _, networkName := range service.Networks {
21
+			networks[networkName] = types.NetworkCreate{
22
+				Labels: getStackLabels(namespace.name, nil),
23
+			}
24
+		}
25
+	}
26
+
27
+	services := make(map[string]swarm.ServiceSpec)
28
+	for internalName, service := range bundle.Services {
29
+		name := namespace.scope(internalName)
30
+
31
+		var ports []swarm.PortConfig
32
+		for _, portSpec := range service.Ports {
33
+			ports = append(ports, swarm.PortConfig{
34
+				Protocol:   swarm.PortConfigProtocol(portSpec.Protocol),
35
+				TargetPort: portSpec.Port,
36
+			})
37
+		}
38
+
39
+		nets := []swarm.NetworkAttachmentConfig{}
40
+		for _, networkName := range service.Networks {
41
+			nets = append(nets, swarm.NetworkAttachmentConfig{
42
+				Target:  namespace.scope(networkName),
43
+				Aliases: []string{networkName},
44
+			})
45
+		}
46
+
47
+		serviceSpec := swarm.ServiceSpec{
48
+			Annotations: swarm.Annotations{
49
+				Name:   name,
50
+				Labels: getStackLabels(namespace.name, service.Labels),
51
+			},
52
+			TaskTemplate: swarm.TaskSpec{
53
+				ContainerSpec: swarm.ContainerSpec{
54
+					Image:   service.Image,
55
+					Command: service.Command,
56
+					Args:    service.Args,
57
+					Env:     service.Env,
58
+					// Service Labels will not be copied to Containers
59
+					// automatically during the deployment so we apply
60
+					// it here.
61
+					Labels: getStackLabels(namespace.name, nil),
62
+				},
63
+			},
64
+			EndpointSpec: &swarm.EndpointSpec{
65
+				Ports: ports,
66
+			},
67
+			Networks: nets,
68
+		}
69
+
70
+		services[internalName] = serviceSpec
71
+	}
72
+
73
+	ctx := context.Background()
74
+
75
+	if err := createNetworks(ctx, dockerCli, namespace, networks); err != nil {
76
+		return err
77
+	}
78
+	return deployServices(ctx, dockerCli, services, namespace, opts.sendRegistryAuth)
79
+}
... ...
@@ -1,6 +1,9 @@
1 1
 package main
2 2
 
3 3
 import (
4
+	"io/ioutil"
5
+	"os"
6
+
4 7
 	"github.com/docker/docker/pkg/integration/checker"
5 8
 	"github.com/go-check/check"
6 9
 )
... ...
@@ -61,3 +64,59 @@ func (s *DockerSwarmSuite) TestStackDeployComposeFile(c *check.C) {
61 61
 	c.Assert(err, checker.IsNil)
62 62
 	c.Assert(out, check.Equals, "NAME  SERVICES\n")
63 63
 }
64
+
65
+// testDAB is the DAB JSON used for testing.
66
+// TODO: Use template/text and substitute "Image" with the result of
67
+// `docker inspect --format '{{index .RepoDigests 0}}' busybox:latest`
68
+const testDAB = `{
69
+    "Version": "0.1",
70
+    "Services": {
71
+	"srv1": {
72
+	    "Image": "busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0",
73
+	    "Command": ["top"]
74
+	},
75
+	"srv2": {
76
+	    "Image": "busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0",
77
+	    "Command": ["tail"],
78
+	    "Args": ["-f", "/dev/null"]
79
+	}
80
+    }
81
+}`
82
+
83
+func (s *DockerSwarmSuite) TestStackDeployWithDAB(c *check.C) {
84
+	testRequires(c, ExperimentalDaemon)
85
+	// setup
86
+	testStackName := "test"
87
+	testDABFileName := testStackName + ".dab"
88
+	defer os.RemoveAll(testDABFileName)
89
+	err := ioutil.WriteFile(testDABFileName, []byte(testDAB), 0444)
90
+	c.Assert(err, checker.IsNil)
91
+	d := s.AddDaemon(c, true, true)
92
+	// deploy
93
+	stackArgs := []string{
94
+		"stack", "deploy",
95
+		"--bundle-file", testDABFileName,
96
+		testStackName,
97
+	}
98
+	out, err := d.Cmd(stackArgs...)
99
+	c.Assert(err, checker.IsNil)
100
+	c.Assert(out, checker.Contains, "Loading bundle from test.dab\n")
101
+	c.Assert(out, checker.Contains, "Creating service test_srv1\n")
102
+	c.Assert(out, checker.Contains, "Creating service test_srv2\n")
103
+	// ls
104
+	stackArgs = []string{"stack", "ls"}
105
+	out, err = d.Cmd(stackArgs...)
106
+	c.Assert(err, checker.IsNil)
107
+	c.Assert(out, check.Equals, "NAME  SERVICES\n"+"test  2\n")
108
+	// rm
109
+	stackArgs = []string{"stack", "rm", testStackName}
110
+	out, err = d.Cmd(stackArgs...)
111
+	c.Assert(err, checker.IsNil)
112
+	c.Assert(out, checker.Contains, "Removing service test_srv1\n")
113
+	c.Assert(out, checker.Contains, "Removing service test_srv2\n")
114
+	// ls (empty)
115
+	stackArgs = []string{"stack", "ls"}
116
+	out, err = d.Cmd(stackArgs...)
117
+	c.Assert(err, checker.IsNil)
118
+	c.Assert(out, check.Equals, "NAME  SERVICES\n")
119
+}