github.com/ssdev-go/moby@v17.12.1-ce-rc2+incompatible/hack/integration-cli-on-swarm/host/compose.go (about) 1 package main 2 3 import ( 4 "context" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "text/template" 9 10 "github.com/docker/docker/client" 11 ) 12 13 const composeTemplate = `# generated by integration-cli-on-swarm 14 version: "3" 15 16 services: 17 worker: 18 image: "{{.WorkerImage}}" 19 command: ["-worker-image-digest={{.WorkerImageDigest}}", "-dry-run={{.DryRun}}", "-keep-executor={{.KeepExecutor}}"] 20 networks: 21 - net 22 volumes: 23 # Bind-mount the API socket so that we can invoke "docker run --privileged" within the service containers 24 - /var/run/docker.sock:/var/run/docker.sock 25 environment: 26 - DOCKER_GRAPHDRIVER={{.EnvDockerGraphDriver}} 27 - DOCKER_EXPERIMENTAL={{.EnvDockerExperimental}} 28 deploy: 29 mode: replicated 30 replicas: {{.Replicas}} 31 restart_policy: 32 # The restart condition needs to be any for funker function 33 condition: any 34 35 master: 36 image: "{{.MasterImage}}" 37 command: ["-worker-service=worker", "-input=/mnt/input", "-chunks={{.Chunks}}", "-shuffle={{.Shuffle}}", "-rand-seed={{.RandSeed}}"] 38 networks: 39 - net 40 volumes: 41 - {{.Volume}}:/mnt 42 deploy: 43 mode: replicated 44 replicas: 1 45 restart_policy: 46 condition: none 47 placement: 48 # Make sure the master can access the volume 49 constraints: [node.id == {{.SelfNodeID}}] 50 51 networks: 52 net: 53 54 volumes: 55 {{.Volume}}: 56 external: true 57 ` 58 59 type composeOptions struct { 60 Replicas int 61 Chunks int 62 MasterImage string 63 WorkerImage string 64 Volume string 65 Shuffle bool 66 RandSeed int64 67 DryRun bool 68 KeepExecutor bool 69 } 70 71 type composeTemplateOptions struct { 72 composeOptions 73 WorkerImageDigest string 74 SelfNodeID string 75 EnvDockerGraphDriver string 76 EnvDockerExperimental string 77 } 78 79 // createCompose creates "dir/docker-compose.yml". 80 // If dir is empty, TempDir() is used. 81 func createCompose(dir string, cli *client.Client, opts composeOptions) (string, error) { 82 if dir == "" { 83 var err error 84 dir, err = ioutil.TempDir("", "integration-cli-on-swarm-") 85 if err != nil { 86 return "", err 87 } 88 } 89 resolved := composeTemplateOptions{} 90 resolved.composeOptions = opts 91 workerImageInspect, _, err := cli.ImageInspectWithRaw(context.Background(), defaultWorkerImageName) 92 if err != nil { 93 return "", err 94 } 95 if len(workerImageInspect.RepoDigests) > 0 { 96 resolved.WorkerImageDigest = workerImageInspect.RepoDigests[0] 97 } else { 98 // fall back for non-pushed image 99 resolved.WorkerImageDigest = workerImageInspect.ID 100 } 101 info, err := cli.Info(context.Background()) 102 if err != nil { 103 return "", err 104 } 105 resolved.SelfNodeID = info.Swarm.NodeID 106 resolved.EnvDockerGraphDriver = os.Getenv("DOCKER_GRAPHDRIVER") 107 resolved.EnvDockerExperimental = os.Getenv("DOCKER_EXPERIMENTAL") 108 composeFilePath := filepath.Join(dir, "docker-compose.yml") 109 tmpl, err := template.New("").Parse(composeTemplate) 110 if err != nil { 111 return "", err 112 } 113 f, err := os.Create(composeFilePath) 114 if err != nil { 115 return "", err 116 } 117 defer f.Close() 118 if err = tmpl.Execute(f, resolved); err != nil { 119 return "", err 120 } 121 return composeFilePath, nil 122 }