func (core *Core) StartJob(job *registry.Job) error { log.Infof("Starting job: %v", job.ID) if job.Image == "" && job.ContextDir == "" { return errors.New("Start job error: image, context_dir cannot be nil at the same time") } job.StartTime = time.Now().UnixNano() if job.ContextDir != "" { core.BuildImage(job) } // TODO split input job.Status = registry.StatusRunning core.RunTask(job) return nil }
func (core *Core) BuildImage(job *registry.Job) error { // Build Images before run test task // TaskID: build-{JobID}-{randID}-{NumberOfScale} log.Infof("Create task for job(%v) to build image", job.ID) job.Image = "image-" + job.ID for index := 1; index <= job.BuildNodeNumber(); index++ { task := ®istry.Task{ Cpus: BuildCPU, Mem: BuildMem, ID: "build-" + job.ID + "-" + strconv.Itoa(index), Name: job.Name, Type: registry.TaskTypeBuild, CreateTime: time.Now().UnixNano(), JobID: job.ID, State: "TASK_WAITING", SLA: registry.SLAOnePerNode, } err := core.AddTask(task.ID, task) job.PushTask(task) if err != nil { log.Errorf("Error when add %d build image task: %v", index, err) task.State = "TASK_FAILED" job.PopLastTask() continue } } return nil }
// CollectResult collect result for task func (core *Core) CollectResult(job *registry.Job, task *registry.Task) { taskInstance := ®istry.Task{ Cpus: CollectCPU, Mem: CollectMem, ID: "collect-" + job.ID + "-" + task.ID, Name: job.Name, Type: registry.TaskTypeBuild, CreateTime: time.Now().UnixNano(), JobID: job.ID, State: "TASK_WAITING", SLA: registry.SLAOnePerNode, Directory: task.Directory, } err := core.AddTask(taskInstance.ID, taskInstance) job.PushTask(taskInstance) if err != nil { log.Errorf("Error when add %d result collector: %v", err) task.State = "TASK_FAILED" job.PopLastTask() } }
func (core *Core) addTask(job *registry.Job, scale int, inputs []string) { for _, task := range job.Tasks { randID, err := utils.Encode(6) if err != nil { log.Errorf("Error when generate id to task %s of job %v", task.ID, job.ID) continue } if task.Scale <= 0 { task.Scale = 1 } if scale == 0 { scale = task.Scale } job.TotalTaskLen = scale for index := 1; index <= scale; index++ { // To avoid use same pointer of ports // Instantiate a new array var ports []*registry.Port for _, port := range task.Ports { ports = append(ports, ®istry.Port{ ContainerPort: port.ContainerPort, HostPort: port.HostPort, }) } taskInstance := ®istry.Task{ JobID: job.ID, ID: "task-" + job.ID + "-" + randID + "-" + strconv.Itoa(index), Name: job.Name, DockerImage: job.Image, Cpus: task.Cpus, Mem: task.Mem, Disk: task.Disk, Ports: ports, Command: task.Command, Volumes: task.Volumes, Resources: task.Resources, Attributes: task.Attributes, CreateTime: time.Now().UnixNano(), Type: registry.TaskTypeTest, State: "TASK_WAITING", } // mount input path if len(inputs) > 0 { taskInstance.Volumes = append(taskInstance.Volumes, ®istry.Volume{ HostPath: fs.NormalizePath(inputs[index-1]), ContainerPath: "/input", }) } // mount work directory taskInstance.Volumes = append(taskInstance.Volumes, ®istry.Volume{ HostPath: fs.NormalizePath(job.WorkDirectory), ContainerPath: "/workspace", }) // mount output taskInstance.Volumes = append(taskInstance.Volumes, ®istry.Volume{ HostPath: fs.NormalizePath(job.OutputPath), ContainerPath: "/output", }) // if task was build from dockerfile // add attribute to task if job.ContextDir != "" { taskInstance.Attributes = append(task.Attributes, &mesosproto.Attribute{ Name: proto.String("Image"), Text: &mesosproto.Value_Text{ Value: proto.String(job.Image), }, }) } // TODO bugfix: task point to one pointer var taskArguments []string for _, arg := range task.Arguments { taskArguments = append(taskArguments, arg) } taskInstance.Arguments = taskArguments err = core.AddTask(taskInstance.ID, taskInstance) job.PushTask(taskInstance) if err != nil { task.State = "TASK_FAILED" log.Errorf("Error when running task %v: %v", task.ID, err) job.PopLastTask() continue } } } }