// BuildContainerConfig creates a cluster.ContainerConfig from a dockerclient.ContainerConfig func BuildContainerConfig(c dockerclient.ContainerConfig) *ContainerConfig { var ( affinities []string constraints []string env []string ) // only for tests if c.Labels == nil { c.Labels = make(map[string]string) } // parse affinities from labels (ex. docker run --label 'com.docker.swarm.affinities=["container==redis","image==nginx"]') if labels, ok := c.Labels[SwarmLabelNamespace+".affinities"]; ok { json.Unmarshal([]byte(labels), &affinities) } // parse constraints from labels (ex. docker run --label 'com.docker.swarm.constraints=["region==us-east","storage==ssd"]') if labels, ok := c.Labels[SwarmLabelNamespace+".constraints"]; ok { json.Unmarshal([]byte(labels), &constraints) } // parse affinities/constraints from env (ex. docker run -e affinity:container==redis -e affinity:image==nginx -e constraint:region==us-east -e constraint:storage==ssd) for _, e := range c.Env { if ok, key, value := parseEnv(e); ok && key == "affinity" { affinities = append(affinities, value) } else if ok && key == "constraint" { constraints = append(constraints, value) } else { env = append(env, e) } } // remove affinities/constraints from env c.Env = env // store affinities in labels if len(affinities) > 0 { if labels, err := json.Marshal(affinities); err == nil { c.Labels[SwarmLabelNamespace+".affinities"] = string(labels) } } // store constraints in labels if len(constraints) > 0 { if labels, err := json.Marshal(constraints); err == nil { c.Labels[SwarmLabelNamespace+".constraints"] = string(labels) } } consolidateResourceFields(&c) return &ContainerConfig{c} }
func CreateService(config *ServiceConfig) ([]string, error) { swarm, err := swarmclient.NewSwarmClient() if err != nil { log.Fatalf("service.CreateService():%s\n", err) return nil, err } containerIds := make([]string, 0) containerConfig := new(dockerclient.ContainerConfig) containerConfig.Image = config.Spec.Image containerConfig.Labels = config.Metadata.Labels portBindings := make(map[string][]dockerclient.PortBinding) containerConfig.Env = config.Spec.Selector containerConfig.Cmd = config.Spec.Cmd //exposed ports , so that others can't use if len(config.Spec.Ports) > 0 { ports := make(map[string]struct{}) for index := range config.Spec.Ports { port := strconv.Itoa(config.Spec.Ports[index]) ports[port] = struct{}{} } containerConfig.ExposedPorts = ports } // intit hostconfig. use host, create and start containers hostConfig := &dockerclient.HostConfig{} if config.Spec.Resources.NetworkMode != "" { hostConfig.NetworkMode = config.Spec.Resources.NetworkMode } else { hostConfig.NetworkMode = "host" } // use to filter Resources hostConfig.CpuShares = config.Spec.Resources.CpuShares hostConfig.CpusetCpus = config.Spec.Resources.CpusetCpus hostConfig.Memory = config.Spec.Resources.Memory hostConfig.MemorySwap = config.Spec.Resources.MemorySwap cpuQuota, err := strconv.Atoi(config.Spec.Resources.CpuQuota) if err != nil { hostConfig.CpuQuota = 0 } else { hostConfig.CpuQuota = int64(cpuQuota) } // replicas numOfTimes := 0 if config.Spec.Replicas > 0 { numOfTimes = config.Spec.Replicas } else if config.Spec.Replicas == 0 { numOfTimes = len(config.Spec.Ips) //**** if len(config.Spec.Ports) == 0 { err := fmt.Errorf("service.CreateService():%+s Give ips but not give ports\n", config.Metadata.Name) log.Error(err) return nil, err } } for i := 0; i < numOfTimes; i++ { // use to filter specific ips and ports for _, port := range config.Spec.Ports { portbinding := &dockerclient.PortBinding{HostPort: strconv.Itoa(port)} if len(config.Spec.Ips) > 0 { portbinding.HostIp = config.Spec.Ips[i] } portBindings[strconv.Itoa(port)] = []dockerclient.PortBinding{*portbinding} } hostConfig.PortBindings = portBindings // hostconfig containerConfig.HostConfig = *hostConfig // give container different name containerName := config.Metadata.Name if role := config.Metadata.Labels["role"]; role != "" { containerName += "_" + role } containerName += strconv.Itoa(i) log.Debugf("service.CreateService():containerName:%s ; containerConfig:%+v\n", containerName, containerConfig) //create container containerId, err := swarm.CreateContainer(containerConfig, containerName) log.Debugf("service.CreateService():containerId:%s\n", containerId) if err != nil { log.Fatalf("service.CreateService():%s\n", err) fmt.Printf("[error]service.CreateService():%+v\n", err) } containerIds = append(containerIds, containerId) if config.Metadata.Labels["type"] != "libvirt" { //docker start container,libvirt do not need to start swarm.StartContainer(containerId, hostConfig) if err != nil { log.Fatalf("service.CreateService():%s\n", err) fmt.Printf("[error]service.CreateService():%+v\n", err) return nil, err } } } return containerIds, err }