Beispiel #1
0
// LaunchTask with specific offer and resources
func (core *Core) LaunchTask(task *registry.Task, offer *mesosproto.Offer, offers []*mesosproto.Offer) error {
	core.generateResource(task)
	resources := resource.BuildResources(task)

	log.Infof("Launch task %v, on node %v", task.ID, offer.GetHostname())
	taskInfo := &mesosproto.TaskInfo{}
	var err error
	if task.Type == registry.TaskTypeTest {
		taskInfo, err = core.CreateSingleTaskInfo(offer, resources, task)
		log.Debug(taskInfo)
	} else if task.Type == registry.TaskTypeBuild {
		taskInfo, err = core.CreateBuildImageTaskInfo(offer, resources, task)
	} else {
		return errors.New("Unknown task type received.")
	}

	if err != nil {
		return err
	}

	for _, value := range offers {
		if offer.GetSlaveId() == value.GetSlaveId() {
			if err := core.AcceptOffer(value, resources, taskInfo); err != nil {
				return err
			}
			core.deleteOffer(value)
			task.State = "TASK_STAGING"
		}
	}
	return nil
}
Beispiel #2
0
func (core *Core) deleteOffer(offer *mesosproto.Offer) {
	size := len(core.offers)
	for i := 0; i < size; i++ {
		if core.offers[i].GetId() == offer.GetId() {
			core.offers = append(core.offers[:i], core.offers[i+1:]...)
			break
		}
	}
}
Beispiel #3
0
func SlAMatch(task *registry.Task, offer *mesosproto.Offer) bool {
	for _, attribute := range offer.GetAttributes() {
		if attribute.GetName() == "SLATasks" {
			items := attribute.GetSet().GetItem()
			for _, item := range items {
				if item == task.Parse() {
					return false
				}
			}
			return true
		}
	}
	return true
}
Beispiel #4
0
// ResourcesMatch check if a offer fit task's resources
func ResourcesMatch(task *registry.Task, offer *mesosproto.Offer) bool {
	BuildBasicResources(task)
	for _, resource := range task.Resources {
		found := false
		for _, offerResource := range offer.GetResources() {
			if offerResource.GetName() == resource.GetName() {
				found = true
				if resource.GetType().String() == "SCALAR" {

					// check SCALAR type resource
					// resource.scalar.value should be greater than offerResource.scalar.value
					if offerResource.GetScalar().GetValue() < resource.GetScalar().GetValue() {
						return false
					}

				} else if resource.GetType().String() == "RANGES" {

					// check RANGES type resource
					// all ranges should be inside offerRanges
					// if not exist (exist == false) return false
					for _, taskRange := range resource.GetRanges().GetRange() {
						exists := false
						for _, offerRange := range offerResource.GetRanges().GetRange() {
							if RangeInside(offerRange, taskRange) {
								exists = true
								break
							}
						}
						if !exists {
							return false
						}
					}

				}
			}
		}

		// the node don't have this resource
		if !found {
			return false
		}

	}
	// all check pass
	return true
}
Beispiel #5
0
// ConstraintsMatch check if a offer fit task's constaints
func ConstraintsMatch(task *registry.Task, offer *mesosproto.Offer) bool {
	if !SlAMatch(task, offer) {
		return false
	}

	// check task attributes
	for _, attribute := range task.Attributes {
		found := false
		for _, offerAttribute := range offer.GetAttributes() {
			if offerAttribute.GetName() == attribute.GetName() {
				found = true
				break
			}
		}
		if !found {
			return false
		}
	}

	return true
}
Beispiel #6
0
// CreateSingleTaskInfo build single taskInfo for task
func (core *Core) CreateSingleTaskInfo(offer *mesosproto.Offer, resources []*mesosproto.Resource, task *registry.Task) (*mesosproto.TaskInfo, error) {
	portResources := []*mesosproto.Value_Range{}

	// Set the docker image if specified
	dockerInfo := &mesosproto.ContainerInfo_DockerInfo{
		Image: &task.DockerImage,
	}
	containerInfo := &mesosproto.ContainerInfo{
		Type:   mesosproto.ContainerInfo_DOCKER.Enum(),
		Docker: dockerInfo,
	}
	for _, volume := range task.Volumes {
		mode := mesosproto.Volume_RW
		if volume.Mode == "ro" {
			mode = mesosproto.Volume_RO
		}

		containerInfo.Volumes = append(containerInfo.Volumes, &mesosproto.Volume{
			ContainerPath: &volume.ContainerPath,
			HostPath:      &volume.HostPath,
			Mode:          &mode,
		})
	}

	for _, port := range task.Ports {
		if port.HostPort == 0 {
			port.HostPort = resource.GeneratePort(offer.GetResources())
		}

		dockerInfo.PortMappings = append(dockerInfo.PortMappings, &mesosproto.ContainerInfo_DockerInfo_PortMapping{
			ContainerPort: &port.ContainerPort,
			HostPort:      &port.HostPort,
		})
		portResources = append(portResources, &mesosproto.Value_Range{
			Begin: proto.Uint64(uint64(port.HostPort)),
			End:   proto.Uint64(uint64(port.HostPort)),
		})
	}

	if len(task.Ports) > 0 {
		// port mapping only works in bridge mode
		dockerInfo.Network = mesosproto.ContainerInfo_DockerInfo_BRIDGE.Enum()
	} else if len(task.NetworkMode) > 0 {
		if task.NetworkMode == registry.NetworkModeBridge {
			dockerInfo.Network = mesosproto.ContainerInfo_DockerInfo_BRIDGE.Enum()
		} else if task.NetworkMode == registry.NetworkModeHost {
			dockerInfo.Network = mesosproto.ContainerInfo_DockerInfo_HOST.Enum()
		} else if task.NetworkMode == registry.NetworkModeNone {
			dockerInfo.Network = mesosproto.ContainerInfo_DockerInfo_NONE.Enum()
		}
	}

	commandInfo := &mesosproto.CommandInfo{
		Shell: proto.Bool(false),
	}
	if len(task.Arguments) > 0 {
		for _, argument := range task.Arguments {
			commandInfo.Arguments = append(commandInfo.Arguments, argument)
		}
	}

	if len(task.Ports) > 0 {
		resources = append(resources,
			&mesosproto.Resource{
				Name:   proto.String("ports"),
				Ranges: &mesosproto.Value_Ranges{Range: portResources},
				Type:   mesosproto.Value_RANGES.Enum(),
			},
		)
	}

	taskInfo := &mesosproto.TaskInfo{
		Name:      proto.String(fmt.Sprintf("test-%s", task.ID)),
		TaskId:    &mesosproto.TaskID{Value: &task.ID},
		SlaveId:   offer.SlaveId,
		Container: containerInfo,
		Command:   commandInfo,
		Resources: resources,
	}

	// Set value only if provided
	commands := strings.Split(task.Command, " ")
	if commands[0] != "" {
		taskInfo.Command.Value = &commands[0]
	}

	// Set args only if they exist
	if len(commands) > 1 {
		taskInfo.Command.Arguments = commands[1:]
	}

	return taskInfo, nil
}