blob: a92282a1a027ed635196a15d6a8675d2c65d36ce [file] [log] [blame]
package main
import (
"context"
"io/ioutil"
"os"
"path/filepath"
"text/template"
"github.com/docker/docker/client"
)
const composeTemplate = `# generated by integration-cli-on-swarm
version: "3"
services:
worker:
image: "{{.WorkerImage}}"
command: ["-worker-image-digest={{.WorkerImageDigest}}", "-dry-run={{.DryRun}}", "-keep-executor={{.KeepExecutor}}"]
networks:
- net
volumes:
# Bind-mount the API socket so that we can invoke "docker run --privileged" within the service containers
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DOCKER_GRAPHDRIVER={{.EnvDockerGraphDriver}}
- DOCKER_EXPERIMENTAL={{.EnvDockerExperimental}}
deploy:
mode: replicated
replicas: {{.Replicas}}
restart_policy:
# The restart condition needs to be any for funker function
condition: any
master:
image: "{{.MasterImage}}"
command: ["-worker-service=worker", "-input=/mnt/input", "-chunks={{.Chunks}}", "-shuffle={{.Shuffle}}", "-rand-seed={{.RandSeed}}"]
networks:
- net
volumes:
- {{.Volume}}:/mnt
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: none
placement:
# Make sure the master can access the volume
constraints: [node.id == {{.SelfNodeID}}]
networks:
net:
volumes:
{{.Volume}}:
external: true
`
type composeOptions struct {
Replicas int
Chunks int
MasterImage string
WorkerImage string
Volume string
Shuffle bool
RandSeed int64
DryRun bool
KeepExecutor bool
}
type composeTemplateOptions struct {
composeOptions
WorkerImageDigest string
SelfNodeID string
EnvDockerGraphDriver string
EnvDockerExperimental string
}
// createCompose creates "dir/docker-compose.yml".
// If dir is empty, TempDir() is used.
func createCompose(dir string, cli *client.Client, opts composeOptions) (string, error) {
if dir == "" {
var err error
dir, err = ioutil.TempDir("", "integration-cli-on-swarm-")
if err != nil {
return "", err
}
}
resolved := composeTemplateOptions{}
resolved.composeOptions = opts
workerImageInspect, _, err := cli.ImageInspectWithRaw(context.Background(), defaultWorkerImageName)
if err != nil {
return "", err
}
if len(workerImageInspect.RepoDigests) > 0 {
resolved.WorkerImageDigest = workerImageInspect.RepoDigests[0]
} else {
// fall back for non-pushed image
resolved.WorkerImageDigest = workerImageInspect.ID
}
info, err := cli.Info(context.Background())
if err != nil {
return "", err
}
resolved.SelfNodeID = info.Swarm.NodeID
resolved.EnvDockerGraphDriver = os.Getenv("DOCKER_GRAPHDRIVER")
resolved.EnvDockerExperimental = os.Getenv("DOCKER_EXPERIMENTAL")
composeFilePath := filepath.Join(dir, "docker-compose.yml")
tmpl, err := template.New("").Parse(composeTemplate)
if err != nil {
return "", err
}
f, err := os.Create(composeFilePath)
if err != nil {
return "", err
}
defer f.Close()
if err = tmpl.Execute(f, resolved); err != nil {
return "", err
}
return composeFilePath, nil
}