diff --git a/cluster/mesos/cluster.go b/cluster/mesos/cluster.go index 43673156d9..c9520f0389 100644 --- a/cluster/mesos/cluster.go +++ b/cluster/mesos/cluster.go @@ -413,7 +413,6 @@ func (c *Cluster) scheduleTask(t *task) bool { } // build the offer from it's internal config and set the slaveID - t.build(n.ID) c.Lock() // TODO: Only use the offer we need @@ -422,6 +421,8 @@ func (c *Cluster) scheduleTask(t *task) bool { offerIDs = append(offerIDs, offer.Id) } + t.build(n.ID, c.slaves[n.ID].offers) + if _, err := c.driver.LaunchTasks(offerIDs, []*mesosproto.TaskInfo{&t.TaskInfo}, &mesosproto.Filters{}); err != nil { // TODO: Do not erase all the offers, only the one used for _, offer := range s.offers { diff --git a/cluster/mesos/task.go b/cluster/mesos/task.go index 6f9242138d..0f194ab44a 100644 --- a/cluster/mesos/task.go +++ b/cluster/mesos/task.go @@ -34,7 +34,7 @@ func (t *task) Do() bool { return t.cluster.scheduleTask(t) } -func (t *task) build(slaveID string) { +func (t *task) build(slaveID string, offers map[string]*mesosproto.Offer) { t.Command = &mesosproto.CommandInfo{Shell: proto.Bool(false)} t.Container = &mesosproto.ContainerInfo{ @@ -56,22 +56,40 @@ func (t *task) build(slaveID string) { t.Container.Docker.Network = mesosproto.ContainerInfo_DockerInfo_NONE.Enum() case "host": t.Container.Docker.Network = mesosproto.ContainerInfo_DockerInfo_HOST.Enum() - case "bridge", "": - for containerPort, bindings := range t.config.HostConfig.PortBindings { + case "default", "bridge", "": + var ports []uint64 + + for _, offer := range offers { + ports = append(ports, getPorts(offer)...) + } + + for containerProtoPort, bindings := range t.config.HostConfig.PortBindings { for _, binding := range bindings { - fmt.Println(containerPort) - containerInfo := strings.SplitN(containerPort, "/", 2) - fmt.Println(containerInfo[0], containerInfo[1]) + containerInfo := strings.SplitN(containerProtoPort, "/", 2) containerPort, err := strconv.ParseUint(containerInfo[0], 10, 32) if err != nil { log.Warn(err) continue } - hostPort, err := strconv.ParseUint(binding.HostPort, 10, 32) - if err != nil { - log.Warn(err) + + var hostPort uint64 + + if binding.HostPort != "" { + hostPort, err = strconv.ParseUint(binding.HostPort, 10, 32) + if err != nil { + log.Warn(err) + continue + } + } else if len(ports) > 0 { + hostPort = ports[0] + ports = ports[1:] + } + + if hostPort == 0 { + log.Warn("cannot find port to bind on the host") continue } + protocol := "tcp" if len(containerInfo) == 2 { protocol = containerInfo[1] diff --git a/cluster/mesos/task_test.go b/cluster/mesos/task_test.go index b6257bfb15..86d82b7e79 100644 --- a/cluster/mesos/task_test.go +++ b/cluster/mesos/task_test.go @@ -23,7 +23,7 @@ func TestBuild(t *testing.T) { }), name) assert.NoError(t, err) - task.build("slave-id") + task.build("slave-id", nil) assert.Equal(t, task.Container.GetType(), mesosproto.ContainerInfo_DOCKER) assert.Equal(t, task.Container.Docker.GetImage(), "test-image") diff --git a/cluster/mesos/utils.go b/cluster/mesos/utils.go index bcdcddda1d..fabb68b74e 100644 --- a/cluster/mesos/utils.go +++ b/cluster/mesos/utils.go @@ -37,3 +37,16 @@ func sumScalarResourceValue(offers map[string]*mesosproto.Offer, name string) fl } return value } + +func getPorts(offer *mesosproto.Offer) (ports []uint64) { + for _, resource := range offer.Resources { + if resource.GetName() == "ports" { + for _, rang := range resource.GetRanges().GetRange() { + for i := rang.GetBegin(); i <= rang.GetEnd(); i++ { + ports = append(ports, i) + } + } + } + } + return ports +}