mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Restore stack deploy integration test with dab
Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
parent
aa5e7d038a
commit
bd8de8d8be
3 changed files with 144 additions and 87 deletions
|
@ -58,100 +58,18 @@ func newDeployCommand(dockerCli *command.DockerCli) *cobra.Command {
|
|||
}
|
||||
|
||||
func runDeploy(dockerCli *command.DockerCli, opts deployOptions) error {
|
||||
if opts.bundlefile == "" && opts.composefile == "" {
|
||||
switch {
|
||||
case opts.bundlefile == "" && opts.composefile == "":
|
||||
return fmt.Errorf("Please specify either a bundle file (with --bundle-file) or a Compose file (with --compose-file).")
|
||||
}
|
||||
|
||||
if opts.bundlefile != "" && opts.composefile != "" {
|
||||
case opts.bundlefile != "" && opts.composefile != "":
|
||||
return fmt.Errorf("You cannot specify both a bundle file and a Compose file.")
|
||||
}
|
||||
|
||||
info, err := dockerCli.Client().Info(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.Swarm.ControlAvailable {
|
||||
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.")
|
||||
}
|
||||
|
||||
if opts.bundlefile != "" {
|
||||
case opts.bundlefile != "":
|
||||
return deployBundle(dockerCli, opts)
|
||||
} else {
|
||||
default:
|
||||
return deployCompose(dockerCli, opts)
|
||||
}
|
||||
}
|
||||
|
||||
func deployBundle(dockerCli *command.DockerCli, opts deployOptions) error {
|
||||
bundle, err := loadBundlefile(dockerCli.Err(), opts.namespace, opts.bundlefile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespace := namespace{name: opts.namespace}
|
||||
|
||||
networks := make(map[string]types.NetworkCreate)
|
||||
for _, service := range bundle.Services {
|
||||
for _, networkName := range service.Networks {
|
||||
networks[networkName] = types.NetworkCreate{
|
||||
Labels: getStackLabels(namespace.name, nil),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
services := make(map[string]swarm.ServiceSpec)
|
||||
for internalName, service := range bundle.Services {
|
||||
name := namespace.scope(internalName)
|
||||
|
||||
var ports []swarm.PortConfig
|
||||
for _, portSpec := range service.Ports {
|
||||
ports = append(ports, swarm.PortConfig{
|
||||
Protocol: swarm.PortConfigProtocol(portSpec.Protocol),
|
||||
TargetPort: portSpec.Port,
|
||||
})
|
||||
}
|
||||
|
||||
nets := []swarm.NetworkAttachmentConfig{}
|
||||
for _, networkName := range service.Networks {
|
||||
nets = append(nets, swarm.NetworkAttachmentConfig{
|
||||
Target: namespace.scope(networkName),
|
||||
Aliases: []string{networkName},
|
||||
})
|
||||
}
|
||||
|
||||
serviceSpec := swarm.ServiceSpec{
|
||||
Annotations: swarm.Annotations{
|
||||
Name: name,
|
||||
Labels: getStackLabels(namespace.name, service.Labels),
|
||||
},
|
||||
TaskTemplate: swarm.TaskSpec{
|
||||
ContainerSpec: swarm.ContainerSpec{
|
||||
Image: service.Image,
|
||||
Command: service.Command,
|
||||
Args: service.Args,
|
||||
Env: service.Env,
|
||||
// Service Labels will not be copied to Containers
|
||||
// automatically during the deployment so we apply
|
||||
// it here.
|
||||
Labels: getStackLabels(namespace.name, nil),
|
||||
},
|
||||
},
|
||||
EndpointSpec: &swarm.EndpointSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
Networks: nets,
|
||||
}
|
||||
|
||||
services[internalName] = serviceSpec
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if err := createNetworks(ctx, dockerCli, namespace, networks); err != nil {
|
||||
return err
|
||||
}
|
||||
return deployServices(ctx, dockerCli, services, namespace, opts.sendRegistryAuth)
|
||||
}
|
||||
|
||||
func deployCompose(dockerCli *command.DockerCli, opts deployOptions) error {
|
||||
configDetails, err := getConfigDetails(opts)
|
||||
if err != nil {
|
||||
|
|
80
cli/command/stack/deploy_bundlefile.go
Normal file
80
cli/command/stack/deploy_bundlefile.go
Normal file
|
@ -0,0 +1,80 @@
|
|||
package stack
|
||||
|
||||
import (
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/cli/command"
|
||||
)
|
||||
|
||||
func deployBundle(dockerCli *command.DockerCli, opts deployOptions) error {
|
||||
bundle, err := loadBundlefile(dockerCli.Err(), opts.namespace, opts.bundlefile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespace := namespace{name: opts.namespace}
|
||||
|
||||
networks := make(map[string]types.NetworkCreate)
|
||||
for _, service := range bundle.Services {
|
||||
for _, networkName := range service.Networks {
|
||||
networks[networkName] = types.NetworkCreate{
|
||||
Labels: getStackLabels(namespace.name, nil),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
services := make(map[string]swarm.ServiceSpec)
|
||||
for internalName, service := range bundle.Services {
|
||||
name := namespace.scope(internalName)
|
||||
|
||||
var ports []swarm.PortConfig
|
||||
for _, portSpec := range service.Ports {
|
||||
ports = append(ports, swarm.PortConfig{
|
||||
Protocol: swarm.PortConfigProtocol(portSpec.Protocol),
|
||||
TargetPort: portSpec.Port,
|
||||
})
|
||||
}
|
||||
|
||||
nets := []swarm.NetworkAttachmentConfig{}
|
||||
for _, networkName := range service.Networks {
|
||||
nets = append(nets, swarm.NetworkAttachmentConfig{
|
||||
Target: namespace.scope(networkName),
|
||||
Aliases: []string{networkName},
|
||||
})
|
||||
}
|
||||
|
||||
serviceSpec := swarm.ServiceSpec{
|
||||
Annotations: swarm.Annotations{
|
||||
Name: name,
|
||||
Labels: getStackLabels(namespace.name, service.Labels),
|
||||
},
|
||||
TaskTemplate: swarm.TaskSpec{
|
||||
ContainerSpec: swarm.ContainerSpec{
|
||||
Image: service.Image,
|
||||
Command: service.Command,
|
||||
Args: service.Args,
|
||||
Env: service.Env,
|
||||
// Service Labels will not be copied to Containers
|
||||
// automatically during the deployment so we apply
|
||||
// it here.
|
||||
Labels: getStackLabels(namespace.name, nil),
|
||||
},
|
||||
},
|
||||
EndpointSpec: &swarm.EndpointSpec{
|
||||
Ports: ports,
|
||||
},
|
||||
Networks: nets,
|
||||
}
|
||||
|
||||
services[internalName] = serviceSpec
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
if err := createNetworks(ctx, dockerCli, namespace, networks); err != nil {
|
||||
return err
|
||||
}
|
||||
return deployServices(ctx, dockerCli, services, namespace, opts.sendRegistryAuth)
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/docker/docker/pkg/integration/checker"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
@ -61,3 +64,59 @@ func (s *DockerSwarmSuite) TestStackDeployComposeFile(c *check.C) {
|
|||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(out, check.Equals, "NAME SERVICES\n")
|
||||
}
|
||||
|
||||
// testDAB is the DAB JSON used for testing.
|
||||
// TODO: Use template/text and substitute "Image" with the result of
|
||||
// `docker inspect --format '{{index .RepoDigests 0}}' busybox:latest`
|
||||
const testDAB = `{
|
||||
"Version": "0.1",
|
||||
"Services": {
|
||||
"srv1": {
|
||||
"Image": "busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0",
|
||||
"Command": ["top"]
|
||||
},
|
||||
"srv2": {
|
||||
"Image": "busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0",
|
||||
"Command": ["tail"],
|
||||
"Args": ["-f", "/dev/null"]
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
func (s *DockerSwarmSuite) TestStackDeployWithDAB(c *check.C) {
|
||||
testRequires(c, ExperimentalDaemon)
|
||||
// setup
|
||||
testStackName := "test"
|
||||
testDABFileName := testStackName + ".dab"
|
||||
defer os.RemoveAll(testDABFileName)
|
||||
err := ioutil.WriteFile(testDABFileName, []byte(testDAB), 0444)
|
||||
c.Assert(err, checker.IsNil)
|
||||
d := s.AddDaemon(c, true, true)
|
||||
// deploy
|
||||
stackArgs := []string{
|
||||
"stack", "deploy",
|
||||
"--bundle-file", testDABFileName,
|
||||
testStackName,
|
||||
}
|
||||
out, err := d.Cmd(stackArgs...)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(out, checker.Contains, "Loading bundle from test.dab\n")
|
||||
c.Assert(out, checker.Contains, "Creating service test_srv1\n")
|
||||
c.Assert(out, checker.Contains, "Creating service test_srv2\n")
|
||||
// ls
|
||||
stackArgs = []string{"stack", "ls"}
|
||||
out, err = d.Cmd(stackArgs...)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(out, check.Equals, "NAME SERVICES\n"+"test 2\n")
|
||||
// rm
|
||||
stackArgs = []string{"stack", "rm", testStackName}
|
||||
out, err = d.Cmd(stackArgs...)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(out, checker.Contains, "Removing service test_srv1\n")
|
||||
c.Assert(out, checker.Contains, "Removing service test_srv2\n")
|
||||
// ls (empty)
|
||||
stackArgs = []string{"stack", "ls"}
|
||||
out, err = d.Cmd(stackArgs...)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(out, check.Equals, "NAME SERVICES\n")
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue