2016-11-08 15:20:16 -05:00
|
|
|
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"
|
2016-12-05 16:14:08 -05:00
|
|
|
"github.com/docker/docker/cli/compose/convert"
|
2016-11-08 15:20:16 -05:00
|
|
|
)
|
|
|
|
|
2016-11-21 15:03:43 -05:00
|
|
|
func deployBundle(ctx context.Context, dockerCli *command.DockerCli, opts deployOptions) error {
|
2016-11-08 15:20:16 -05:00
|
|
|
bundle, err := loadBundlefile(dockerCli.Err(), opts.namespace, opts.bundlefile)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2016-11-21 15:03:43 -05:00
|
|
|
if err := checkDaemonIsSwarmManager(ctx, dockerCli); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2016-12-05 16:14:08 -05:00
|
|
|
namespace := convert.NewNamespace(opts.namespace)
|
2016-11-08 15:20:16 -05:00
|
|
|
|
2017-02-22 15:43:13 -05:00
|
|
|
if opts.prune {
|
|
|
|
services := map[string]struct{}{}
|
|
|
|
for service := range bundle.Services {
|
|
|
|
services[service] = struct{}{}
|
|
|
|
}
|
|
|
|
pruneServices(ctx, dockerCli, namespace, services)
|
|
|
|
}
|
|
|
|
|
2016-11-08 15:20:16 -05:00
|
|
|
networks := make(map[string]types.NetworkCreate)
|
|
|
|
for _, service := range bundle.Services {
|
|
|
|
for _, networkName := range service.Networks {
|
|
|
|
networks[networkName] = types.NetworkCreate{
|
2016-12-05 16:14:08 -05:00
|
|
|
Labels: convert.AddStackLabel(namespace, nil),
|
2016-11-08 15:20:16 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
services := make(map[string]swarm.ServiceSpec)
|
|
|
|
for internalName, service := range bundle.Services {
|
2016-11-30 17:38:40 -05:00
|
|
|
name := namespace.Scope(internalName)
|
2016-11-08 15:20:16 -05:00
|
|
|
|
|
|
|
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{
|
2016-11-30 17:38:40 -05:00
|
|
|
Target: namespace.Scope(networkName),
|
2016-11-08 15:20:16 -05:00
|
|
|
Aliases: []string{networkName},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
serviceSpec := swarm.ServiceSpec{
|
|
|
|
Annotations: swarm.Annotations{
|
|
|
|
Name: name,
|
2016-12-05 16:14:08 -05:00
|
|
|
Labels: convert.AddStackLabel(namespace, service.Labels),
|
2016-11-08 15:20:16 -05:00
|
|
|
},
|
|
|
|
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.
|
2016-12-05 16:14:08 -05:00
|
|
|
Labels: convert.AddStackLabel(namespace, nil),
|
2016-11-08 15:20:16 -05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
EndpointSpec: &swarm.EndpointSpec{
|
|
|
|
Ports: ports,
|
|
|
|
},
|
|
|
|
Networks: nets,
|
|
|
|
}
|
|
|
|
|
|
|
|
services[internalName] = serviceSpec
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := createNetworks(ctx, dockerCli, namespace, networks); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return deployServices(ctx, dockerCli, services, namespace, opts.sendRegistryAuth)
|
|
|
|
}
|