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  }