func (c *Cluster) createContainer(config *cluster.ContainerConfig, name string, withImageAffinity bool, authConfig *dockerclient.AuthConfig) (*cluster.Container, error) { c.scheduler.Lock() // Ensure the name is available if !c.checkNameUniqueness(name) { c.scheduler.Unlock() return nil, fmt.Errorf("Conflict: The name %s is already assigned. You have to delete (or rename) that container to be able to assign %s to a container again.", name, name) } swarmID := config.SwarmID() if swarmID == "" { // Associate a Swarm ID to the container we are creating. swarmID = c.generateUniqueID() config.SetSwarmID(swarmID) } if network := c.Networks().Get(config.HostConfig.NetworkMode); network != nil && network.Scope == "local" { if !config.HaveNodeConstraint() { config.AddConstraint("node==~" + network.Engine.Name) } config.HostConfig.NetworkMode = network.Name } if withImageAffinity { config.AddAffinity("image==" + config.Image) } nodes, err := c.scheduler.SelectNodesForContainer(c.listNodes(), config) if withImageAffinity { config.RemoveAffinity("image==" + config.Image) } if err != nil { c.scheduler.Unlock() return nil, err } n := nodes[0] engine, ok := c.engines[n.ID] if !ok { c.scheduler.Unlock() return nil, fmt.Errorf("error creating container") } c.pendingContainers[swarmID] = &pendingContainer{ Name: name, Config: config, Engine: engine, } c.scheduler.Unlock() container, err := engine.Create(config, name, true, authConfig) c.scheduler.Lock() delete(c.pendingContainers, swarmID) c.scheduler.Unlock() return container, err }
// CreateContainer aka schedule a brand new container into the cluster. func (c *Cluster) CreateContainer(config *cluster.ContainerConfig, name string, authConfig *types.AuthConfig) (*cluster.Container, error) { poolUUID := os.Getenv("CX_POOL") log.Debug("CX: Adding label pool=" + poolUUID) config.Labels["pool"] = poolUUID container, err := c.createContainer(config, name, false, authConfig) if err != nil { var retries int64 // fails with image not found, then try to reschedule with image affinity // ENGINEAPIFIXME: The first error can be removed once dockerclient is removed bImageNotFoundError, _ := regexp.MatchString(`image \S* not found`, err.Error()) if (bImageNotFoundError || client.IsErrImageNotFound(err)) && !config.HaveNodeConstraint() { // Check if the image exists in the cluster // If exists, retry with an image affinity if c.Image(config.Image) != nil { container, err = c.createContainer(config, name, true, authConfig) retries++ } } for ; retries < c.createRetry && err != nil; retries++ { log.WithFields(log.Fields{"Name": "Swarm"}).Warnf("Failed to create container: %s, retrying", err) container, err = c.createContainer(config, name, false, authConfig) } } return container, err }
// CreateContainer aka schedule a brand new container into the cluster. func (c *Cluster) CreateContainer(config *cluster.ContainerConfig, name string) (*cluster.Container, error) { container, err := c.createContainer(config, name, false) // fails with image not found, then try to reschedule with soft-image-affinity if err != nil && strings.HasSuffix(err.Error(), "not found") && !config.HaveNodeConstraint() { // Check if the image exists in the cluster // If exists, retry with a soft-image-affinity if image := c.Image(config.Image); image != nil { container, err = c.createContainer(config, name, true) } } return container, err }
// CreateContainer aka schedule a brand new container into the cluster. func (c *Cluster) CreateContainer(config *cluster.ContainerConfig, name string, authConfig *dockerclient.AuthConfig) (*cluster.Container, error) { container, err := c.createContainer(config, name, false, authConfig) // fails with image not found, then try to reschedule with soft-image-affinity if err != nil { bImageNotFoundError, _ := regexp.MatchString(`image \S* not found`, err.Error()) if bImageNotFoundError && !config.HaveNodeConstraint() { // Check if the image exists in the cluster // If exists, retry with a soft-image-affinity if image := c.Image(config.Image); image != nil { container, err = c.createContainer(config, name, true, authConfig) } } } return container, err }
// CreateContainer aka schedule a brand new container into the cluster. func (c *Cluster) CreateContainer(config *cluster.ContainerConfig, name string, authConfig *dockerclient.AuthConfig) (*cluster.Container, error) { container, err := c.createContainer(config, name, false, authConfig) if err != nil { var retries int64 // fails with image not found, then try to reschedule with image affinity bImageNotFoundError, _ := regexp.MatchString(`image \S* not found`, err.Error()) if bImageNotFoundError && !config.HaveNodeConstraint() { // Check if the image exists in the cluster // If exists, retry with a image affinity if c.Image(config.Image) != nil { container, err = c.createContainer(config, name, true, authConfig) retries++ } } for ; retries < c.createRetry && err != nil; retries++ { log.WithFields(log.Fields{"Name": "Swarm"}).Warnf("Failed to create container: %s, retrying", err) container, err = c.createContainer(config, name, false, authConfig) } } return container, err }