| @@ -3,6 +3,7 @@ package cloudbrain | |||
| import ( | |||
| "encoding/json" | |||
| "errors" | |||
| "os" | |||
| "strconv" | |||
| "code.gitea.io/gitea/modules/timeutil" | |||
| @@ -567,3 +568,43 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e | |||
| return nil | |||
| } | |||
| func DelCloudBrainJob(jobId string) string { | |||
| task, err := models.GetCloudbrainByJobID(jobId) | |||
| if err != nil { | |||
| log.Error("get cloud brain err:", err) | |||
| return "cloudbrain.Delete_failed" | |||
| } | |||
| if task.Status != string(models.JobStopped) && task.Status != string(models.JobFailed) && task.Status != string(models.JobSucceeded) { | |||
| log.Error("the job(%s) has not been stopped", task.JobName) | |||
| return "cloudbrain.Not_Stopped" | |||
| } | |||
| err = models.DeleteJob(task) | |||
| if err != nil { | |||
| log.Error("DeleteJob failed:", err) | |||
| return "cloudbrain.Delete_failed" | |||
| } | |||
| deleteJobStorage(task.JobName) | |||
| return "" | |||
| } | |||
| func deleteJobStorage(jobName string) error { | |||
| //delete local | |||
| localJobPath := setting.JobPath + jobName | |||
| err := os.RemoveAll(localJobPath) | |||
| if err != nil { | |||
| log.Error("RemoveAll(%s) failed:%v", localJobPath, err) | |||
| } | |||
| dirPath := setting.CBCodePathPrefix + jobName + "/" | |||
| err = storage.Attachments.DeleteDir(dirPath) | |||
| if err != nil { | |||
| log.Error("DeleteDir(%s) failed:%v", localJobPath, err) | |||
| } | |||
| return nil | |||
| } | |||
| @@ -3081,4 +3081,7 @@ INFERENCE = INFERENCE | |||
| BENCHMARK = BENCHMARK | |||
| brain_area = Brain Area | |||
| error.dataset_select = dataset select error:the count exceed the limit or has same name | |||
| Delete_failed=Fail to delete, please try again later. | |||
| Not_Stopped=The job is not stopped, can not be deleted. | |||
| error.dataset_select = dataset select error:the count exceed the limit or has same name | |||
| @@ -3095,4 +3095,7 @@ INFERENCE = 推理任务 | |||
| BENCHMARK = 评测任务 | |||
| brain_area = 脑区 | |||
| error.dataset_select = 数据集选择错误:数量超过限制或者有同名数据集 | |||
| Delete_failed=删除失败,请稍后再试。 | |||
| Not_Stopped=任务还未终止,不能删除。 | |||
| error.dataset_select = 数据集选择错误:数量超过限制或者有同名数据集 | |||
| @@ -921,6 +921,13 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Post("/stop_version", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo_ext.CloudBrainStop) | |||
| }) | |||
| }) | |||
| m.Group("/inference-job", func() { | |||
| m.Group("/:jobid", func() { | |||
| m.Get("", repo.GetCloudBrainInferenceJob) | |||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.DelCloudBrainJob) | |||
| m.Get("/result_list", repo.InferencJobResultList) | |||
| }) | |||
| }) | |||
| }, reqRepoReader(models.UnitTypeCloudBrain)) | |||
| m.Group("/modelarts", func() { | |||
| m.Group("/notebook", func() { | |||
| @@ -100,6 +100,114 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||
| } | |||
| func GetCloudBrainInferenceJob(ctx *context.APIContext) { | |||
| jobID := ctx.Params(":jobid") | |||
| job, err := models.GetCloudbrainByJobID(jobID) | |||
| if err != nil { | |||
| ctx.NotFound(err) | |||
| return | |||
| } | |||
| jobResult, err := cloudbrain.GetJob(job.JobID) | |||
| if err != nil { | |||
| ctx.NotFound(err) | |||
| log.Error("GetJob failed:", err) | |||
| return | |||
| } | |||
| result, err := models.ConvertToJobResultPayload(jobResult.Payload) | |||
| if err != nil { | |||
| ctx.NotFound(err) | |||
| log.Error("ConvertToJobResultPayload failed:", err) | |||
| return | |||
| } | |||
| job.Status = result.JobStatus.State | |||
| if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { | |||
| taskRoles := result.TaskRoles | |||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||
| job.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | |||
| job.ContainerID = taskRes.TaskStatuses[0].ContainerID | |||
| job.Status = taskRes.TaskStatuses[0].State | |||
| } | |||
| if result.JobStatus.State != string(models.JobWaiting) { | |||
| models.ParseAndSetDurationFromCloudBrainOne(result, job) | |||
| err = models.UpdateJob(job) | |||
| if err != nil { | |||
| log.Error("UpdateJob failed:", err) | |||
| } | |||
| } | |||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
| "JobID": jobID, | |||
| "JobStatus": job.Status, | |||
| "JobDuration": job.TrainJobDuration, | |||
| }) | |||
| } | |||
| func DelCloudBrainJob(ctx *context.APIContext) { | |||
| jobID := ctx.Params(":jobid") | |||
| errStr := cloudbrain.DelCloudBrainJob(jobID) | |||
| if errStr != "" { | |||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr(errStr))) | |||
| } else { | |||
| ctx.JSON(http.StatusOK, models.BaseOKMessage) | |||
| } | |||
| } | |||
| func InferencJobResultList(ctx *context.APIContext) { | |||
| jobID := ctx.Params(":jobid") | |||
| parentDir := ctx.Query("parentDir") | |||
| dirArray := strings.Split(parentDir, "/") | |||
| task, err := models.GetCloudbrainByJobID(jobID) | |||
| if err != nil { | |||
| log.Error("get cloud brain err:", err) | |||
| ctx.ServerError("get cloud brain information failed:", err) | |||
| } | |||
| //get dirs | |||
| dirs, err := routerRepo.GetResultDirs(task.JobName, parentDir) | |||
| if err != nil { | |||
| log.Error("GetModelDirs failed:%v", err.Error(), ctx.Data["msgID"]) | |||
| ctx.ServerError("GetModelDirs failed:", err) | |||
| return | |||
| } | |||
| var fileInfos []storage.FileInfo | |||
| err = json.Unmarshal([]byte(dirs), &fileInfos) | |||
| if err != nil { | |||
| log.Error("json.Unmarshal failed:%v", err.Error(), ctx.Data["msgID"]) | |||
| ctx.ServerError("json.Unmarshal failed:", err) | |||
| return | |||
| } | |||
| for i, fileInfo := range fileInfos { | |||
| temp, _ := time.Parse("2006-01-02 15:04:05", fileInfo.ModTime) | |||
| fileInfos[i].ModTime = temp.Local().Format("2006-01-02 15:04:05") | |||
| } | |||
| sort.Slice(fileInfos, func(i, j int) bool { | |||
| return fileInfos[i].ModTime > fileInfos[j].ModTime | |||
| }) | |||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
| "JobID": jobID, | |||
| "StatusOK": 0, | |||
| "Path": dirArray, | |||
| "Dirs": fileInfos, | |||
| "task": task, | |||
| "PageIsCloudBrain": true, | |||
| }) | |||
| } | |||
| func CloudbrainGetLog(ctx *context.Context) { | |||
| ID := ctx.Params(":id") | |||
| job, err := models.GetCloudbrainByID(ID) | |||
| @@ -1292,6 +1292,18 @@ func GetModelDirs(jobName string, parentDir string) (string, error) { | |||
| return getDirs(req) | |||
| } | |||
| func GetResultDirs(jobName string, parentDir string) (string, error) { | |||
| var req string | |||
| modelActualPath := storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/") | |||
| if parentDir == "" { | |||
| req = "baseDir=" + modelActualPath | |||
| } else { | |||
| req = "baseDir=" + modelActualPath + "&parentDir=" + parentDir | |||
| } | |||
| return getDirs(req) | |||
| } | |||
| func CloudBrainDownloadModel(ctx *context.Context) { | |||
| parentDir := ctx.Query("parentDir") | |||
| fileName := ctx.Query("fileName") | |||