func CreateContainer(containerName, image, domain string, portsToMap []Port, environmentVars map[string]string) (*docker.Container, error) { cfg := &docker.Config{} cfg.Image = image cfg.Hostname = containerName cfg.Domainname = domain var e struct{} exposedPorts := make(map[docker.Port]struct{}) for _, p := range portsToMap { prt := strconv.FormatUint(p.Private, 10) + "/" + p.Type exposedPorts[docker.Port(prt)] = e fmt.Printf("Exposing %s\n", prt) } cfg.ExposedPorts = exposedPorts envStrs := make([]string, 0, 10) for k, v := range environmentVars { envStrs = append(envStrs, k+"="+v) } cfg.Env = envStrs hostCfg := &docker.HostConfig{} hostCfg.PublishAllPorts = false hostCfg.Privileged = false hostPorts := make(map[docker.Port][]docker.PortBinding) for _, p := range portsToMap { prt := strconv.FormatUint(p.Private, 10) + "/" + p.Type bindings := make([]docker.PortBinding, 0, 4) bindings = append(bindings, docker.PortBinding{HostIP: "", HostPort: strconv.FormatUint(p.Public, 10)}) fmt.Printf("Binding %s to %s\n", prt, bindings[0]) hostPorts[docker.Port(prt)] = bindings } hostCfg.PortBindings = hostPorts opts := docker.CreateContainerOptions{} opts.Config = cfg opts.Name = containerName opts.HostConfig = hostCfg json, _ := data.PrettyPrint(opts) fmt.Printf("create options: %s\n", string(json)) container, err := client.CreateContainer(opts) if err != nil { fmt.Fprintf(os.Stderr, "Error creating container: %s\n", err.Error()) } else { fmt.Printf("Container created: %s\n", container.ID) } return container, err }
// DockerRun perform a docker run func DockerRun(req *DockerRunRequest) (DockerRunResponse, error) { response := DockerRunResponse{} //logit.Info.Println("DockerRun called") swarmURL := os.Getenv("SWARM_MANAGER_URL") if swarmURL == "" { logit.Error.Println("SWARM_MANAGER_URL not set") return response, errors.New("SWARM_MANAGER_URL not set") } var envvars []string var i = 0 if req.EnvVars != nil { envvars = make([]string, len(req.EnvVars)+1) for k, v := range req.EnvVars { envvars[i] = k + "=" + v i++ } } else { envvars = make([]string, 1) } if req.Profile == "" { return response, errors.New("Profile was empty and should not be") } //typical case is to always add the profile constraint env var //like SM, MED, LG, however in the case of a restore job, we //use a hard constraint of the host ipaddress to pin //the restored container to the same host as where the backup //is stored if req.IPAddress != "" { envvars[i] = "constraint:host==~" + req.IPAddress } else { envvars[i] = "constraint:profile==~" + req.Profile } docker, err := dockerapi.NewClient(swarmURL) if err != nil { logit.Error.Println(err.Error()) return response, err } options := dockerapi.CreateContainerOptions{} config := dockerapi.Config{} config.Hostname = req.ContainerName options.Config = &config hostConfig := dockerapi.HostConfig{} options.HostConfig = &hostConfig options.Name = req.ContainerName options.Config.Env = envvars options.Config.Image = "crunchydata/" + req.Image //logit.Info.Println("swarmapi using " + options.Config.Image + " as the image name") options.Config.Volumes = make(map[string]struct{}) //TODO figure out cpu shares and memory settings, these are different //than what I was using before due to me using the docker api directly //with this swarm implementation...use the defaults for now //options.HostConfig.CPUShares, err = strconv.ParseInt(req.CPU, 0, 64) //if err != nil { //logit.Error.Println(err.Error()) //return response, err //} //options.HostConfig.Memory = req.MEM options.HostConfig.Binds = make([]string, 3) options.HostConfig.Binds[0] = req.PGDataPath + ":/pgdata" options.HostConfig.Binds[1] = "/var/cpm/data/keys:/keys" options.HostConfig.Binds[2] = "/var/cpm/config:/syslogconfig" container, err3 := docker.CreateContainer(options) if err3 != nil { logit.Error.Println(err3.Error()) return response, err3 } var startResponse DockerStartResponse startRequest := DockerStartRequest{} startRequest.ContainerName = req.ContainerName startResponse, err = DockerStart(&startRequest) if err != nil { logit.Error.Println(err.Error()) return response, err } logit.Info.Println(startResponse.Output) //cmd := exec.Command(req.CommandPath, req.PGDataPath, req.ContainerName, //req.Image, req.CPU, req.MEM, allEnvVars) response.ID = container.ID return response, nil }