mirror of https://github.com/docker/docs.git
129 lines
3.0 KiB
Go
129 lines
3.0 KiB
Go
package provision
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
"text/template"
|
|
|
|
"github.com/docker/machine/libmachine/auth"
|
|
"github.com/docker/machine/libmachine/log"
|
|
"github.com/docker/machine/libmachine/swarm"
|
|
)
|
|
|
|
type SwarmCommandContext struct {
|
|
ContainerName string
|
|
Env []string
|
|
DockerDir string
|
|
DockerPort int
|
|
IP string
|
|
Port string
|
|
AuthOptions auth.Options
|
|
SwarmOptions swarm.Options
|
|
SwarmImage string
|
|
}
|
|
|
|
// Wrapper function to generate a docker run swarm command (manage or join)
|
|
// from a template/context and execute it.
|
|
func runSwarmCommandFromTemplate(p Provisioner, cmdTmpl string, swarmCmdContext SwarmCommandContext) error {
|
|
var (
|
|
executedCmdTmpl bytes.Buffer
|
|
)
|
|
|
|
parsedMasterCmdTemplate, err := template.New("swarmMasterCmd").Parse(cmdTmpl)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
parsedMasterCmdTemplate.Execute(&executedCmdTmpl, swarmCmdContext)
|
|
|
|
log.Debugf("The swarm command being run is: %s", executedCmdTmpl.String())
|
|
|
|
if _, err := p.SSHCommand(executedCmdTmpl.String()); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func configureSwarm(p Provisioner, swarmOptions swarm.Options, authOptions auth.Options) error {
|
|
if !swarmOptions.IsSwarm {
|
|
return nil
|
|
}
|
|
|
|
log.Info("Configuring swarm...")
|
|
|
|
ip, err := p.GetDriver().GetIP()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
u, err := url.Parse(swarmOptions.Host)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
parts := strings.Split(u.Host, ":")
|
|
port := parts[1]
|
|
|
|
dockerDir := p.GetDockerOptionsDir()
|
|
|
|
swarmCmdContext := SwarmCommandContext{
|
|
ContainerName: "",
|
|
Env: swarmOptions.Env,
|
|
DockerDir: dockerDir,
|
|
DockerPort: 2376,
|
|
IP: ip,
|
|
Port: port,
|
|
AuthOptions: authOptions,
|
|
SwarmOptions: swarmOptions,
|
|
SwarmImage: swarmOptions.Image,
|
|
}
|
|
|
|
// First things first, get the swarm image.
|
|
if _, err := p.SSHCommand(fmt.Sprintf("sudo docker pull %s", swarmOptions.Image)); err != nil {
|
|
return err
|
|
}
|
|
|
|
swarmMasterCmdTemplate := `sudo docker run -d \
|
|
--restart=always \
|
|
--net=host \
|
|
{{range .Env}} -e {{.}}{{end}} \
|
|
--name swarm-agent-master \
|
|
-p {{.Port}}:{{.Port}} \
|
|
-v {{.DockerDir}}:{{.DockerDir}} \
|
|
{{.SwarmImage}} \
|
|
manage \
|
|
--tlsverify \
|
|
--tlscacert={{.AuthOptions.CaCertRemotePath}} \
|
|
--tlscert={{.AuthOptions.ServerCertRemotePath}} \
|
|
--tlskey={{.AuthOptions.ServerKeyRemotePath}} \
|
|
-H {{.SwarmOptions.Host}} \
|
|
--strategy {{.SwarmOptions.Strategy}} --advertise {{.IP}}:{{.DockerPort}} {{range .SwarmOptions.ArbitraryFlags}} --{{.}}{{end}} {{.SwarmOptions.Discovery}}
|
|
`
|
|
|
|
swarmWorkerCmdTemplate := `sudo docker run -d \
|
|
--restart=always \
|
|
--net=host \
|
|
{{range .Env}} -e {{.}}{{end}} \
|
|
--name swarm-agent \
|
|
{{.SwarmImage}} \
|
|
join --advertise {{.IP}}:{{.DockerPort}} {{.SwarmOptions.Discovery}}
|
|
`
|
|
|
|
if swarmOptions.Master {
|
|
log.Debug("Launching swarm master")
|
|
if err := runSwarmCommandFromTemplate(p, swarmMasterCmdTemplate, swarmCmdContext); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
log.Debug("Launch swarm worker")
|
|
if err := runSwarmCommandFromTemplate(p, swarmWorkerCmdTemplate, swarmCmdContext); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|