| @@ -87,6 +87,8 @@ GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/integrations/migration-test,$(fi | |||||
| WEBPACK_SOURCES := $(shell find web_src/js web_src/less -type f) | WEBPACK_SOURCES := $(shell find web_src/js web_src/less -type f) | ||||
| WEBPACK_CONFIGS := webpack.config.js | WEBPACK_CONFIGS := webpack.config.js | ||||
| WEBPACK_CONFIGS_TMP := webpack_temp.config.js | |||||
| WEBPACK_CONFIGS_PRO := webpack_pro.config.js | |||||
| WEBPACK_DEST := public/js/index.js public/css/index.css | WEBPACK_DEST := public/js/index.js public/css/index.css | ||||
| WEBPACK_DEST_DIRS := public/js public/css public/fonts | WEBPACK_DEST_DIRS := public/js public/css public/fonts | ||||
| @@ -290,7 +292,7 @@ lint-backend: golangci-lint revive vet swagger-check swagger-validate test-vendo | |||||
| .PHONY: lint-frontend | .PHONY: lint-frontend | ||||
| lint-frontend: node_modules | lint-frontend: node_modules | ||||
| npx eslint web_src/js webpack.config.js | |||||
| npx eslint web_src/js $(WEBPACK_CONFIGS) | |||||
| npx stylelint web_src/less | npx stylelint web_src/less | ||||
| .PHONY: watch-frontend | .PHONY: watch-frontend | ||||
| @@ -504,7 +506,7 @@ install: $(wildcard *.go) | |||||
| build: frontend backend | build: frontend backend | ||||
| .PHONY: frontend | .PHONY: frontend | ||||
| frontend: node-check $(FOMANTIC_DEST) $(WEBPACK_DEST) | |||||
| frontend: node-check webpack_prepare $(FOMANTIC_DEST) $(WEBPACK_DEST) webpack_end | |||||
| .PHONY: backend | .PHONY: backend | ||||
| backend: go-check generate $(EXECUTABLE) | backend: go-check generate $(EXECUTABLE) | ||||
| @@ -596,6 +598,19 @@ $(FOMANTIC_DEST): $(FOMANTIC_CONFIGS) package-lock.json | node_modules | |||||
| .PHONY: webpack | .PHONY: webpack | ||||
| webpack: $(WEBPACK_DEST) | webpack: $(WEBPACK_DEST) | ||||
| webpack_prepare: | |||||
| if [ $(filter bindata,$(TAGS_SPLIT))x = "bindata"x ]; then \ | |||||
| echo "prepare"; \ | |||||
| cp $(WEBPACK_CONFIGS) $(WEBPACK_CONFIGS_TMP); \ | |||||
| cp $(WEBPACK_CONFIGS_PRO) $(WEBPACK_CONFIGS); \ | |||||
| fi | |||||
| webpack_end: | |||||
| if [ $(filter bindata,$(TAGS_SPLIT))x = "bindata"x ]; then \ | |||||
| echo "end"; \ | |||||
| mv $(WEBPACK_CONFIGS_TMP) $(WEBPACK_CONFIGS); \ | |||||
| fi | |||||
| $(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json | node_modules | $(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json | node_modules | ||||
| rm -rf $(WEBPACK_DEST_DIRS) | rm -rf $(WEBPACK_DEST_DIRS) | ||||
| @@ -3,6 +3,7 @@ package models | |||||
| import ( | import ( | ||||
| "encoding/json" | "encoding/json" | ||||
| "fmt" | "fmt" | ||||
| "strconv" | |||||
| "strings" | "strings" | ||||
| "time" | "time" | ||||
| @@ -92,9 +93,10 @@ type Cloudbrain struct { | |||||
| JobID string `xorm:"INDEX NOT NULL"` | JobID string `xorm:"INDEX NOT NULL"` | ||||
| JobType string `xorm:"INDEX NOT NULL DEFAULT 'DEBUG'"` | JobType string `xorm:"INDEX NOT NULL DEFAULT 'DEBUG'"` | ||||
| JobName string | JobName string | ||||
| DisplayJobName string | |||||
| Status string | Status string | ||||
| UserID int64 | |||||
| RepoID int64 | |||||
| UserID int64 `xorm:"INDEX NOT NULL"` | |||||
| RepoID int64 `xorm:"INDEX NOT NULL"` | |||||
| SubTaskName string | SubTaskName string | ||||
| ContainerID string | ContainerID string | ||||
| ContainerIp string | ContainerIp string | ||||
| @@ -1198,7 +1200,7 @@ func QueryModelTrainJobList(repoId int64) ([]*CloudbrainInfo, int, error) { | |||||
| ) | ) | ||||
| cloudbrains := make([]*CloudbrainInfo, 0) | cloudbrains := make([]*CloudbrainInfo, 0) | ||||
| if err := sess.Select("job_id,job_name").Table(&Cloudbrain{}).Where(cond).OrderBy("created_unix DESC"). | |||||
| if err := sess.Select("job_id,display_job_name").Table(&Cloudbrain{}).Where(cond).OrderBy("created_unix DESC"). | |||||
| Find(&cloudbrains); err != nil { | Find(&cloudbrains); err != nil { | ||||
| return nil, 0, fmt.Errorf("Find: %v", err) | return nil, 0, fmt.Errorf("Find: %v", err) | ||||
| } | } | ||||
| @@ -1207,7 +1209,7 @@ func QueryModelTrainJobList(repoId int64) ([]*CloudbrainInfo, int, error) { | |||||
| uniqueElements := make([]*CloudbrainInfo, 0) | uniqueElements := make([]*CloudbrainInfo, 0) | ||||
| for _, entry := range cloudbrains { | for _, entry := range cloudbrains { | ||||
| if _, value := keys[entry.JobID]; !value { | if _, value := keys[entry.JobID]; !value { | ||||
| keys[entry.JobID] = entry.JobName | |||||
| keys[entry.JobID] = entry.DisplayJobName | |||||
| uniqueElements = append(uniqueElements, entry) | uniqueElements = append(uniqueElements, entry) | ||||
| } | } | ||||
| } | } | ||||
| @@ -1307,6 +1309,12 @@ func GetCloudbrainByJobID(jobID string) (*Cloudbrain, error) { | |||||
| return getRepoCloudBrain(cb) | return getRepoCloudBrain(cb) | ||||
| } | } | ||||
| func GetCloudbrainByID(id string) (*Cloudbrain, error) { | |||||
| idInt64, _ := strconv.ParseInt(id, 10, 64) | |||||
| cb := &Cloudbrain{ID: idInt64} | |||||
| return getRepoCloudBrain(cb) | |||||
| } | |||||
| func GetCloudbrainByJobIDAndVersionName(jobID string, versionName string) (*Cloudbrain, error) { | func GetCloudbrainByJobIDAndVersionName(jobID string, versionName string) (*Cloudbrain, error) { | ||||
| cb := &Cloudbrain{JobID: jobID, VersionName: versionName} | cb := &Cloudbrain{JobID: jobID, VersionName: versionName} | ||||
| return getRepoCloudBrain(cb) | return getRepoCloudBrain(cb) | ||||
| @@ -1329,6 +1337,12 @@ func GetCloudbrainsNeededStopByRepoID(repoID int64) ([]*Cloudbrain, error) { | |||||
| return cloudBrains, err | return cloudBrains, err | ||||
| } | } | ||||
| func GetCloudbrainsByDisplayJobName(repoID int64, jobType string, displayJobName string) ([]*Cloudbrain, error) { | |||||
| cloudBrains := make([]*Cloudbrain, 0) | |||||
| err := x.Cols("job_id", "job_name", "repo_id", "user_id", "job_type", "display_job_name").Where("repo_id=? AND job_type =? AND lower(display_job_name) = lower(?)", repoID, jobType, displayJobName).Find(&cloudBrains) | |||||
| return cloudBrains, err | |||||
| } | |||||
| func SetCloudbrainStatusByJobID(jobID string, status CloudbrainStatus) (err error) { | func SetCloudbrainStatusByJobID(jobID string, status CloudbrainStatus) (err error) { | ||||
| cb := &Cloudbrain{JobID: jobID, Status: string(status)} | cb := &Cloudbrain{JobID: jobID, Status: string(status)} | ||||
| _, err = x.Cols("status").Where("cloudbrain.job_id=?", jobID).Update(cb) | _, err = x.Cols("status").Where("cloudbrain.job_id=?", jobID).Update(cb) | ||||
| @@ -7,6 +7,7 @@ import ( | |||||
| type CreateCloudBrainForm struct { | type CreateCloudBrainForm struct { | ||||
| JobName string `form:"job_name" binding:"Required"` | JobName string `form:"job_name" binding:"Required"` | ||||
| DisplayJobName string `form:"display_job_name" binding:"Required"` | |||||
| Image string `form:"image" binding:"Required"` | Image string `form:"image" binding:"Required"` | ||||
| Command string `form:"command" binding:"Required"` | Command string `form:"command" binding:"Required"` | ||||
| Attachment string `form:"attachment" binding:"Required"` | Attachment string `form:"attachment" binding:"Required"` | ||||
| @@ -16,11 +16,12 @@ func (f *CreateModelArtsForm) Validate(ctx *macaron.Context, errs binding.Errors | |||||
| } | } | ||||
| type CreateModelArtsNotebookForm struct { | type CreateModelArtsNotebookForm struct { | ||||
| JobName string `form:"job_name" binding:"Required"` | |||||
| Attachment string `form:"attachment"` | |||||
| Description string `form:"description"` | |||||
| Flavor string `form:"flavor" binding:"Required"` | |||||
| ImageId string `form:"image_id" binding:"Required"` | |||||
| DisplayJobName string `form:"display_job_name" binding:"Required"` | |||||
| JobName string `form:"job_name" binding:"Required"` | |||||
| Attachment string `form:"attachment"` | |||||
| Description string `form:"description"` | |||||
| Flavor string `form:"flavor" binding:"Required"` | |||||
| ImageId string `form:"image_id" binding:"Required"` | |||||
| } | } | ||||
| func (f *CreateModelArtsNotebookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *CreateModelArtsNotebookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
| @@ -28,6 +29,7 @@ func (f *CreateModelArtsNotebookForm) Validate(ctx *macaron.Context, errs bindin | |||||
| } | } | ||||
| type CreateModelArtsTrainJobForm struct { | type CreateModelArtsTrainJobForm struct { | ||||
| DisplayJobName string `form:"display_job_name" binding:"Required"` | |||||
| JobName string `form:"job_name" binding:"Required"` | JobName string `form:"job_name" binding:"Required"` | ||||
| Attachment string `form:"attachment" binding:"Required"` | Attachment string `form:"attachment" binding:"Required"` | ||||
| BootFile string `form:"boot_file" binding:"Required"` | BootFile string `form:"boot_file" binding:"Required"` | ||||
| @@ -47,6 +49,7 @@ type CreateModelArtsTrainJobForm struct { | |||||
| } | } | ||||
| type CreateModelArtsInferenceJobForm struct { | type CreateModelArtsInferenceJobForm struct { | ||||
| DisplayJobName string `form:"display_job_name" binding:"Required"` | |||||
| JobName string `form:"job_name" binding:"Required"` | JobName string `form:"job_name" binding:"Required"` | ||||
| Attachment string `form:"attachment" binding:"Required"` | Attachment string `form:"attachment" binding:"Required"` | ||||
| BootFile string `form:"boot_file" binding:"Required"` | BootFile string `form:"boot_file" binding:"Required"` | ||||
| @@ -85,30 +85,69 @@ func isAdminOrJobCreater(ctx *context.Context, job *models.Cloudbrain, err error | |||||
| func AdminOrOwnerOrJobCreaterRight(ctx *context.Context) { | func AdminOrOwnerOrJobCreaterRight(ctx *context.Context) { | ||||
| var jobID = ctx.Params(":jobid") | |||||
| var ID = ctx.Params(":id") | |||||
| job, err := models.GetCloudbrainByID(ID) | |||||
| if err != nil { | |||||
| log.Error("GetCloudbrainByID failed:%v", err.Error()) | |||||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||||
| } | |||||
| ctx.Cloudbrain = job | |||||
| if !isAdminOrOwnerOrJobCreater(ctx, job, err) { | |||||
| log.Error("!isAdminOrOwnerOrJobCreater error:%v", err.Error()) | |||||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||||
| } | |||||
| } | |||||
| func AdminOrJobCreaterRight(ctx *context.Context) { | |||||
| var ID = ctx.Params(":id") | |||||
| job, err := models.GetCloudbrainByID(ID) | |||||
| if err != nil { | |||||
| log.Error("GetCloudbrainByID failed:%v", err.Error()) | |||||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||||
| } | |||||
| ctx.Cloudbrain = job | |||||
| if !isAdminOrJobCreater(ctx, job, err) { | |||||
| log.Error("!isAdminOrJobCreater error:%v", err.Error()) | |||||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||||
| } | |||||
| } | |||||
| func AdminOrOwnerOrJobCreaterRightForTrain(ctx *context.Context) { | |||||
| var jobID = ctx.Params(":jobid") | |||||
| job, err := models.GetCloudbrainByJobID(jobID) | job, err := models.GetCloudbrainByJobID(jobID) | ||||
| if err != nil { | |||||
| log.Error("GetCloudbrainByJobID failed:%v", err.Error()) | |||||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||||
| } | |||||
| ctx.Cloudbrain = job | ctx.Cloudbrain = job | ||||
| if !isAdminOrOwnerOrJobCreater(ctx, job, err) { | if !isAdminOrOwnerOrJobCreater(ctx, job, err) { | ||||
| log.Error("!isAdminOrOwnerOrJobCreater failed:%v", err.Error()) | |||||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | ||||
| } | } | ||||
| } | } | ||||
| func AdminOrJobCreaterRight(ctx *context.Context) { | |||||
| func AdminOrJobCreaterRightForTrain(ctx *context.Context) { | |||||
| var jobID = ctx.Params(":jobid") | var jobID = ctx.Params(":jobid") | ||||
| job, err := models.GetCloudbrainByJobID(jobID) | job, err := models.GetCloudbrainByJobID(jobID) | ||||
| if err != nil { | |||||
| log.Error("GetCloudbrainByJobID failed:%v", err.Error()) | |||||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||||
| } | |||||
| ctx.Cloudbrain = job | ctx.Cloudbrain = job | ||||
| if !isAdminOrJobCreater(ctx, job, err) { | if !isAdminOrJobCreater(ctx, job, err) { | ||||
| log.Error("!isAdminOrJobCreater errot:%v", err.Error()) | |||||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | ||||
| } | } | ||||
| } | } | ||||
| func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, brainScorePath, jobType, gpuQueue, description string, benchmarkTypeID, benchmarkChildTypeID, resourceSpecId int) error { | |||||
| func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, brainScorePath, jobType, gpuQueue, description string, benchmarkTypeID, benchmarkChildTypeID, resourceSpecId int) error { | |||||
| dataActualPath := setting.Attachment.Minio.RealPath + | dataActualPath := setting.Attachment.Minio.RealPath + | ||||
| setting.Attachment.Minio.Bucket + "/" + | setting.Attachment.Minio.Bucket + "/" + | ||||
| setting.Attachment.Minio.BasePath + | setting.Attachment.Minio.BasePath + | ||||
| @@ -212,6 +251,7 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, | |||||
| RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
| JobID: jobID, | JobID: jobID, | ||||
| JobName: jobName, | JobName: jobName, | ||||
| DisplayJobName: displayJobName, | |||||
| SubTaskName: SubTaskName, | SubTaskName: SubTaskName, | ||||
| JobType: jobType, | JobType: jobType, | ||||
| Type: models.TypeCloudBrainOne, | Type: models.TypeCloudBrainOne, | ||||
| @@ -229,16 +269,23 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, | |||||
| return err | return err | ||||
| } | } | ||||
| task, err := models.GetCloudbrainByName(jobName) | |||||
| if err != nil { | |||||
| log.Error("GetCloudbrainByName failed: %v", err.Error()) | |||||
| return err | |||||
| } | |||||
| stringId := strconv.FormatInt(task.ID, 10) | |||||
| if string(models.JobTypeBenchmark) == jobType { | if string(models.JobTypeBenchmark) == jobType { | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, jobName, models.ActionCreateBenchMarkTask) | |||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateBenchMarkTask) | |||||
| } else { | } else { | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, jobName, models.ActionCreateDebugGPUTask) | |||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugGPUTask) | |||||
| } | } | ||||
| return nil | return nil | ||||
| } | } | ||||
| func RestartTask(ctx *context.Context, task *models.Cloudbrain, newJobID *string) error { | |||||
| func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) error { | |||||
| dataActualPath := setting.Attachment.Minio.RealPath + | dataActualPath := setting.Attachment.Minio.RealPath + | ||||
| setting.Attachment.Minio.Bucket + "/" + | setting.Attachment.Minio.Bucket + "/" + | ||||
| setting.Attachment.Minio.BasePath + | setting.Attachment.Minio.BasePath + | ||||
| @@ -343,6 +390,7 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newJobID *string | |||||
| RepoID: task.RepoID, | RepoID: task.RepoID, | ||||
| JobID: jobID, | JobID: jobID, | ||||
| JobName: task.JobName, | JobName: task.JobName, | ||||
| DisplayJobName: task.DisplayJobName, | |||||
| SubTaskName: task.SubTaskName, | SubTaskName: task.SubTaskName, | ||||
| JobType: task.JobType, | JobType: task.JobType, | ||||
| Type: task.Type, | Type: task.Type, | ||||
| @@ -359,7 +407,8 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newJobID *string | |||||
| return err | return err | ||||
| } | } | ||||
| *newJobID = jobID | |||||
| idString := strconv.FormatInt(newTask.ID, 10) | |||||
| *newID = idString | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -70,6 +70,7 @@ var ( | |||||
| type GenerateTrainJobReq struct { | type GenerateTrainJobReq struct { | ||||
| JobName string | JobName string | ||||
| DisplayJobName string | |||||
| Uuid string | Uuid string | ||||
| Description string | Description string | ||||
| CodeObsPath string | CodeObsPath string | ||||
| @@ -95,33 +96,9 @@ type GenerateTrainJobReq struct { | |||||
| TotalVersionCount int | TotalVersionCount int | ||||
| } | } | ||||
| type GenerateTrainJobVersionReq struct { | |||||
| JobName string | |||||
| Uuid string | |||||
| Description string | |||||
| CodeObsPath string | |||||
| BootFile string | |||||
| BootFileUrl string | |||||
| DataUrl string | |||||
| TrainUrl string | |||||
| FlavorCode string | |||||
| LogUrl string | |||||
| PoolID string | |||||
| WorkServerNumber int | |||||
| EngineID int64 | |||||
| Parameters []models.Parameter | |||||
| Params string | |||||
| PreVersionId int64 | |||||
| CommitID string | |||||
| BranchName string | |||||
| FlavorName string | |||||
| EngineName string | |||||
| PreVersionName string | |||||
| TotalVersionCount int | |||||
| } | |||||
| type GenerateInferenceJobReq struct { | type GenerateInferenceJobReq struct { | ||||
| JobName string | JobName string | ||||
| DisplayJobName string | |||||
| Uuid string | Uuid string | ||||
| Description string | Description string | ||||
| CodeObsPath string | CodeObsPath string | ||||
| @@ -266,7 +243,7 @@ func GenerateTask(ctx *context.Context, jobName, uuid, description, flavor strin | |||||
| return nil | return nil | ||||
| } | } | ||||
| func GenerateNotebook2(ctx *context.Context, jobName, uuid, description, flavor, imageId string) error { | |||||
| func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, description, flavor, imageId string) error { | |||||
| if poolInfos == nil { | if poolInfos == nil { | ||||
| json.Unmarshal([]byte(setting.PoolInfos), &poolInfos) | json.Unmarshal([]byte(setting.PoolInfos), &poolInfos) | ||||
| } | } | ||||
| @@ -302,6 +279,7 @@ func GenerateNotebook2(ctx *context.Context, jobName, uuid, description, flavor, | |||||
| RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
| JobID: jobResult.ID, | JobID: jobResult.ID, | ||||
| JobName: jobName, | JobName: jobName, | ||||
| DisplayJobName: displayJobName, | |||||
| JobType: string(models.JobTypeDebug), | JobType: string(models.JobTypeDebug), | ||||
| Type: models.TypeCloudBrainTwo, | Type: models.TypeCloudBrainTwo, | ||||
| Uuid: uuid, | Uuid: uuid, | ||||
| @@ -313,7 +291,13 @@ func GenerateNotebook2(ctx *context.Context, jobName, uuid, description, flavor, | |||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobResult.ID, jobName, models.ActionCreateDebugNPUTask) | |||||
| task, err := models.GetCloudbrainByName(jobName) | |||||
| if err != nil { | |||||
| log.Error("GetCloudbrainByName failed: %v", err.Error()) | |||||
| return err | |||||
| } | |||||
| stringId := strconv.FormatInt(task.ID, 10) | |||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugNPUTask) | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -354,6 +338,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||||
| RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
| JobID: jobId, | JobID: jobId, | ||||
| JobName: req.JobName, | JobName: req.JobName, | ||||
| DisplayJobName: req.DisplayJobName, | |||||
| JobType: string(models.JobTypeTrain), | JobType: string(models.JobTypeTrain), | ||||
| Type: models.TypeCloudBrainTwo, | Type: models.TypeCloudBrainTwo, | ||||
| VersionID: jobResult.VersionID, | VersionID: jobResult.VersionID, | ||||
| @@ -380,10 +365,10 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||||
| }) | }) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, err.Error()) | |||||
| log.Error("CreateCloudbrain(%s) failed:%v", req.DisplayJobName, err.Error()) | |||||
| return err | return err | ||||
| } | } | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobId, req.JobName, models.ActionCreateTrainTask) | |||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobId, req.DisplayJobName, models.ActionCreateTrainTask) | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -438,6 +423,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobReq, job | |||||
| RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
| JobID: strconv.FormatInt(jobResult.JobID, 10), | JobID: strconv.FormatInt(jobResult.JobID, 10), | ||||
| JobName: req.JobName, | JobName: req.JobName, | ||||
| DisplayJobName: req.DisplayJobName, | |||||
| JobType: string(models.JobTypeTrain), | JobType: string(models.JobTypeTrain), | ||||
| Type: models.TypeCloudBrainTwo, | Type: models.TypeCloudBrainTwo, | ||||
| VersionID: jobResult.VersionID, | VersionID: jobResult.VersionID, | ||||
| @@ -574,6 +560,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||||
| RepoID: ctx.Repo.Repository.ID, | RepoID: ctx.Repo.Repository.ID, | ||||
| JobID: jobID, | JobID: jobID, | ||||
| JobName: req.JobName, | JobName: req.JobName, | ||||
| DisplayJobName: req.DisplayJobName, | |||||
| JobType: string(models.JobTypeInference), | JobType: string(models.JobTypeInference), | ||||
| Type: models.TypeCloudBrainTwo, | Type: models.TypeCloudBrainTwo, | ||||
| VersionID: jobResult.VersionID, | VersionID: jobResult.VersionID, | ||||
| @@ -608,7 +595,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||||
| log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, err.Error()) | log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, err.Error()) | ||||
| return err | return err | ||||
| } | } | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, req.JobName, models.ActionCreateInferenceTask) | |||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, req.DisplayJobName, models.ActionCreateInferenceTask) | |||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -6,8 +6,10 @@ package util | |||||
| import ( | import ( | ||||
| "bytes" | "bytes" | ||||
| "math/rand" | |||||
| "strconv" | "strconv" | ||||
| "strings" | "strings" | ||||
| "time" | |||||
| ) | ) | ||||
| // OptionalBool a boolean that can be "null" | // OptionalBool a boolean that can be "null" | ||||
| @@ -110,3 +112,16 @@ func AddZero(t int64) (m string) { | |||||
| return strconv.FormatInt(t, 10) | return strconv.FormatInt(t, 10) | ||||
| } | } | ||||
| } | } | ||||
| func ConvertDisplayJobNameToJobName(DisplayName string) (JobName string) { | |||||
| t := time.Now() | |||||
| JobName = "openi" + strings.ToLower(cutNameString(DisplayName, 15)) + "t" + t.Format("20060102150405")[4:] + strconv.Itoa(int(rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(100000))) | |||||
| return JobName | |||||
| } | |||||
| func cutNameString(str string, lens int) string { | |||||
| if len(str) < lens { | |||||
| return str | |||||
| } | |||||
| return str[:lens] | |||||
| } | |||||
| @@ -850,6 +850,8 @@ model_rename=Duplicate model name, please modify model name. | |||||
| debug=Debug | debug=Debug | ||||
| stop=Stop | stop=Stop | ||||
| delete=Delete | delete=Delete | ||||
| more=More | |||||
| gpu_type_all=All | |||||
| model_download=Model Download | model_download=Model Download | ||||
| submit_image=Submit Image | submit_image=Submit Image | ||||
| download=Download | download=Download | ||||
| @@ -879,6 +881,8 @@ cloudbrain_status_createtime = Status/Createtime | |||||
| cloudbrain_status_runtime = Running Time | cloudbrain_status_runtime = Running Time | ||||
| cloudbrain_jobname_err=Name must start with a lowercase letter or number,can include lowercase letter,number,_ and -,can not end with _, and can be up to 36 characters long. | cloudbrain_jobname_err=Name must start with a lowercase letter or number,can include lowercase letter,number,_ and -,can not end with _, and can be up to 36 characters long. | ||||
| cloudbrain_query_fail=Failed to query cloudbrain information. | cloudbrain_query_fail=Failed to query cloudbrain information. | ||||
| cloudbrain.mirror_tag = Mirror Tag | |||||
| cloudbrain.mirror_description = Mirror Description | |||||
| record_begintime_get_err=Can not get the record begin time. | record_begintime_get_err=Can not get the record begin time. | ||||
| parameter_is_wrong=The input parameter is wrong. | parameter_is_wrong=The input parameter is wrong. | ||||
| @@ -2796,3 +2800,20 @@ foot.help = help | |||||
| foot.copyright= Copyright: New Generation Artificial Intelligence Open Source Open Platform (OpenI) | foot.copyright= Copyright: New Generation Artificial Intelligence Open Source Open Platform (OpenI) | ||||
| Platform_Tutorial = Tutorial | Platform_Tutorial = Tutorial | ||||
| foot.advice_feedback = Feedback | foot.advice_feedback = Feedback | ||||
| [cloudbrain] | |||||
| compute_resource = Computing resources | |||||
| task_name = Task name | |||||
| task_type = Task type | |||||
| gpu_type = GPU type | |||||
| mirror = Mirror | |||||
| dataset = Dataset | |||||
| resource_specification = Resource specification | |||||
| dataset_storage_path = Dataset storage path | |||||
| model_storage_path = Model storage path | |||||
| code_storage_path = Code storage path | |||||
| benchmark_path = Benchmark script path | |||||
| snn4imagenet_path = Snn4imagenet script path | |||||
| brainscore_path = Brainscore script path | |||||
| start_command = Start command | |||||
| choose_mirror = select mirror | |||||
| @@ -855,6 +855,8 @@ debug=调试 | |||||
| debug_again=再次调试 | debug_again=再次调试 | ||||
| stop=停止 | stop=停止 | ||||
| delete=删除 | delete=删除 | ||||
| more=更多 | |||||
| gpu_type_all=全部 | |||||
| model_download=结果下载 | model_download=结果下载 | ||||
| submit_image=提交镜像 | submit_image=提交镜像 | ||||
| download=模型下载 | download=模型下载 | ||||
| @@ -883,6 +885,8 @@ cloudbrain_status_createtime=状态/创建时间 | |||||
| cloudbrain_status_runtime = 运行时长 | cloudbrain_status_runtime = 运行时长 | ||||
| cloudbrain_jobname_err=只能以小写字母或数字开头且只包含小写字母、数字、_和-,不能以_结尾,最长36个字符。 | cloudbrain_jobname_err=只能以小写字母或数字开头且只包含小写字母、数字、_和-,不能以_结尾,最长36个字符。 | ||||
| cloudbrain_query_fail=查询云脑任务失败。 | cloudbrain_query_fail=查询云脑任务失败。 | ||||
| cloudbrain.mirror_tag = 镜像标签 | |||||
| cloudbrain.mirror_description = 镜像描述 | |||||
| record_begintime_get_err=无法获取统计开始时间。 | record_begintime_get_err=无法获取统计开始时间。 | ||||
| parameter_is_wrong=输入参数错误,请检查输入参数。 | parameter_is_wrong=输入参数错误,请检查输入参数。 | ||||
| @@ -2094,7 +2098,7 @@ team_permission_desc=权限 | |||||
| team_unit_desc=允许访问项目单元 | team_unit_desc=允许访问项目单元 | ||||
| team_unit_disabled=(已禁用) | team_unit_disabled=(已禁用) | ||||
| selected_couse=精选课程 | selected_couse=精选课程 | ||||
| release_course = 发布课程 | |||||
| release_course = 发布课程 | |||||
| all_keywords=全部关键字 | all_keywords=全部关键字 | ||||
| all_org_topics=全部 | all_org_topics=全部 | ||||
| max_selectedPro= 最多可选9个公开项目 | max_selectedPro= 最多可选9个公开项目 | ||||
| @@ -2105,7 +2109,7 @@ select_again = 选择超过9个,请重新选择! | |||||
| custom_select_projects = 自定义精选项目 | custom_select_projects = 自定义精选项目 | ||||
| customize = 自定义 | customize = 自定义 | ||||
| selected_project=精选项目 | selected_project=精选项目 | ||||
| fold = 折叠 | |||||
| fold = 收起 | |||||
| unfold = 展开 | unfold = 展开 | ||||
| form.name_reserved=组织名称 '%s' 是被保留的。 | form.name_reserved=组织名称 '%s' 是被保留的。 | ||||
| @@ -2804,3 +2808,20 @@ foot.help=帮助 | |||||
| foot.copyright= 版权所有:新一代人工智能开源开放平台(OpenI) | foot.copyright= 版权所有:新一代人工智能开源开放平台(OpenI) | ||||
| Platform_Tutorial=新手指引 | Platform_Tutorial=新手指引 | ||||
| foot.advice_feedback = 意见反馈 | foot.advice_feedback = 意见反馈 | ||||
| [cloudbrain] | |||||
| compute_resource = 计算资源 | |||||
| task_name = 任务名称 | |||||
| task_type = 任务类型 | |||||
| gpu_type = GPU类型 | |||||
| mirror = 镜像 | |||||
| dataset = 数据集 | |||||
| resource_specification = 资源规格 | |||||
| dataset_storage_path = 数据集存放路径 | |||||
| model_storage_path = 模型存放路径 | |||||
| code_storage_path = 代码存放路径 | |||||
| benchmark_path = benchmark脚本存放路径 | |||||
| snn4imagenet_path = snn4imagenet脚本存放路径 | |||||
| brainscore_path = brainscore脚本存放路径 | |||||
| start_command = 启动命令 | |||||
| choose_mirror = 选择镜像或输入镜像地址 | |||||
| @@ -113,7 +113,7 @@ socket.onmessage = function (e) { | |||||
| html += recordPrefix + actionName; | html += recordPrefix + actionName; | ||||
| html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" +getRepotext(record) + "</a>" | html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" +getRepotext(record) + "</a>" | ||||
| } | } | ||||
| else if( record.OpType == "5"){ | |||||
| else if(record.OpType == "5"){ | |||||
| branch = "<a href=\"" + getRepoLink(record) + "/src/branch/" + encodeURI(record.RefName) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | branch = "<a href=\"" + getRepoLink(record) + "/src/branch/" + encodeURI(record.RefName) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | ||||
| actionName = actionName.replace("{branch}",branch); | actionName = actionName.replace("{branch}",branch); | ||||
| html += recordPrefix + actionName; | html += recordPrefix + actionName; | ||||
| @@ -135,7 +135,11 @@ socket.onmessage = function (e) { | |||||
| html += recordPrefix + actionName; | html += recordPrefix + actionName; | ||||
| html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>" | html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>" | ||||
| } | } | ||||
| else if(record.OpType == "24" || record.OpType == "25" || record.OpType == "26" || record.OpType == "27" || record.OpType == "28" || record.OpType == "29" || record.OpType == "30"){ | |||||
| else if(record.OpType == "24" || record.OpType == "26" || record.OpType == "27" || record.OpType == "28" || record.OpType == "30"){ | |||||
| html += recordPrefix + actionName; | |||||
| html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | |||||
| } | |||||
| else if(record.OpType == "25" || record.OpType == "29"){ | |||||
| html += recordPrefix + actionName; | html += recordPrefix + actionName; | ||||
| html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | ||||
| } | } | ||||
| @@ -160,7 +164,7 @@ function getTaskLink(record){ | |||||
| if(record.OpType == 24){ | if(record.OpType == 24){ | ||||
| re = re + "/datasets?type=" + record.Content; | re = re + "/datasets?type=" + record.Content; | ||||
| }else if(record.OpType == 25){ | }else if(record.OpType == 25){ | ||||
| re = re + "/cloudbrain/" + record.RefName; | |||||
| re = re + "/cloudbrain/" + record.Content; | |||||
| }else if(record.OpType == 26){ | }else if(record.OpType == 26){ | ||||
| re = re + "/modelarts/notebook/" + record.Content; | re = re + "/modelarts/notebook/" + record.Content; | ||||
| }else if(record.OpType == 27){ | }else if(record.OpType == 27){ | ||||
| @@ -168,7 +172,7 @@ function getTaskLink(record){ | |||||
| }else if(record.OpType == 28){ | }else if(record.OpType == 28){ | ||||
| re = re + "/modelarts/inference-job/" + record.Content; | re = re + "/modelarts/inference-job/" + record.Content; | ||||
| }else if(record.OpType == 29){ | }else if(record.OpType == 29){ | ||||
| re = re + "/cloudbrain/benchmark/" + record.RefName; | |||||
| re = re + "/cloudbrain/benchmark/" + record.Content; | |||||
| }else if(record.OpType == 30){ | }else if(record.OpType == 30){ | ||||
| re = re + "/modelmanage/show_model_info?name=" + record.RefName; | re = re + "/modelmanage/show_model_info?name=" + record.RefName; | ||||
| } | } | ||||
| @@ -179,7 +179,7 @@ func DownloadCloudBrains(ctx *context.Context) { | |||||
| } | } | ||||
| func allValues(row int, rs *models.CloudbrainInfo, ctx *context.Context) map[string]string { | func allValues(row int, rs *models.CloudbrainInfo, ctx *context.Context) map[string]string { | ||||
| return map[string]string{getCellName("A", row): rs.JobName, getCellName("B", row): rs.JobType, getCellName("C", row): rs.Status, getCellName("D", row): time.Unix(int64(rs.Cloudbrain.CreatedUnix), 0).Format(CREATE_TIME_FORMAT), getCellName("E", row): getDurationTime(rs), | |||||
| return map[string]string{getCellName("A", row): rs.DisplayJobName, getCellName("B", row): rs.JobType, getCellName("C", row): rs.Status, getCellName("D", row): time.Unix(int64(rs.Cloudbrain.CreatedUnix), 0).Format(CREATE_TIME_FORMAT), getCellName("E", row): getDurationTime(rs), | |||||
| getCellName("F", row): rs.ComputeResource, getCellName("G", row): rs.Name, getCellName("H", row): getRepoPathName(rs), getCellName("I", row): rs.JobName, | getCellName("F", row): rs.ComputeResource, getCellName("G", row): rs.Name, getCellName("H", row): getRepoPathName(rs), getCellName("I", row): rs.JobName, | ||||
| } | } | ||||
| } | } | ||||
| @@ -880,13 +880,13 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| }, reqAdmin()) | }, reqAdmin()) | ||||
| }, reqAnyRepoReader()) | }, reqAnyRepoReader()) | ||||
| m.Group("/cloudbrain", func() { | m.Group("/cloudbrain", func() { | ||||
| m.Get("/:jobid", repo.GetCloudbrainTask) | |||||
| m.Get("/:jobname/log", repo.CloudbrainGetLog) | |||||
| m.Get("/:id", repo.GetCloudbrainTask) | |||||
| m.Get("/:id/log", repo.CloudbrainGetLog) | |||||
| }, reqRepoReader(models.UnitTypeCloudBrain)) | }, reqRepoReader(models.UnitTypeCloudBrain)) | ||||
| m.Group("/modelarts", func() { | m.Group("/modelarts", func() { | ||||
| m.Group("/notebook", func() { | m.Group("/notebook", func() { | ||||
| //m.Get("/:jobid", repo.GetModelArtsNotebook) | //m.Get("/:jobid", repo.GetModelArtsNotebook) | ||||
| m.Get("/:jobid", repo.GetModelArtsNotebook2) | |||||
| m.Get("/:id", repo.GetModelArtsNotebook2) | |||||
| }) | }) | ||||
| m.Group("/train-job", func() { | m.Group("/train-job", func() { | ||||
| m.Group("/:jobid", func() { | m.Group("/:jobid", func() { | ||||
| @@ -49,22 +49,23 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||||
| err error | err error | ||||
| ) | ) | ||||
| // jobName := ctx.Params(":jobname") | |||||
| // job, err := models.GetCloudbrainByName(jobName) | |||||
| jobID := ctx.Params(":jobid") | |||||
| repoID := ctx.Repo.Repository.ID | |||||
| job, err := models.GetRepoCloudBrainByJobID(repoID, jobID) | |||||
| ID := ctx.Params(":id") | |||||
| job, err := models.GetCloudbrainByID(ID) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Data["error"] = err.Error() | |||||
| ctx.NotFound(err) | |||||
| log.Error("GetCloudbrainByID failed:", err) | |||||
| return | |||||
| } | } | ||||
| jobResult, err := cloudbrain.GetJob(job.JobID) | jobResult, err := cloudbrain.GetJob(job.JobID) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.NotFound(err) | ctx.NotFound(err) | ||||
| log.Error("GetJob failed:", err) | |||||
| return | return | ||||
| } | } | ||||
| result, err := models.ConvertToJobResultPayload(jobResult.Payload) | result, err := models.ConvertToJobResultPayload(jobResult.Payload) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.NotFound(err) | ctx.NotFound(err) | ||||
| log.Error("ConvertToJobResultPayload failed:", err) | |||||
| return | return | ||||
| } | } | ||||
| @@ -86,7 +87,7 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||||
| } | } | ||||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
| "JobID": result.Config.JobID, | |||||
| "ID": ID, | |||||
| "JobName": result.Config.JobName, | "JobName": result.Config.JobName, | ||||
| "JobStatus": result.JobStatus.State, | "JobStatus": result.JobStatus.State, | ||||
| "SubState": result.JobStatus.SubState, | "SubState": result.JobStatus.SubState, | ||||
| @@ -97,8 +98,8 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||||
| } | } | ||||
| func CloudbrainGetLog(ctx *context.Context) { | func CloudbrainGetLog(ctx *context.Context) { | ||||
| jobName := ctx.Params(":jobname") | |||||
| job, err := models.GetCloudbrainByName(jobName) | |||||
| ID := ctx.Params(":id") | |||||
| job, err := models.GetCloudbrainByID(ID) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetCloudbrainByJobName failed: %v", err, ctx.Data["MsgID"]) | log.Error("GetCloudbrainByJobName failed: %v", err, ctx.Data["MsgID"]) | ||||
| ctx.ServerError(err.Error(), err) | ctx.ServerError(err.Error(), err) | ||||
| @@ -145,7 +146,7 @@ func CloudbrainGetLog(ctx *context.Context) { | |||||
| } | } | ||||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
| "JobName": jobName, | |||||
| "JobName": job.JobName, | |||||
| "Content": content, | "Content": content, | ||||
| }) | }) | ||||
| @@ -56,14 +56,13 @@ func GetModelArtsNotebook2(ctx *context.APIContext) { | |||||
| err error | err error | ||||
| ) | ) | ||||
| jobID := ctx.Params(":jobid") | |||||
| repoID := ctx.Repo.Repository.ID | |||||
| job, err := models.GetRepoCloudBrainByJobID(repoID, jobID) | |||||
| ID := ctx.Params(":id") | |||||
| job, err := models.GetCloudbrainByID(ID) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.NotFound(err) | ctx.NotFound(err) | ||||
| return | return | ||||
| } | } | ||||
| result, err := modelarts.GetNotebook2(jobID) | |||||
| result, err := modelarts.GetNotebook2(job.JobID) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.NotFound(err) | ctx.NotFound(err) | ||||
| return | return | ||||
| @@ -76,7 +75,7 @@ func GetModelArtsNotebook2(ctx *context.APIContext) { | |||||
| } | } | ||||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | ctx.JSON(http.StatusOK, map[string]interface{}{ | ||||
| "JobID": jobID, | |||||
| "ID": ID, | |||||
| "JobName": job.JobName, | "JobName": job.JobName, | ||||
| "JobStatus": result.Status, | "JobStatus": result.Status, | ||||
| }) | }) | ||||
| @@ -6,8 +6,13 @@ package events | |||||
| import ( | import ( | ||||
| "net/http" | "net/http" | ||||
| "time" | |||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/eventsource" | |||||
| "code.gitea.io/gitea/modules/graceful" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/routers/user" | |||||
| ) | ) | ||||
| // Events listens for events | // Events listens for events | ||||
| @@ -22,86 +27,86 @@ func Events(ctx *context.Context) { | |||||
| ctx.Resp.WriteHeader(http.StatusOK) | ctx.Resp.WriteHeader(http.StatusOK) | ||||
| // Listen to connection close and un-register messageChan | // Listen to connection close and un-register messageChan | ||||
| // notify := ctx.Req.Context().Done() | |||||
| // ctx.Resp.Flush() | |||||
| notify := ctx.Req.Context().Done() | |||||
| ctx.Resp.Flush() | |||||
| // shutdownCtx := graceful.GetManager().ShutdownContext() | |||||
| shutdownCtx := graceful.GetManager().ShutdownContext() | |||||
| // uid := ctx.User.ID | |||||
| uid := ctx.User.ID | |||||
| // messageChan := eventsource.GetManager().Register(uid) | |||||
| messageChan := eventsource.GetManager().Register(uid) | |||||
| // unregister := func() { | |||||
| // eventsource.GetManager().Unregister(uid, messageChan) | |||||
| // // ensure the messageChan is closed | |||||
| // for { | |||||
| // _, ok := <-messageChan | |||||
| // if !ok { | |||||
| // break | |||||
| // } | |||||
| // } | |||||
| // } | |||||
| unregister := func() { | |||||
| eventsource.GetManager().Unregister(uid, messageChan) | |||||
| // ensure the messageChan is closed | |||||
| for { | |||||
| _, ok := <-messageChan | |||||
| if !ok { | |||||
| break | |||||
| } | |||||
| } | |||||
| } | |||||
| // if _, err := ctx.Resp.Write([]byte("\n")); err != nil { | |||||
| // log.Error("Unable to write to EventStream: %v", err) | |||||
| // unregister() | |||||
| // return | |||||
| // } | |||||
| if _, err := ctx.Resp.Write([]byte("\n")); err != nil { | |||||
| log.Error("Unable to write to EventStream: %v", err) | |||||
| unregister() | |||||
| return | |||||
| } | |||||
| // timer := time.NewTicker(30 * time.Second) | |||||
| timer := time.NewTicker(30 * time.Second) | |||||
| // loop: | |||||
| // for { | |||||
| // select { | |||||
| // case <-timer.C: | |||||
| // event := &eventsource.Event{ | |||||
| // Name: "ping", | |||||
| // } | |||||
| // _, err := event.WriteTo(ctx.Resp) | |||||
| // if err != nil { | |||||
| // log.Error("Unable to write to EventStream for user %s: %v", ctx.User.Name, err) | |||||
| // go unregister() | |||||
| // break loop | |||||
| // } | |||||
| // ctx.Resp.Flush() | |||||
| // case <-notify: | |||||
| // go unregister() | |||||
| // break loop | |||||
| // case <-shutdownCtx.Done(): | |||||
| // go unregister() | |||||
| // break loop | |||||
| // case event, ok := <-messageChan: | |||||
| // if !ok { | |||||
| // break loop | |||||
| // } | |||||
| loop: | |||||
| for { | |||||
| select { | |||||
| case <-timer.C: | |||||
| event := &eventsource.Event{ | |||||
| Name: "ping", | |||||
| } | |||||
| _, err := event.WriteTo(ctx.Resp) | |||||
| if err != nil { | |||||
| log.Error("Unable to write to EventStream for user %s: %v", ctx.User.Name, err) | |||||
| go unregister() | |||||
| break loop | |||||
| } | |||||
| ctx.Resp.Flush() | |||||
| case <-notify: | |||||
| go unregister() | |||||
| break loop | |||||
| case <-shutdownCtx.Done(): | |||||
| go unregister() | |||||
| break loop | |||||
| case event, ok := <-messageChan: | |||||
| if !ok { | |||||
| break loop | |||||
| } | |||||
| // // Handle logout | |||||
| // if event.Name == "logout" { | |||||
| // if ctx.Session.ID() == event.Data { | |||||
| // _, _ = (&eventsource.Event{ | |||||
| // Name: "logout", | |||||
| // Data: "here", | |||||
| // }).WriteTo(ctx.Resp) | |||||
| // ctx.Resp.Flush() | |||||
| // go unregister() | |||||
| // user.HandleSignOut(ctx) | |||||
| // break loop | |||||
| // } | |||||
| // // Replace the event - we don't want to expose the session ID to the user | |||||
| // event = (&eventsource.Event{ | |||||
| // Name: "logout", | |||||
| // Data: "elsewhere", | |||||
| // }) | |||||
| // } | |||||
| // Handle logout | |||||
| if event.Name == "logout" { | |||||
| if ctx.Session.ID() == event.Data { | |||||
| _, _ = (&eventsource.Event{ | |||||
| Name: "logout", | |||||
| Data: "here", | |||||
| }).WriteTo(ctx.Resp) | |||||
| ctx.Resp.Flush() | |||||
| go unregister() | |||||
| user.HandleSignOut(ctx) | |||||
| break loop | |||||
| } | |||||
| // Replace the event - we don't want to expose the session ID to the user | |||||
| event = (&eventsource.Event{ | |||||
| Name: "logout", | |||||
| Data: "elsewhere", | |||||
| }) | |||||
| } | |||||
| // _, err := event.WriteTo(ctx.Resp) | |||||
| // if err != nil { | |||||
| // log.Error("Unable to write to EventStream for user %s: %v", ctx.User.Name, err) | |||||
| // go unregister() | |||||
| // break loop | |||||
| // } | |||||
| // ctx.Resp.Flush() | |||||
| // } | |||||
| // } | |||||
| // timer.Stop() | |||||
| _, err := event.WriteTo(ctx.Resp) | |||||
| if err != nil { | |||||
| log.Error("Unable to write to EventStream for user %s: %v", ctx.User.Name, err) | |||||
| go unregister() | |||||
| break loop | |||||
| } | |||||
| ctx.Resp.Flush() | |||||
| } | |||||
| } | |||||
| timer.Stop() | |||||
| } | } | ||||
| @@ -416,6 +416,10 @@ func HookPostReceive(ctx *macaron.Context, opts private.HookOptions) { | |||||
| copy(updates[1:], updates) | copy(updates[1:], updates) | ||||
| updates[0] = &option | updates[0] = &option | ||||
| } | } | ||||
| if err := updateRepoCommitCnt(ctx, repo); err != nil { | |||||
| log.Error("updateRepoCommitCnt failed:%v", err.Error(), ctx.Data["MsgID"]) | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -521,10 +525,6 @@ func HookPostReceive(ctx *macaron.Context, opts private.HookOptions) { | |||||
| } | } | ||||
| } | } | ||||
| if err := updateRepoCommitCnt(ctx, repo); err != nil { | |||||
| log.Error("updateRepoCommitCnt failed:%v", err.Error(), ctx.Data["MsgID"]) | |||||
| } | |||||
| ctx.JSON(http.StatusOK, private.HookPostReceiveResult{ | ctx.JSON(http.StatusOK, private.HookPostReceiveResult{ | ||||
| Results: results, | Results: results, | ||||
| RepoWasEmpty: wasEmpty, | RepoWasEmpty: wasEmpty, | ||||
| @@ -512,7 +512,12 @@ func GetSuccessChunks(ctx *context.Context) { | |||||
| return | return | ||||
| } | } | ||||
| } else { | } else { | ||||
| isExist, err = storage.ObsHasObject(setting.BasePath + models.AttachmentRelativePath(fileChunk.UUID) + "/" + fileName) | |||||
| oldFileName := fileName | |||||
| oldAttachment, _ := models.GetAttachmentByUUID(fileChunk.UUID) | |||||
| if oldAttachment != nil { | |||||
| oldFileName = oldAttachment.Name | |||||
| } | |||||
| isExist, err = storage.ObsHasObject(setting.BasePath + models.AttachmentRelativePath(fileChunk.UUID) + "/" + oldFileName) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("ObsHasObject failed", err) | ctx.ServerError("ObsHasObject failed", err) | ||||
| return | return | ||||
| @@ -76,8 +76,8 @@ func jobNamePrefixValid(s string) string { | |||||
| func cloudBrainNewDataPrepare(ctx *context.Context) error { | func cloudBrainNewDataPrepare(ctx *context.Context) error { | ||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| t := time.Now() | t := time.Now() | ||||
| var jobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["job_name"] = jobName | |||||
| var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["display_job_name"] = displayJobName | |||||
| result, err := cloudbrain.GetImages() | result, err := cloudbrain.GetImages() | ||||
| if err != nil { | if err != nil { | ||||
| @@ -176,7 +176,8 @@ func CloudBrainNew(ctx *context.Context) { | |||||
| func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | ||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| jobName := form.JobName | |||||
| displayJobName := form.DisplayJobName | |||||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||||
| image := form.Image | image := form.Image | ||||
| uuid := form.Attachment | uuid := form.Attachment | ||||
| jobType := form.JobType | jobType := form.JobType | ||||
| @@ -184,8 +185,26 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
| gpuQueue := form.GpuType | gpuQueue := form.GpuType | ||||
| codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | ||||
| resourceSpecId := form.ResourceSpecId | resourceSpecId := form.ResourceSpecId | ||||
| repo := ctx.Repo.Repository | |||||
| if !jobNamePattern.MatchString(jobName) { | |||||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeDebug), displayJobName) | |||||
| if err == nil { | |||||
| if len(tasks) != 0 { | |||||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("the job name did already exist", tplCloudBrainNew, &form) | |||||
| return | |||||
| } | |||||
| } else { | |||||
| if !models.IsErrJobNotExist(err) { | |||||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("system error", tplCloudBrainNew, &form) | |||||
| return | |||||
| } | |||||
| } | |||||
| if !jobNamePattern.MatchString(displayJobName) { | |||||
| ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplCloudBrainNew, &form) | ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplCloudBrainNew, &form) | ||||
| return | return | ||||
| } | } | ||||
| @@ -212,21 +231,6 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
| } | } | ||||
| } | } | ||||
| _, err = models.GetCloudbrainByName(jobName) | |||||
| if err == nil { | |||||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("the job name did already exist", tplCloudBrainNew, &form) | |||||
| return | |||||
| } else { | |||||
| if !models.IsErrJobNotExist(err) { | |||||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("system error", tplCloudBrainNew, &form) | |||||
| return | |||||
| } | |||||
| } | |||||
| repo := ctx.Repo.Repository | |||||
| downloadCode(repo, codePath) | downloadCode(repo, codePath) | ||||
| uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/") | uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/") | ||||
| @@ -258,7 +262,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
| uploadCodeToMinio(brainScorePath+"/", jobName, cloudbrain.BrainScoreMountPath+"/") | uploadCodeToMinio(brainScorePath+"/", jobName, cloudbrain.BrainScoreMountPath+"/") | ||||
| } | } | ||||
| err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | |||||
| err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, uuid, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | |||||
| storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | ||||
| storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | ||||
| storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, form.Description, | storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, form.Description, | ||||
| @@ -273,11 +277,10 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
| } | } | ||||
| func CloudBrainRestart(ctx *context.Context) { | func CloudBrainRestart(ctx *context.Context) { | ||||
| var jobID = ctx.Params(":jobid") | |||||
| var ID = ctx.Params(":id") | |||||
| var resultCode = "0" | var resultCode = "0" | ||||
| var errorMsg = "" | var errorMsg = "" | ||||
| var status = string(models.JobWaiting) | var status = string(models.JobWaiting) | ||||
| task := ctx.Cloudbrain | task := ctx.Cloudbrain | ||||
| for { | for { | ||||
| if task.Status != string(models.JobStopped) && task.Status != string(models.JobSucceeded) && task.Status != string(models.JobFailed) { | if task.Status != string(models.JobStopped) && task.Status != string(models.JobSucceeded) && task.Status != string(models.JobFailed) { | ||||
| @@ -316,7 +319,7 @@ func CloudBrainRestart(ctx *context.Context) { | |||||
| } | } | ||||
| } | } | ||||
| err = cloudbrain.RestartTask(ctx, task, &jobID) | |||||
| err = cloudbrain.RestartTask(ctx, task, &ID) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("RestartTask failed:%v", err.Error(), ctx.Data["MsgID"]) | log.Error("RestartTask failed:%v", err.Error(), ctx.Data["MsgID"]) | ||||
| resultCode = "-1" | resultCode = "-1" | ||||
| @@ -331,7 +334,7 @@ func CloudBrainRestart(ctx *context.Context) { | |||||
| "result_code": resultCode, | "result_code": resultCode, | ||||
| "error_msg": errorMsg, | "error_msg": errorMsg, | ||||
| "status": status, | "status": status, | ||||
| "job_id": jobID, | |||||
| "id": ID, | |||||
| }) | }) | ||||
| } | } | ||||
| @@ -352,14 +355,16 @@ func CloudBrainShow(ctx *context.Context) { | |||||
| func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | ||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| var jobName = ctx.Params(":jobname") | |||||
| var ID = ctx.Params(":id") | |||||
| debugListType := ctx.Query("debugListType") | debugListType := ctx.Query("debugListType") | ||||
| task, err := models.GetCloudbrainByName(jobName) | |||||
| task, err := models.GetCloudbrainByID(ID) | |||||
| if err != nil { | if err != nil { | ||||
| log.Info("error:" + err.Error()) | |||||
| ctx.Data["error"] = err.Error() | ctx.Data["error"] = err.Error() | ||||
| } | } | ||||
| result, err := cloudbrain.GetJob(task.JobID) | result, err := cloudbrain.GetJob(task.JobID) | ||||
| if err != nil { | if err != nil { | ||||
| log.Info("error:" + err.Error()) | |||||
| ctx.Data["error"] = err.Error() | ctx.Data["error"] = err.Error() | ||||
| } | } | ||||
| if result != nil { | if result != nil { | ||||
| @@ -423,8 +428,8 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||||
| ctx.Data["duration"] = util.AddZero(duration/3600000) + ":" + util.AddZero(duration%3600000/60000) + ":" + util.AddZero(duration%60000/1000) | ctx.Data["duration"] = util.AddZero(duration/3600000) + ":" + util.AddZero(duration%3600000/60000) + ":" + util.AddZero(duration%60000/1000) | ||||
| ctx.Data["task"] = task | ctx.Data["task"] = task | ||||
| // ctx.Data["jobID"] = task.JobID | |||||
| ctx.Data["jobName"] = task.JobName | ctx.Data["jobName"] = task.JobName | ||||
| ctx.Data["displayJobName"] = task.DisplayJobName | |||||
| version_list_task := make([]*models.Cloudbrain, 0) | version_list_task := make([]*models.Cloudbrain, 0) | ||||
| version_list_task = append(version_list_task, task) | version_list_task = append(version_list_task, task) | ||||
| ctx.Data["version_list_task"] = version_list_task | ctx.Data["version_list_task"] = version_list_task | ||||
| @@ -433,7 +438,8 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName) { | |||||
| } | } | ||||
| func CloudBrainDebug(ctx *context.Context) { | func CloudBrainDebug(ctx *context.Context) { | ||||
| debugUrl := setting.DebugServerHost + "jpylab_" + ctx.Cloudbrain.JobID + "_" + ctx.Cloudbrain.SubTaskName | |||||
| task := ctx.Cloudbrain | |||||
| debugUrl := setting.DebugServerHost + "jpylab_" + task.JobID + "_" + task.SubTaskName | |||||
| ctx.Redirect(debugUrl) | ctx.Redirect(debugUrl) | ||||
| } | } | ||||
| @@ -460,7 +466,7 @@ func CloudBrainCommitImage(ctx *context.Context, form auth.CommitImageCloudBrain | |||||
| } | } | ||||
| func CloudBrainStop(ctx *context.Context) { | func CloudBrainStop(ctx *context.Context) { | ||||
| var jobID = ctx.Params(":jobid") | |||||
| var ID = ctx.Params(":id") | |||||
| var resultCode = "0" | var resultCode = "0" | ||||
| var errorMsg = "" | var errorMsg = "" | ||||
| var status = "" | var status = "" | ||||
| @@ -474,7 +480,7 @@ func CloudBrainStop(ctx *context.Context) { | |||||
| break | break | ||||
| } | } | ||||
| err := cloudbrain.StopJob(jobID) | |||||
| err := cloudbrain.StopJob(task.JobID) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("StopJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"]) | log.Error("StopJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"]) | ||||
| resultCode = "-1" | resultCode = "-1" | ||||
| @@ -499,7 +505,7 @@ func CloudBrainStop(ctx *context.Context) { | |||||
| "result_code": resultCode, | "result_code": resultCode, | ||||
| "error_msg": errorMsg, | "error_msg": errorMsg, | ||||
| "status": status, | "status": status, | ||||
| "job_id": jobID, | |||||
| "id": ID, | |||||
| }) | }) | ||||
| } | } | ||||
| @@ -621,10 +627,10 @@ func deleteCloudbrainJob(ctx *context.Context) error { | |||||
| func CloudBrainShowModels(ctx *context.Context) { | func CloudBrainShowModels(ctx *context.Context) { | ||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| jobID := ctx.Params(":jobid") | |||||
| ID := ctx.Params(":id") | |||||
| parentDir := ctx.Query("parentDir") | parentDir := ctx.Query("parentDir") | ||||
| dirArray := strings.Split(parentDir, "/") | dirArray := strings.Split(parentDir, "/") | ||||
| task, err := models.GetCloudbrainByJobID(jobID) | |||||
| task, err := models.GetCloudbrainByID(ID) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("no such job!", ctx.Data["msgID"]) | log.Error("no such job!", ctx.Data["msgID"]) | ||||
| ctx.ServerError("no such job:", err) | ctx.ServerError("no such job:", err) | ||||
| @@ -659,7 +665,7 @@ func CloudBrainShowModels(ctx *context.Context) { | |||||
| ctx.Data["Path"] = dirArray | ctx.Data["Path"] = dirArray | ||||
| ctx.Data["Dirs"] = fileInfos | ctx.Data["Dirs"] = fileInfos | ||||
| ctx.Data["task"] = task | ctx.Data["task"] = task | ||||
| ctx.Data["JobID"] = jobID | |||||
| ctx.Data["ID"] = ID | |||||
| ctx.HTML(200, tplCloudBrainShowModels) | ctx.HTML(200, tplCloudBrainShowModels) | ||||
| } | } | ||||
| @@ -728,8 +734,8 @@ func GetRate(ctx *context.Context) { | |||||
| return | return | ||||
| } | } | ||||
| var jobID = ctx.Params(":jobid") | |||||
| job, err := models.GetCloudbrainByJobID(jobID) | |||||
| var ID = ctx.Params(":id") | |||||
| job, err := models.GetCloudbrainByID(ID) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("GetCloudbrainByJobID failed", err) | ctx.ServerError("GetCloudbrainByJobID failed", err) | ||||
| return | return | ||||
| @@ -1220,7 +1226,8 @@ func getBenchmarkResourceSpec(resourceSpecID int) (int, error) { | |||||
| func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | ||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| jobName := form.JobName | |||||
| displayJobName := form.DisplayJobName | |||||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||||
| image := form.Image | image := form.Image | ||||
| gpuQueue := form.GpuType | gpuQueue := form.GpuType | ||||
| command := cloudbrain.CommandBenchmark | command := cloudbrain.CommandBenchmark | ||||
| @@ -1232,6 +1239,26 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||||
| ctx.Data["description"] = form.Description | ctx.Data["description"] = form.Description | ||||
| ctx.Data["benchmarkTypeID"] = benchmarkTypeID | ctx.Data["benchmarkTypeID"] = benchmarkTypeID | ||||
| ctx.Data["benchmark_child_types_id_hidden"] = benchmarkChildTypeID | ctx.Data["benchmark_child_types_id_hidden"] = benchmarkChildTypeID | ||||
| repo := ctx.Repo.Repository | |||||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeBenchmark), displayJobName) | |||||
| if err == nil { | |||||
| if len(tasks) != 0 { | |||||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("the job name did already exist", tplCloudBrainBenchmarkNew, &form) | |||||
| return | |||||
| } | |||||
| } else { | |||||
| if !models.IsErrJobNotExist(err) { | |||||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) | |||||
| return | |||||
| } | |||||
| } | |||||
| if !jobNamePattern.MatchString(jobName) { | if !jobNamePattern.MatchString(jobName) { | ||||
| cloudBrainNewDataPrepare(ctx) | cloudBrainNewDataPrepare(ctx) | ||||
| ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplCloudBrainBenchmarkNew, &form) | ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplCloudBrainBenchmarkNew, &form) | ||||
| @@ -1277,21 +1304,6 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||||
| } | } | ||||
| } | } | ||||
| _, err = models.GetCloudbrainByName(jobName) | |||||
| if err == nil { | |||||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("the job name did already exist", tplCloudBrainBenchmarkNew, &form) | |||||
| return | |||||
| } else { | |||||
| if !models.IsErrJobNotExist(err) { | |||||
| log.Error("GetCloudbrainByName failed, %v", err, ctx.Data["MsgID"]) | |||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) | |||||
| return | |||||
| } | |||||
| } | |||||
| repo := ctx.Repo.Repository | |||||
| os.RemoveAll(codePath) | os.RemoveAll(codePath) | ||||
| if err := downloadCode(repo, codePath); err != nil { | if err := downloadCode(repo, codePath); err != nil { | ||||
| log.Error("downloadCode failed, %v", err, ctx.Data["MsgID"]) | log.Error("downloadCode failed, %v", err, ctx.Data["MsgID"]) | ||||
| @@ -1355,7 +1367,7 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||||
| //return | //return | ||||
| } | } | ||||
| err = cloudbrain.GenerateTask(ctx, jobName, image, command, childInfo.Attachment, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | |||||
| err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, childInfo.Attachment, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | |||||
| storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | ||||
| storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | ||||
| storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), string(models.JobTypeBenchmark), gpuQueue, form.Description, | storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), string(models.JobTypeBenchmark), gpuQueue, form.Description, | ||||
| @@ -25,6 +25,7 @@ import ( | |||||
| "code.gitea.io/gitea/modules/obs" | "code.gitea.io/gitea/modules/obs" | ||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| "code.gitea.io/gitea/modules/storage" | "code.gitea.io/gitea/modules/storage" | ||||
| "code.gitea.io/gitea/modules/util" | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| @@ -112,8 +113,8 @@ func NotebookNew(ctx *context.Context) { | |||||
| func notebookNewDataPrepare(ctx *context.Context) error { | func notebookNewDataPrepare(ctx *context.Context) error { | ||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| t := time.Now() | t := time.Now() | ||||
| var jobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["job_name"] = jobName | |||||
| var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["display_job_name"] = displayJobName | |||||
| attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID) | attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -181,11 +182,13 @@ func NotebookCreate(ctx *context.Context, form auth.CreateModelArtsNotebookForm) | |||||
| func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm) { | func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm) { | ||||
| ctx.Data["PageIsNotebook"] = true | ctx.Data["PageIsNotebook"] = true | ||||
| jobName := form.JobName | |||||
| displayJobName := form.DisplayJobName | |||||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||||
| uuid := form.Attachment | uuid := form.Attachment | ||||
| description := form.Description | description := form.Description | ||||
| flavor := form.Flavor | flavor := form.Flavor | ||||
| imageId := form.ImageId | imageId := form.ImageId | ||||
| repo := ctx.Repo.Repository | |||||
| count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID) | count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -201,12 +204,15 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm | |||||
| return | return | ||||
| } | } | ||||
| } | } | ||||
| _, err = models.GetCloudbrainByName(jobName) | |||||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeDebug), displayJobName) | |||||
| if err == nil { | if err == nil { | ||||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||||
| notebookNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("the job name did already exist", tplModelArtsNotebookNew, &form) | |||||
| return | |||||
| if len(tasks) != 0 { | |||||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||||
| notebookNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("the job name did already exist", tplModelArtsNotebookNew, &form) | |||||
| return | |||||
| } | |||||
| } else { | } else { | ||||
| if !models.IsErrJobNotExist(err) { | if !models.IsErrJobNotExist(err) { | ||||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | log.Error("system error, %v", err, ctx.Data["MsgID"]) | ||||
| @@ -216,7 +222,7 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm | |||||
| } | } | ||||
| } | } | ||||
| err = modelarts.GenerateNotebook2(ctx, jobName, uuid, description, flavor, imageId) | |||||
| err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, flavor, imageId) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("GenerateNotebook2 failed, %v", err, ctx.Data["MsgID"]) | log.Error("GenerateNotebook2 failed, %v", err, ctx.Data["MsgID"]) | ||||
| notebookNewDataPrepare(ctx) | notebookNewDataPrepare(ctx) | ||||
| @@ -230,15 +236,15 @@ func NotebookShow(ctx *context.Context) { | |||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| debugListType := ctx.Query("debugListType") | debugListType := ctx.Query("debugListType") | ||||
| var jobID = ctx.Params(":jobid") | |||||
| task, err := models.GetCloudbrainByJobID(jobID) | |||||
| var ID = ctx.Params(":id") | |||||
| task, err := models.GetCloudbrainByID(ID) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Data["error"] = err.Error() | ctx.Data["error"] = err.Error() | ||||
| ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil) | ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil) | ||||
| return | return | ||||
| } | } | ||||
| result, err := modelarts.GetNotebook2(jobID) | |||||
| result, err := modelarts.GetNotebook2(task.JobID) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Data["error"] = err.Error() | ctx.Data["error"] = err.Error() | ||||
| ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil) | ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil) | ||||
| @@ -270,7 +276,7 @@ func NotebookShow(ctx *context.Context) { | |||||
| ctx.Data["datasetDownloadLink"] = datasetDownloadLink | ctx.Data["datasetDownloadLink"] = datasetDownloadLink | ||||
| ctx.Data["task"] = task | ctx.Data["task"] = task | ||||
| ctx.Data["jobID"] = jobID | |||||
| ctx.Data["ID"] = ID | |||||
| ctx.Data["jobName"] = task.JobName | ctx.Data["jobName"] = task.JobName | ||||
| ctx.Data["result"] = result | ctx.Data["result"] = result | ||||
| ctx.Data["debugListType"] = debugListType | ctx.Data["debugListType"] = debugListType | ||||
| @@ -305,9 +311,8 @@ func NotebookDebug(ctx *context.Context) { | |||||
| } | } | ||||
| func NotebookDebug2(ctx *context.Context) { | func NotebookDebug2(ctx *context.Context) { | ||||
| var jobID = ctx.Params(":jobid") | |||||
| result, err := modelarts.GetNotebook2(jobID) | |||||
| task := ctx.Cloudbrain | |||||
| result, err := modelarts.GetNotebook2(task.JobID) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil) | ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil) | ||||
| return | return | ||||
| @@ -317,16 +322,16 @@ func NotebookDebug2(ctx *context.Context) { | |||||
| } | } | ||||
| func NotebookManage(ctx *context.Context) { | func NotebookManage(ctx *context.Context) { | ||||
| var jobID = ctx.Params(":jobid") | |||||
| var ID = ctx.Params(":id") | |||||
| var action = ctx.Params(":action") | var action = ctx.Params(":action") | ||||
| var resultCode = "0" | var resultCode = "0" | ||||
| var errorMsg = "" | var errorMsg = "" | ||||
| var status = "" | var status = "" | ||||
| for { | for { | ||||
| task, err := models.GetCloudbrainByJobID(jobID) | |||||
| task, err := models.GetCloudbrainByID(ID) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetCloudbrainByJobID failed:%v", err, ctx.Data["MsgID"]) | |||||
| log.Error("get task(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | |||||
| resultCode = "-1" | resultCode = "-1" | ||||
| errorMsg = "system error" | errorMsg = "system error" | ||||
| break | break | ||||
| @@ -391,7 +396,7 @@ func NotebookManage(ctx *context.Context) { | |||||
| param := models.NotebookAction{ | param := models.NotebookAction{ | ||||
| Action: action, | Action: action, | ||||
| } | } | ||||
| res, err := modelarts.ManageNotebook2(jobID, param) | |||||
| res, err := modelarts.ManageNotebook2(task.JobID, param) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("ManageNotebook2(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | log.Error("ManageNotebook2(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | ||||
| resultCode = "-1" | resultCode = "-1" | ||||
| @@ -420,12 +425,11 @@ func NotebookManage(ctx *context.Context) { | |||||
| "result_code": resultCode, | "result_code": resultCode, | ||||
| "error_msg": errorMsg, | "error_msg": errorMsg, | ||||
| "status": status, | "status": status, | ||||
| "job_id": jobID, | |||||
| "id": ID, | |||||
| }) | }) | ||||
| } | } | ||||
| func NotebookDel(ctx *context.Context) { | func NotebookDel(ctx *context.Context) { | ||||
| var jobID = ctx.Params(":jobid") | |||||
| var listType = ctx.Query("debugListType") | var listType = ctx.Query("debugListType") | ||||
| task := ctx.Cloudbrain | task := ctx.Cloudbrain | ||||
| @@ -435,10 +439,10 @@ func NotebookDel(ctx *context.Context) { | |||||
| return | return | ||||
| } | } | ||||
| _, err := modelarts.DelNotebook2(jobID) | |||||
| _, err := modelarts.DelNotebook2(task.JobID) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("DelNotebook2(%s) failed:%v", task.JobName, err.Error()) | log.Error("DelNotebook2(%s) failed:%v", task.JobName, err.Error()) | ||||
| if strings.Contains(err.Error(), modelarts.NotebookNotFound) || strings.Contains(err.Error(), modelarts.NotebookNoPermission) || strings.Contains(err.Error(), modelarts.NotebookInvalid){ | |||||
| if strings.Contains(err.Error(), modelarts.NotebookNotFound) || strings.Contains(err.Error(), modelarts.NotebookNoPermission) || strings.Contains(err.Error(), modelarts.NotebookInvalid) { | |||||
| log.Info("old notebook version") | log.Info("old notebook version") | ||||
| } else { | } else { | ||||
| ctx.RenderWithErr(err.Error(), tplDebugJobIndex, nil) | ctx.RenderWithErr(err.Error(), tplDebugJobIndex, nil) | ||||
| @@ -529,8 +533,8 @@ func trainJobNewDataPrepare(ctx *context.Context) error { | |||||
| //} | //} | ||||
| t := time.Now() | t := time.Now() | ||||
| var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["job_name"] = jobName | |||||
| var displayJobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["display_job_name"] = displayJobName | |||||
| attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -567,8 +571,6 @@ func trainJobNewDataPrepare(ctx *context.Context) error { | |||||
| } | } | ||||
| ctx.Data["flavor_infos"] = flavorInfos.Info | ctx.Data["flavor_infos"] = flavorInfos.Info | ||||
| outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath | |||||
| ctx.Data["train_url"] = outputObsPath | |||||
| ctx.Data["params"] = "" | ctx.Data["params"] = "" | ||||
| ctx.Data["branchName"] = ctx.Repo.BranchName | ctx.Data["branchName"] = ctx.Repo.BranchName | ||||
| @@ -598,8 +600,8 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts | |||||
| //} | //} | ||||
| t := time.Now() | t := time.Now() | ||||
| var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["job_name"] = jobName | |||||
| var displayJobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["display_job_name"] = displayJobName | |||||
| attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -636,9 +638,6 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts | |||||
| } | } | ||||
| ctx.Data["flavor_infos"] = flavorInfos.Info | ctx.Data["flavor_infos"] = flavorInfos.Info | ||||
| outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath | |||||
| ctx.Data["train_url"] = outputObsPath | |||||
| configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom) | configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("getConfigList failed:", err) | ctx.ServerError("getConfigList failed:", err) | ||||
| @@ -685,8 +684,7 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error { | |||||
| return err | return err | ||||
| } | } | ||||
| t := time.Now() | |||||
| var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["display_job_name"] = task.DisplayJobName | |||||
| ctx.Data["job_name"] = task.JobName | ctx.Data["job_name"] = task.JobName | ||||
| attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | ||||
| @@ -731,9 +729,6 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error { | |||||
| } | } | ||||
| ctx.Data["params"] = Parameters.Parameter | ctx.Data["params"] = Parameters.Parameter | ||||
| outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath | |||||
| ctx.Data["train_url"] = outputObsPath | |||||
| branches, _, err := ctx.Repo.GitRepo.GetBranches(0, 0) | branches, _, err := ctx.Repo.GitRepo.GetBranches(0, 0) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("GetBranches error:", err) | ctx.ServerError("GetBranches error:", err) | ||||
| @@ -854,7 +849,8 @@ func versionErrorDataPrepare(ctx *context.Context, form auth.CreateModelArtsTrai | |||||
| func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) { | func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) { | ||||
| ctx.Data["PageIsTrainJob"] = true | ctx.Data["PageIsTrainJob"] = true | ||||
| VersionOutputPath := modelarts.GetOutputPathByCount(modelarts.TotalVersionCount) | VersionOutputPath := modelarts.GetOutputPathByCount(modelarts.TotalVersionCount) | ||||
| jobName := form.JobName | |||||
| displayJobName := form.DisplayJobName | |||||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||||
| uuid := form.Attachment | uuid := form.Attachment | ||||
| description := form.Description | description := form.Description | ||||
| workServerNumber := form.WorkServerNumber | workServerNumber := form.WorkServerNumber | ||||
| @@ -897,6 +893,23 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
| ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form) | ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form) | ||||
| return | return | ||||
| } | } | ||||
| //Determine whether the task name of the task in the project is duplicated | |||||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeTrain), displayJobName) | |||||
| if err == nil { | |||||
| if len(tasks) != 0 { | |||||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("the job name did already exist", tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| } else { | |||||
| if !models.IsErrJobNotExist(err) { | |||||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("system error", tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| } | |||||
| //todo: del the codeLocalPath | //todo: del the codeLocalPath | ||||
| _, err = ioutil.ReadDir(codeLocalPath) | _, err = ioutil.ReadDir(codeLocalPath) | ||||
| @@ -910,9 +923,9 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
| if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{ | if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{ | ||||
| Branch: branch_name, | Branch: branch_name, | ||||
| }); err != nil { | }); err != nil { | ||||
| log.Error("创建任务失败,服务器超时!: %s (%v)", repo.FullName(), err) | |||||
| log.Error("Create task failed, server timed out: %s (%v)", repo.FullName(), err) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | trainJobErrorNewDataPrepare(ctx, form) | ||||
| ctx.RenderWithErr("创建任务失败,服务器超时!", tplModelArtsTrainJobNew, &form) | |||||
| ctx.RenderWithErr("Create task failed, server timed out", tplModelArtsTrainJobNew, &form) | |||||
| return | return | ||||
| } | } | ||||
| @@ -1006,6 +1019,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||||
| req := &modelarts.GenerateTrainJobReq{ | req := &modelarts.GenerateTrainJobReq{ | ||||
| JobName: jobName, | JobName: jobName, | ||||
| DisplayJobName: displayJobName, | |||||
| DataUrl: dataPath, | DataUrl: dataPath, | ||||
| Description: description, | Description: description, | ||||
| CodeObsPath: codeObsPath, | CodeObsPath: codeObsPath, | ||||
| @@ -1072,6 +1086,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
| } | } | ||||
| VersionOutputPath := modelarts.GetOutputPathByCount(latestTask.TotalVersionCount + 1) | VersionOutputPath := modelarts.GetOutputPathByCount(latestTask.TotalVersionCount + 1) | ||||
| displayJobName := form.DisplayJobName | |||||
| jobName := form.JobName | jobName := form.JobName | ||||
| uuid := form.Attachment | uuid := form.Attachment | ||||
| description := form.Description | description := form.Description | ||||
| @@ -1094,7 +1109,6 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
| EngineName := form.EngineName | EngineName := form.EngineName | ||||
| isLatestVersion := modelarts.IsLatestVersion | isLatestVersion := modelarts.IsLatestVersion | ||||
| //判断权限 | |||||
| canNewJob, _ := canUserCreateTrainJobVersion(ctx, latestTask.UserID) | canNewJob, _ := canUserCreateTrainJobVersion(ctx, latestTask.UserID) | ||||
| if !canNewJob { | if !canNewJob { | ||||
| ctx.RenderWithErr("user cann't new trainjob", tplModelArtsTrainJobVersionNew, &form) | ctx.RenderWithErr("user cann't new trainjob", tplModelArtsTrainJobVersionNew, &form) | ||||
| @@ -1112,22 +1126,16 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
| _, err = ioutil.ReadDir(codeLocalPath) | _, err = ioutil.ReadDir(codeLocalPath) | ||||
| if err == nil { | if err == nil { | ||||
| os.RemoveAll(codeLocalPath) | os.RemoveAll(codeLocalPath) | ||||
| } else { | |||||
| log.Error("创建任务失败,原代码还未删除,请重试!: %s (%v)", repo.FullName(), err) | |||||
| versionErrorDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("创建任务失败,原代码还未删除,请重试!", tplModelArtsTrainJobVersionNew, &form) | |||||
| return | |||||
| } | } | ||||
| // os.RemoveAll(codeLocalPath) | |||||
| gitRepo, _ := git.OpenRepository(repo.RepoPath()) | gitRepo, _ := git.OpenRepository(repo.RepoPath()) | ||||
| commitID, _ := gitRepo.GetBranchCommitID(branch_name) | commitID, _ := gitRepo.GetBranchCommitID(branch_name) | ||||
| if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{ | if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{ | ||||
| Branch: branch_name, | Branch: branch_name, | ||||
| }); err != nil { | }); err != nil { | ||||
| log.Error("创建任务失败,任务名称已存在!: %s (%v)", repo.FullName(), err) | |||||
| log.Error("Failed git clone repo to local(!: %s (%v)", repo.FullName(), err) | |||||
| versionErrorDataPrepare(ctx, form) | versionErrorDataPrepare(ctx, form) | ||||
| ctx.RenderWithErr("创建任务失败,任务名称已存在!", tplModelArtsTrainJobVersionNew, &form) | |||||
| ctx.RenderWithErr("Failed git clone repo to local!", tplModelArtsTrainJobVersionNew, &form) | |||||
| return | return | ||||
| } | } | ||||
| @@ -1233,7 +1241,8 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ | |||||
| return | return | ||||
| } | } | ||||
| req := &modelarts.GenerateTrainJobReq{ | req := &modelarts.GenerateTrainJobReq{ | ||||
| JobName: task.JobName, | |||||
| JobName: jobName, | |||||
| DisplayJobName: displayJobName, | |||||
| DataUrl: dataPath, | DataUrl: dataPath, | ||||
| Description: description, | Description: description, | ||||
| CodeObsPath: codeObsPath, | CodeObsPath: codeObsPath, | ||||
| @@ -1463,7 +1472,7 @@ func TrainJobShow(ctx *context.Context) { | |||||
| pager.SetDefaultParams(ctx) | pager.SetDefaultParams(ctx) | ||||
| ctx.Data["Page"] = pager | ctx.Data["Page"] = pager | ||||
| ctx.Data["jobID"] = jobID | ctx.Data["jobID"] = jobID | ||||
| ctx.Data["jobName"] = VersionListTasks[0].JobName | |||||
| ctx.Data["displayJobName"] = VersionListTasks[0].DisplayJobName | |||||
| ctx.Data["version_list_task"] = VersionListTasks | ctx.Data["version_list_task"] = VersionListTasks | ||||
| ctx.Data["version_list_count"] = VersionListCount | ctx.Data["version_list_count"] = VersionListCount | ||||
| ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, &VersionListTasks[0].Cloudbrain) | ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, &VersionListTasks[0].Cloudbrain) | ||||
| @@ -1664,7 +1673,8 @@ func getConfigList(perPage, page int, sortBy, order, searchContent, configType s | |||||
| func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInferenceJobForm) { | func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInferenceJobForm) { | ||||
| ctx.Data["PageIsTrainJob"] = true | ctx.Data["PageIsTrainJob"] = true | ||||
| VersionOutputPath := modelarts.GetOutputPathByCount(modelarts.TotalVersionCount) | VersionOutputPath := modelarts.GetOutputPathByCount(modelarts.TotalVersionCount) | ||||
| jobName := form.JobName | |||||
| displayJobName := form.DisplayJobName | |||||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||||
| uuid := form.Attachment | uuid := form.Attachment | ||||
| description := form.Description | description := form.Description | ||||
| workServerNumber := form.WorkServerNumber | workServerNumber := form.WorkServerNumber | ||||
| @@ -1692,13 +1702,6 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
| ckptUrl := form.TrainUrl + form.CkptName | ckptUrl := form.TrainUrl + form.CkptName | ||||
| if err := paramCheckCreateInferenceJob(form); err != nil { | |||||
| log.Error("paramCheckCreateInferenceJob failed:(%v)", err) | |||||
| inferenceJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr(err.Error(), tplModelArtsInferenceJobNew, &form) | |||||
| return | |||||
| } | |||||
| count, err := models.GetCloudbrainInferenceJobCountByUserID(ctx.User.ID) | count, err := models.GetCloudbrainInferenceJobCountByUserID(ctx.User.ID) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetCloudbrainInferenceJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) | log.Error("GetCloudbrainInferenceJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) | ||||
| @@ -1714,6 +1717,31 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
| } | } | ||||
| } | } | ||||
| if err := paramCheckCreateInferenceJob(form); err != nil { | |||||
| log.Error("paramCheckCreateInferenceJob failed:(%v)", err) | |||||
| inferenceJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr(err.Error(), tplModelArtsInferenceJobNew, &form) | |||||
| return | |||||
| } | |||||
| //Determine whether the task name of the task in the project is duplicated | |||||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeInference), displayJobName) | |||||
| if err == nil { | |||||
| if len(tasks) != 0 { | |||||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||||
| inferenceJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("the job name did already exist", tplModelArtsInferenceJobNew, &form) | |||||
| return | |||||
| } | |||||
| } else { | |||||
| if !models.IsErrJobNotExist(err) { | |||||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||||
| inferenceJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("system error", tplModelArtsInferenceJobNew, &form) | |||||
| return | |||||
| } | |||||
| } | |||||
| //todo: del the codeLocalPath | //todo: del the codeLocalPath | ||||
| _, err = ioutil.ReadDir(codeLocalPath) | _, err = ioutil.ReadDir(codeLocalPath) | ||||
| if err == nil { | if err == nil { | ||||
| @@ -1726,9 +1754,9 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
| if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{ | if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{ | ||||
| Branch: branch_name, | Branch: branch_name, | ||||
| }); err != nil { | }); err != nil { | ||||
| log.Error("创建任务失败,服务器超时!: %s (%v)", repo.FullName(), err) | |||||
| log.Error("Create task failed, server timed out: %s (%v)", repo.FullName(), err) | |||||
| inferenceJobErrorNewDataPrepare(ctx, form) | inferenceJobErrorNewDataPrepare(ctx, form) | ||||
| ctx.RenderWithErr("创建任务失败,服务器超时!", tplModelArtsInferenceJobNew, &form) | |||||
| ctx.RenderWithErr("Create task failed, server timed out", tplModelArtsInferenceJobNew, &form) | |||||
| return | return | ||||
| } | } | ||||
| @@ -1785,6 +1813,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
| req := &modelarts.GenerateInferenceJobReq{ | req := &modelarts.GenerateInferenceJobReq{ | ||||
| JobName: jobName, | JobName: jobName, | ||||
| DisplayJobName: displayJobName, | |||||
| DataUrl: dataPath, | DataUrl: dataPath, | ||||
| Description: description, | Description: description, | ||||
| CodeObsPath: codeObsPath, | CodeObsPath: codeObsPath, | ||||
| @@ -1797,7 +1826,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
| LogUrl: logObsPath, | LogUrl: logObsPath, | ||||
| PoolID: poolID, | PoolID: poolID, | ||||
| Uuid: uuid, | Uuid: uuid, | ||||
| Parameters: param, //modelarts训练时用到 | |||||
| Parameters: param, //modelarts train parameters | |||||
| CommitID: commitID, | CommitID: commitID, | ||||
| BranchName: branch_name, | BranchName: branch_name, | ||||
| Params: form.Params, | Params: form.Params, | ||||
| @@ -1813,13 +1842,6 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||||
| ResultUrl: resultObsPath, | ResultUrl: resultObsPath, | ||||
| } | } | ||||
| //将params转换Parameters.Parameter,出错时返回给前端 | |||||
| // var Parameters modelarts.Parameters | |||||
| // if err := json.Unmarshal([]byte(params), &Parameters); err != nil { | |||||
| // ctx.ServerError("json.Unmarshal failed:", err) | |||||
| // return | |||||
| // } | |||||
| err = modelarts.GenerateInferenceJob(ctx, req) | err = modelarts.GenerateInferenceJob(ctx, req) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("GenerateTrainJob failed:%v", err.Error()) | log.Error("GenerateTrainJob failed:%v", err.Error()) | ||||
| @@ -1895,8 +1917,8 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { | |||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| t := time.Now() | t := time.Now() | ||||
| var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["job_name"] = jobName | |||||
| var displayJobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["display_job_name"] = displayJobName | |||||
| attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -2070,6 +2092,7 @@ func InferenceJobShow(ctx *context.Context) { | |||||
| ctx.Data["labelName"] = LabelName | ctx.Data["labelName"] = LabelName | ||||
| ctx.Data["jobID"] = jobID | ctx.Data["jobID"] = jobID | ||||
| ctx.Data["jobName"] = task.JobName | ctx.Data["jobName"] = task.JobName | ||||
| ctx.Data["displayJobName"] = task.DisplayJobName | |||||
| ctx.Data["task"] = task | ctx.Data["task"] = task | ||||
| ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, task) | ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, task) | ||||
| @@ -2116,12 +2139,11 @@ func ResultDownload(ctx *context.Context) { | |||||
| err error | err error | ||||
| ) | ) | ||||
| var jobID = ctx.Params(":jobid") | |||||
| versionName := ctx.Query("version_name") | versionName := ctx.Query("version_name") | ||||
| parentDir := ctx.Query("parent_dir") | parentDir := ctx.Query("parent_dir") | ||||
| fileName := ctx.Query("file_name") | fileName := ctx.Query("file_name") | ||||
| log.Info("DownloadResult start.") | log.Info("DownloadResult start.") | ||||
| task, err := models.GetCloudbrainByJobID(jobID) | |||||
| task := ctx.Cloudbrain | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Data["error"] = err.Error() | ctx.Data["error"] = err.Error() | ||||
| } | } | ||||
| @@ -2175,7 +2197,7 @@ func DownloadMultiResultFile(ctx *context.Context) { | |||||
| //count++ | //count++ | ||||
| // models.ModifyModelDownloadCount(id) | // models.ModifyModelDownloadCount(id) | ||||
| returnFileName := task.JobName + ".zip" | |||||
| returnFileName := task.DisplayJobName + ".zip" | |||||
| ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+returnFileName) | ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+returnFileName) | ||||
| ctx.Resp.Header().Set("Content-Type", "application/octet-stream") | ctx.Resp.Header().Set("Content-Type", "application/octet-stream") | ||||
| w := zip.NewWriter(ctx.Resp) | w := zip.NewWriter(ctx.Resp) | ||||
| @@ -992,10 +992,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| }, context.RepoRef()) | }, context.RepoRef()) | ||||
| m.Group("/cloudbrain", func() { | m.Group("/cloudbrain", func() { | ||||
| m.Group("/:jobname", func() { | |||||
| m.Group("/:id", func() { | |||||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainShow) | m.Get("", reqRepoCloudBrainReader, repo.CloudBrainShow) | ||||
| }) | |||||
| m.Group("/:jobid", func() { | |||||
| m.Get("/debug", cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDebug) | m.Get("/debug", cloudbrain.AdminOrJobCreaterRight, repo.CloudBrainDebug) | ||||
| m.Post("/commit_image", cloudbrain.AdminOrJobCreaterRight, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) | m.Post("/commit_image", cloudbrain.AdminOrJobCreaterRight, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) | ||||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | ||||
| @@ -1010,10 +1008,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Group("/benchmark", func() { | m.Group("/benchmark", func() { | ||||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainBenchmarkIndex) | m.Get("", reqRepoCloudBrainReader, repo.CloudBrainBenchmarkIndex) | ||||
| m.Group("/:jobname", func() { | |||||
| m.Group("/:id", func() { | |||||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainBenchMarkShow) | m.Get("", reqRepoCloudBrainReader, repo.CloudBrainBenchMarkShow) | ||||
| }) | |||||
| m.Group("/:jobid", func() { | |||||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | ||||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.BenchmarkDel) | m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.BenchmarkDel) | ||||
| m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate) | m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate) | ||||
| @@ -1061,7 +1057,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Get("/create", reqRepoCloudBrainWriter, repo.NotebookNew) | m.Get("/create", reqRepoCloudBrainWriter, repo.NotebookNew) | ||||
| m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsNotebookForm{}), repo.NotebookCreate) | m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsNotebookForm{}), repo.NotebookCreate) | ||||
| */ | */ | ||||
| m.Group("/:jobid", func() { | |||||
| m.Group("/:id", func() { | |||||
| m.Get("", reqRepoCloudBrainReader, repo.NotebookShow) | m.Get("", reqRepoCloudBrainReader, repo.NotebookShow) | ||||
| m.Get("/debug", cloudbrain.AdminOrJobCreaterRight, repo.NotebookDebug2) | m.Get("/debug", cloudbrain.AdminOrJobCreaterRight, repo.NotebookDebug2) | ||||
| m.Post("/:action", reqRepoCloudBrainWriter, repo.NotebookManage) | m.Post("/:action", reqRepoCloudBrainWriter, repo.NotebookManage) | ||||
| @@ -1075,11 +1071,11 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Get("", reqRepoCloudBrainReader, repo.TrainJobIndex) | m.Get("", reqRepoCloudBrainReader, repo.TrainJobIndex) | ||||
| m.Group("/:jobid", func() { | m.Group("/:jobid", func() { | ||||
| m.Get("", reqRepoCloudBrainReader, repo.TrainJobShow) | m.Get("", reqRepoCloudBrainReader, repo.TrainJobShow) | ||||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.TrainJobStop) | |||||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.TrainJobDel) | |||||
| m.Get("/model_download", cloudbrain.AdminOrJobCreaterRight, repo.ModelDownload) | |||||
| m.Get("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRight, repo.TrainJobNewVersion) | |||||
| m.Post("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRight, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreateVersion) | |||||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.TrainJobStop) | |||||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.TrainJobDel) | |||||
| m.Get("/model_download", cloudbrain.AdminOrJobCreaterRightForTrain, repo.ModelDownload) | |||||
| m.Get("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, repo.TrainJobNewVersion) | |||||
| m.Post("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreateVersion) | |||||
| }) | }) | ||||
| m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.TrainJobNew) | m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.TrainJobNew) | ||||
| m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreate) | m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreate) | ||||
| @@ -1091,7 +1087,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Get("", reqRepoCloudBrainReader, repo.InferenceJobIndex) | m.Get("", reqRepoCloudBrainReader, repo.InferenceJobIndex) | ||||
| m.Group("/:jobid", func() { | m.Group("/:jobid", func() { | ||||
| m.Get("", reqRepoCloudBrainReader, repo.InferenceJobShow) | m.Get("", reqRepoCloudBrainReader, repo.InferenceJobShow) | ||||
| m.Get("/result_download", cloudbrain.AdminOrJobCreaterRight, repo.ResultDownload) | |||||
| m.Get("/result_download", cloudbrain.AdminOrJobCreaterRightForTrain, repo.ResultDownload) | |||||
| m.Get("/downloadall", repo.DownloadMultiResultFile) | m.Get("/downloadall", repo.DownloadMultiResultFile) | ||||
| }) | }) | ||||
| m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.InferenceJobNew) | m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.InferenceJobNew) | ||||
| @@ -64,22 +64,29 @@ | |||||
| <div class="ui grid stackable item"> | <div class="ui grid stackable item"> | ||||
| <div class="row"> | <div class="row"> | ||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| {{$JobID := '0'}} | |||||
| {{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK"}} | |||||
| {{$JobID = .Cloudbrain.ID}} | |||||
| {{else}} | |||||
| {{$JobID = .JobID}} | |||||
| {{end}} | |||||
| <!-- {{$JobID}} --> | |||||
| <div class="two wide column nowrap"> | <div class="two wide column nowrap"> | ||||
| {{if or (eq .JobType "DEBUG") (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}} | {{if or (eq .JobType "DEBUG") (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}} | ||||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{.JobName}}{{else}}/modelarts/notebook/{{.JobID}}{{end}}" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{$JobID}}{{else}}/modelarts/notebook/{{$JobID}}{{end}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||||
| </a> | </a> | ||||
| {{else if eq .JobType "INFERENCE"}} | {{else if eq .JobType "INFERENCE"}} | ||||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{.JobID}}" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||||
| </a> | </a> | ||||
| {{else if eq .JobType "TRAIN"}} | {{else if eq .JobType "TRAIN"}} | ||||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/train-job/{{.JobID}}" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/train-job/{{$JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||||
| </a> | </a> | ||||
| {{else if eq .JobType "BENCHMARK"}} | {{else if eq .JobType "BENCHMARK"}} | ||||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{.JobName}}" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| @@ -89,8 +96,8 @@ | |||||
| </div> | </div> | ||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 10% !important;"> | <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 10% !important;"> | ||||
| <span class="job-status" id="{{.JobID}}" data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||||
| <span><i id="{{.JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||||
| <span class="job-status" id="{{$JobID}}" data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{$JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||||
| </span> | </span> | ||||
| </div> | </div> | ||||
| <!-- 任务创建时间 --> | <!-- 任务创建时间 --> | ||||
| @@ -99,7 +106,7 @@ | |||||
| </div> | </div> | ||||
| <!-- 任务运行时间 --> | <!-- 任务运行时间 --> | ||||
| <div class="one wide column text center nowrap"> | <div class="one wide column text center nowrap"> | ||||
| <span style="font-size: 12px;" id="duration-{{.JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||||
| <span style="font-size: 12px;" id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||||
| </div> | </div> | ||||
| <!-- 计算资源 --> | <!-- 计算资源 --> | ||||
| <div class="one wide column text center nowrap"> | <div class="one wide column text center nowrap"> | ||||
| @@ -119,19 +126,19 @@ | |||||
| </div> | </div> | ||||
| <!-- 云脑侧名称 --> | <!-- 云脑侧名称 --> | ||||
| <div class="two wide column text center nowrap" style="overflow: hidden;text-overflow:ellipsis;"> | <div class="two wide column text center nowrap" style="overflow: hidden;text-overflow:ellipsis;"> | ||||
| <span class="fitted">{{.JobName}}</span> | |||||
| <span class="fitted" title="{{.JobName}}">{{.JobName}}</span> | |||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | ||||
| {{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE"}} | {{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE"}} | ||||
| <div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
| <form id="debugAgainForm-{{.JobID}}"> | |||||
| <form id="debugAgainForm-{{$JobID}}"> | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | ||||
| <a style="margin: 0 1rem;" id="ai-debug-{{.JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' data-jobid="{{.JobID}}" data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/'> | |||||
| <a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' data-jobid="{{$JobID}}" data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'> | |||||
| {{$.i18n.Tr "repo.debug"}} | {{$.i18n.Tr "repo.debug"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| <a id="ai-debug-{{.JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' data-jobid="{{.JobID}}" data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/'> | |||||
| <a id="ai-debug-{{$JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' data-jobid="{{$JobID}}" data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'> | |||||
| {{$.i18n.Tr "repo.debug_again"}} | {{$.i18n.Tr "repo.debug_again"}} | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| @@ -141,22 +148,22 @@ | |||||
| <!-- 停止任务 --> | <!-- 停止任务 --> | ||||
| <div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
| {{if eq .JobType "DEBUG" "BENCHMARK" "SNN4IMAGENET" "BRAINSCORE"}} | {{if eq .JobType "DEBUG" "BENCHMARK" "SNN4IMAGENET" "BRAINSCORE"}} | ||||
| <form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | |||||
| <form id="stopForm-{{$JobID}}" style="margin-left:-1px;"> | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class='ui basic ai_stop {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED" "STOPPING"}}disabled {{else}} blue {{end}}button' data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}/{{.JobID}}/stop' data-jobid="{{.JobID}}"> | |||||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class='ui basic ai_stop {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED" "STOPPING"}}disabled {{else}} blue {{end}}button' data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}/{{$JobID}}/stop' data-jobid="{{$JobID}}"> | |||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| </form> | </form> | ||||
| {{else}} | {{else}} | ||||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class="ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED"}}disabled {{else}} blue {{end}}button" data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/{{if eq .JobType "INFERENCE"}}inference-job{{else}}train-job{{end}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}" > | |||||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class="ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED"}}disabled {{else}} blue {{end}}button" data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/{{if eq .JobType "INFERENCE"}}inference-job{{else}}train-job{{end}}" data-jobid="{{$JobID}}" data-version="{{.VersionName}}" > | |||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <!-- 删除任务 --> | <!-- 删除任务 --> | ||||
| <form class="ui compact buttons" id="delForm-{{.JobID}}" action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{end}}/{{.JobID}}/del?isadminpage=true' method="post"> | |||||
| <form class="ui compact buttons" id="delForm-{{$JobID}}" action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{end}}/{{$JobID}}/del?isadminpage=true' method="post"> | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{.JobID}}/del_version?isadminpage=true" data-version="{{.VersionName}}" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | |||||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}/del_version?isadminpage=true" data-version="{{.VersionName}}" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| </form> | </form> | ||||
| @@ -164,25 +171,31 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{else}} | {{else}} | ||||
| {{$JobID := '0'}} | |||||
| {{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK"}} | |||||
| {{$JobID = .Cloudbrain.ID}} | |||||
| {{else}} | |||||
| {{$JobID = .JobID}} | |||||
| {{end}} | |||||
| <div class="ui grid stackable item"> | <div class="ui grid stackable item"> | ||||
| <div class="row"> | <div class="row"> | ||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="two wide column nowrap"> | <div class="two wide column nowrap"> | ||||
| {{if eq .JobType "DEBUG"}} | {{if eq .JobType "DEBUG"}} | ||||
| <a class="title" href="" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||||
| </a> | </a> | ||||
| {{else if eq .JobType "INFERENCE"}} | {{else if eq .JobType "INFERENCE"}} | ||||
| <a class="title" href="" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||||
| </a> | </a> | ||||
| {{else if eq .JobType "TRAIN"}} | {{else if eq .JobType "TRAIN"}} | ||||
| <a class="title" href="" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||||
| </a> | </a> | ||||
| {{else if eq .JobType "BENCHMARK"}} | {{else if eq .JobType "BENCHMARK"}} | ||||
| <a class="title" href="" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| @@ -192,8 +205,8 @@ | |||||
| </div> | </div> | ||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 10% !important;"> | <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 10% !important;"> | ||||
| <span class="job-status" id="{{.JobID}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||||
| <span><i id="{{.JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||||
| <span class="job-status" id="{{$JobID}}" data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{$JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||||
| </span> | </span> | ||||
| </div> | </div> | ||||
| <!-- 任务创建时间 --> | <!-- 任务创建时间 --> | ||||
| @@ -202,7 +215,7 @@ | |||||
| </div> | </div> | ||||
| <!-- 任务运行时间 --> | <!-- 任务运行时间 --> | ||||
| <div class="one wide column text center nowrap"> | <div class="one wide column text center nowrap"> | ||||
| <span style="font-size: 12px;" id="duration-{{.JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||||
| <span style="font-size: 12px;" id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||||
| </div> | </div> | ||||
| <!-- 计算资源 --> | <!-- 计算资源 --> | ||||
| <div class="one wide column text center nowrap"> | <div class="one wide column text center nowrap"> | ||||
| @@ -227,14 +240,14 @@ | |||||
| <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | ||||
| {{if eq .JobType "DEBUG"}} | {{if eq .JobType "DEBUG"}} | ||||
| <div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
| <form id="debugAgainForm-{{.JobID}}"> | |||||
| <form id="debugAgainForm-{{$JobID}}"> | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | ||||
| <a style="margin: 0 1rem;" id="ai-debug-{{.JobID}}" class='ui basic disabled button' > | |||||
| <a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}" class='ui basic disabled button' > | |||||
| {{$.i18n.Tr "repo.debug"}} | {{$.i18n.Tr "repo.debug"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| <a id="ai-debug-{{.JobID}}" class='ui basic disabled button' > | |||||
| <a id="ai-debug-{{$JobID}}" class='ui basic disabled button' > | |||||
| {{$.i18n.Tr "repo.debug_again"}} | {{$.i18n.Tr "repo.debug_again"}} | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| @@ -243,14 +256,14 @@ | |||||
| {{end}} | {{end}} | ||||
| <!-- 停止任务 --> | <!-- 停止任务 --> | ||||
| <div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class="ui basic disabled button" data-jobid="{{.JobID}}" data-version="{{.VersionName}}" > | |||||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class="ui basic disabled button" data-jobid="{{$JobID}}" data-version="{{.VersionName}}" > | |||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <!-- 删除任务 --> | <!-- 删除任务 --> | ||||
| <form class="ui compact buttons" id="delForm-{{.JobID}}" action='' method="post"> | |||||
| <form class="ui compact buttons" id="delForm-{{$JobID}}" action='' method="post"> | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic disabled button" style="border-radius: .28571429rem;"> | |||||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" class="ui basic disabled button" style="border-radius: .28571429rem;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| </form> | </form> | ||||
| @@ -29,16 +29,17 @@ | |||||
| <div class="ui mobile reversed stackable grid"> | <div class="ui mobile reversed stackable grid"> | ||||
| <div class="ui sixteen wide tablet sixteen wide computer column margin-bottom20 pad-botom maxheight" id='key_tag'> | <div class="ui sixteen wide tablet sixteen wide computer column margin-bottom20 pad-botom maxheight" id='key_tag'> | ||||
| {{if .OrgTopics}} | {{if .OrgTopics}} | ||||
| <a class="{{if eq $.Keyword "" }} tag_bg {{end}} tag_key ui small tag_lable topic omit" href="{{$.Link}}?" >{{$.i18n.Tr "org.all_org_topics"}}</span></a> | |||||
| <a class="{{if eq $.Keyword "" }} tag_bg {{end}} tag_key ui small tag_lable topic omit" href="{{$.Link}}?" onclick="iscontinueStatus()" id="tag_a">{{$.i18n.Tr "org.all_org_topics"}}</a> | |||||
| {{end}} | {{end}} | ||||
| {{range .OrgTopics}} | {{range .OrgTopics}} | ||||
| {{if ne .Name ""}} | {{if ne .Name ""}} | ||||
| <a class="{{if eq $.Keyword .Name }} tag_bg {{end}} tag_key ui small tag_lable topic omit" href="{{$.Link}}?q={{.Name}}" > | |||||
| <a class="{{if eq $.Keyword .Name }} tag_bg {{end}} tag_key ui small tag_lable topic omit" href="{{$.Link}}?q={{.Name}}" onclick="iscontinueStatus()"> | |||||
| {{.Name}} | {{.Name}} | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| {{end}} | {{end}} | ||||
| {{if .OrgTopics}} | {{if .OrgTopics}} | ||||
| <a class=" tag_key ui small tag_lable topic omit icon_a" onclick="isUnfold()" id="icon_btn" > | <a class=" tag_key ui small tag_lable topic omit icon_a" onclick="isUnfold()" id="icon_btn" > | ||||
| <i class="ri-arrow-down-s-line" style="display:inline-block;vertical-align:top"></i> | <i class="ri-arrow-down-s-line" style="display:inline-block;vertical-align:top"></i> | ||||
| @@ -136,14 +137,38 @@ | |||||
| <script> | <script> | ||||
| function isUnfold(){ | function isUnfold(){ | ||||
| // var isTrue = document.getElementById("tag_a").getAttribute("data-tag") | |||||
| var isContain= document.querySelector("#key_tag").classList.contains("maxheight"); | var isContain= document.querySelector("#key_tag").classList.contains("maxheight"); | ||||
| if(isContain){ | |||||
| if(isContain){ | |||||
| document.querySelector("#key_tag").classList.remove("maxheight"); | document.querySelector("#key_tag").classList.remove("maxheight"); | ||||
| document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-up-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.fold"}}" | document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-up-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.fold"}}" | ||||
| localStorage.setItem("isunfold",true) | |||||
| }else{ | }else{ | ||||
| document.querySelector("#key_tag").classList.add("maxheight"); | document.querySelector("#key_tag").classList.add("maxheight"); | ||||
| document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-down-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.unfold"}}" | document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-down-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.unfold"}}" | ||||
| localStorage.setItem("isunfold",false) | |||||
| } | } | ||||
| } | } | ||||
| function isShowIconBtn(){ | |||||
| var key_height = document.getElementById("key_tag").offsetHeight | |||||
| var parent = document.getElementById("key_tag") | |||||
| var child = document.getElementById("icon_btn") | |||||
| if (key_height < 88){ | |||||
| parent.removeChild(child) | |||||
| } | |||||
| } | |||||
| function iscontinueStatus(){ | |||||
| var isunfold = localStorage.getItem("isunfold") | |||||
| if (isunfold == "true" || isunfold == true){ | |||||
| document.querySelector("#key_tag").classList.remove("maxheight"); | |||||
| document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-up-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.fold"}}" | |||||
| }else{ | |||||
| document.querySelector("#key_tag").classList.add("maxheight"); | |||||
| document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-down-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.unfold"}}" | |||||
| } | |||||
| } | |||||
| isShowIconBtn() | |||||
| iscontinueStatus() | |||||
| </script> | </script> | ||||
| @@ -102,14 +102,14 @@ | |||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="three wide column padding0"> | <div class="three wide column padding0"> | ||||
| <a class="title" href="{{$.Link}}/{{.JobName}}" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||||
| <a class="title" href="{{$.Link}}/{{.Cloudbrain.ID}}" title="{{.Cloudbrain.ID}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column padding0" style="padding-left: 2.2rem !important;"> | <div class="two wide column padding0" style="padding-left: 2.2rem !important;"> | ||||
| <span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||||
| <span><i id="{{.JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||||
| <span class="job-status" id="{{.Cloudbrain.ID}}" data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}" data-jobid="{{.Cloudbrain.ID}}" data-version="{{.VersionName}}"> | |||||
| <span><i id="{{.Cloudbrain.ID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.Cloudbrain.ID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||||
| </span> | </span> | ||||
| </div> | </div> | ||||
| <div class="two wide column text center padding0"> | <div class="two wide column text center padding0"> | ||||
| @@ -123,7 +123,7 @@ | |||||
| </div> | </div> | ||||
| <!-- 任务运行时间 --> | <!-- 任务运行时间 --> | ||||
| <div class="one wide column text center padding0"> | <div class="one wide column text center padding0"> | ||||
| <span style="font-size: 12px;" id="duration-{{.JobID}}">{{.TrainJobDuration}}</span> | |||||
| <span style="font-size: 12px;" id="duration-{{.Cloudbrain.ID}}">{{.TrainJobDuration}}</span> | |||||
| </div> | </div> | ||||
| <!-- 计算资源 --> | <!-- 计算资源 --> | ||||
| <div class="two wide column text center padding0"> | <div class="two wide column text center padding0"> | ||||
| @@ -141,10 +141,10 @@ | |||||
| <div class="three wide column text center padding0"> | <div class="three wide column text center padding0"> | ||||
| <div class="ui compact buttons" > | <div class="ui compact buttons" > | ||||
| <!-- 停止任务 --> | <!-- 停止任务 --> | ||||
| <form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | |||||
| <form id="stopForm-{{.Cloudbrain.ID}}" style="margin-left:-1px;"> | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a id="ai-stop-{{.JobID}}" class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/stop" data-jobid="{{.JobID}}"> | |||||
| <a id="ai-stop-{{.Cloudbrain.ID}}" class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/stop" data-jobid="{{.Cloudbrain.ID}}"> | |||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| @@ -154,16 +154,16 @@ | |||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </form> | </form> | ||||
| <a class="ui basic button {{if $.IsSigned}} blue{{else}} disabled{{end}}" href="{{$.RepoLink}}/cloudbrain/{{.JobID}}/rate" target="_blank"> | |||||
| <a class="ui basic button {{if $.IsSigned}} blue{{else}} disabled{{end}}" href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/rate" target="_blank"> | |||||
| 评分 | 评分 | ||||
| </a> | </a> | ||||
| <!-- 删除任务 --> | <!-- 删除任务 --> | ||||
| <form id="delForm-{{.JobID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/benchmark{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}/del" method="post"> | |||||
| <form id="delForm-{{.Cloudbrain.ID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/benchmark{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/del" method="post"> | |||||
| <input type="hidden" name="debugListType" value="all"> | <input type="hidden" name="debugListType" value="all"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a id="ai-delete-{{.JobID}}" class='ui basic ai_delete {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "SUCCEEDED"}}blue {{else}}disabled {{end}}button' style="border-radius: .28571429rem;"> | |||||
| <a id="ai-delete-{{.Cloudbrain.ID}}" class='ui basic ai_delete {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "SUCCEEDED"}}blue {{else}}disabled {{end}}button' style="border-radius: .28571429rem;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| @@ -82,7 +82,7 @@ | |||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 80%;" name="job_name" id="trainjob_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.job_name}}" tabindex="3" autofocus required maxlength="254"> | |||||
| <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="254"> | |||||
| </div> | </div> | ||||
| <div class="unite min_title inline field"> | <div class="unite min_title inline field"> | ||||
| <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | ||||
| @@ -124,7 +124,7 @@ | |||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_mirror"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_mirror"}}</label> | ||||
| <span> </span> | <span> </span> | ||||
| <input type="text" list="cloudbrain_image" placeholder="选择镜像" name="image" value="{{.image}}" class="required autofocus" style='width:492px;' maxlength="254"> | |||||
| <input type="text" list="cloudbrain_image" placeholder="选择镜像或输入镜像地址" name="image" value="{{.image}}" class="required autofocus" style='width:492px;' maxlength="254"> | |||||
| <i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i> | <i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i> | ||||
| <datalist class="ui search" id="cloudbrain_image" style='width:385px;' name="image"> | <datalist class="ui search" id="cloudbrain_image" style='width:385px;' name="image"> | ||||
| {{range .images}} | {{range .images}} | ||||
| @@ -183,7 +183,7 @@ td, th { | |||||
| {{$.i18n.Tr "repo.modelarts.evaluate_job"}} | {{$.i18n.Tr "repo.modelarts.evaluate_job"}} | ||||
| </a> | </a> | ||||
| <div class="divider"> / </div> | <div class="divider"> / </div> | ||||
| <div class="active section">{{.jobName}}</div> | |||||
| <div class="active section">{{.displayJobName}}</div> | |||||
| </div> | </div> | ||||
| </h4> | </h4> | ||||
| {{range $k ,$v := .version_list_task}} | {{range $k ,$v := .version_list_task}} | ||||
| @@ -229,7 +229,7 @@ td, th { | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.JobName}} | |||||
| {{.DisplayJobName}} | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -6,7 +6,7 @@ | |||||
| <td class="name four wide"> | <td class="name four wide"> | ||||
| <span class="truncate"> | <span class="truncate"> | ||||
| <span class="octicon octicon-file-directory"></span> | <span class="octicon octicon-file-directory"></span> | ||||
| <a class="title" href="{{if .IsDir}}{{$.RepoLink}}/cloudbrain/{{$.JobID}}/models?parentDir={{.ParenDir}}{{else}}{{$.RepoLink}}/cloudbrain/{{$.JobID}}/download_model?parentDir={{.ParenDir}}&fileName={{.FileName}}&jobName={{$.task.JobName}}{{end}}"> | |||||
| <a class="title" href="{{if .IsDir}}{{$.RepoLink}}/cloudbrain/{{$.task.ID}}/models?parentDir={{.ParenDir}}{{else}}{{$.RepoLink}}/cloudbrain/{{$.task.ID}}/download_model?parentDir={{.ParenDir}}&fileName={{.FileName}}&jobName={{$.task.JobName}}{{end}}"> | |||||
| <span class="fitted">{{if .IsDir}} {{svg "octicon-file-directory" 16}}{{else}}{{svg "octicon-file" 16}}{{end}}</span> {{.FileName}} | <span class="fitted">{{if .IsDir}} {{svg "octicon-file-directory" 16}}{{else}}{{svg "octicon-file" 16}}{{end}}</span> {{.FileName}} | ||||
| </a> | </a> | ||||
| </span> | </span> | ||||
| @@ -1,7 +1,7 @@ | |||||
| {{template "base/head" .}} | {{template "base/head" .}} | ||||
| <style> | <style> | ||||
| /* 遮罩层css效果图 */ | /* 遮罩层css效果图 */ | ||||
| #mask { | #mask { | ||||
| position: fixed; | position: fixed; | ||||
| top: 0px; | top: 0px; | ||||
| @@ -18,7 +18,7 @@ | |||||
| color: #000000 | color: #000000 | ||||
| } | } | ||||
| /* 加载圈css效果图 */ | /* 加载圈css效果图 */ | ||||
| #loadingPage { | #loadingPage { | ||||
| margin: 200px auto; | margin: 200px auto; | ||||
| width: 50px; | width: 50px; | ||||
| @@ -27,7 +27,7 @@ | |||||
| font-size: 10px; | font-size: 10px; | ||||
| display: block; | display: block; | ||||
| } | } | ||||
| #loadingPage>div { | #loadingPage>div { | ||||
| background-color: green; | background-color: green; | ||||
| height: 100%; | height: 100%; | ||||
| @@ -36,27 +36,27 @@ | |||||
| -webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out; | -webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out; | ||||
| animation: sk-stretchdelay 1.2s infinite ease-in-out; | animation: sk-stretchdelay 1.2s infinite ease-in-out; | ||||
| } | } | ||||
| #loadingPage .rect2 { | #loadingPage .rect2 { | ||||
| -webkit-animation-delay: -1.1s; | -webkit-animation-delay: -1.1s; | ||||
| animation-delay: -1.1s; | animation-delay: -1.1s; | ||||
| } | } | ||||
| #loadingPage .rect3 { | #loadingPage .rect3 { | ||||
| -webkit-animation-delay: -1.0s; | -webkit-animation-delay: -1.0s; | ||||
| animation-delay: -1.0s; | animation-delay: -1.0s; | ||||
| } | } | ||||
| #loadingPage .rect4 { | #loadingPage .rect4 { | ||||
| -webkit-animation-delay: -0.9s; | -webkit-animation-delay: -0.9s; | ||||
| animation-delay: -0.9s; | animation-delay: -0.9s; | ||||
| } | } | ||||
| #loadingPage .rect5 { | #loadingPage .rect5 { | ||||
| -webkit-animation-delay: -0.8s; | -webkit-animation-delay: -0.8s; | ||||
| animation-delay: -0.8s; | animation-delay: -0.8s; | ||||
| } | } | ||||
| @-webkit-keyframes sk-stretchdelay { | @-webkit-keyframes sk-stretchdelay { | ||||
| 0%, | 0%, | ||||
| 40%, | 40%, | ||||
| @@ -67,7 +67,7 @@ | |||||
| -webkit-transform: scaleY(1.0) | -webkit-transform: scaleY(1.0) | ||||
| } | } | ||||
| } | } | ||||
| @keyframes sk-stretchdelay { | @keyframes sk-stretchdelay { | ||||
| 0%, | 0%, | ||||
| 40%, | 40%, | ||||
| @@ -80,7 +80,7 @@ | |||||
| -webkit-transform: scaleY(1.0); | -webkit-transform: scaleY(1.0); | ||||
| } | } | ||||
| } | } | ||||
| .inline.required.field.cloudbrain_benchmark { | .inline.required.field.cloudbrain_benchmark { | ||||
| display: none; | display: none; | ||||
| } | } | ||||
| @@ -128,7 +128,7 @@ | |||||
| </h3> | </h3> | ||||
| <div class="ui attached segment"> | <div class="ui attached segment"> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>计算资源</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||||
| <div class="ui blue small menu compact selectcloudbrain"> | <div class="ui blue small menu compact selectcloudbrain"> | ||||
| <a class="active item" href="{{.RepoLink}}/cloudbrain/create"> | <a class="active item" href="{{.RepoLink}}/cloudbrain/create"> | ||||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | ||||
| @@ -146,12 +146,12 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>任务名称</label> | |||||
| <input name="job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||||
| <label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | |||||
| <input name="display_job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>任务类型</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.task_type"}}</label> | |||||
| <select id="cloudbrain_job_type" class="ui search dropdown" placeholder="选择任务类型" style='width:385px' name="job_type"> | <select id="cloudbrain_job_type" class="ui search dropdown" placeholder="选择任务类型" style='width:385px' name="job_type"> | ||||
| <option name="job_type" value="DEBUG">DEBUG</option> | <option name="job_type" value="DEBUG">DEBUG</option> | ||||
| {{if .is_snn4imagenet_enabled}} | {{if .is_snn4imagenet_enabled}} | ||||
| @@ -179,7 +179,7 @@ | |||||
| <input id="store_category" type="hidden" name="get_benchmark_category"> | <input id="store_category" type="hidden" name="get_benchmark_category"> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>GPU类型</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||||
| <select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type"> | <select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type"> | ||||
| {{range .gpu_types}} | {{range .gpu_types}} | ||||
| <option value="{{.Queue}}">{{.Value}}</option> | <option value="{{.Queue}}">{{.Value}}</option> | ||||
| @@ -188,8 +188,8 @@ | |||||
| </div> | </div> | ||||
| <div class="inline required field" style="position: relative;"> | <div class="inline required field" style="position: relative;"> | ||||
| <label>镜像</label> | |||||
| <input type="text" list="cloudbrain_image" placeholder="选择镜像" name="image" required autofocus maxlength="255"> | |||||
| <label>{{.i18n.Tr "cloudbrain.mirror"}}</label> | |||||
| <input type="text" list="cloudbrain_image" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" name="image" required autofocus maxlength="255"> | |||||
| <i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i> | <i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i> | ||||
| <datalist class="ui search" id="cloudbrain_image" style='width:385px;' name="image"> | <datalist class="ui search" id="cloudbrain_image" style='width:385px;' name="image"> | ||||
| {{range .images}} | {{range .images}} | ||||
| @@ -202,9 +202,9 @@ | |||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>数据集</label> | |||||
| <select id="cloudbrain_dataset" class="ui search dropdown" placeholder="选择数据集" style='width:385px' name="attachment" required> | |||||
| <label>{{.i18n.Tr "cloudbrain.dataset"}}</label> | |||||
| <select id="cloudbrain_dataset" class="ui search dropdown" placeholder="选择数据集" style='width:385px' name="attachment" required> | |||||
| {{range .attachments}} | {{range .attachments}} | ||||
| <option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | <option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | ||||
| {{end}} | {{end}} | ||||
| @@ -212,7 +212,7 @@ | |||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>资源规格</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格" style='width:385px' name="resource_spec_id"> | <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格" style='width:385px' name="resource_spec_id"> | ||||
| {{range .resource_specs}} | {{range .resource_specs}} | ||||
| <option name="resource_spec_id" value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | <option name="resource_spec_id" value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | ||||
| @@ -221,31 +221,31 @@ | |||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>数据集存放路径</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.dataset_storage_path"}}</label> | |||||
| <input name="dataset_path" id="cloudbrain_dataset_path" value="{{.dataset_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | <input name="dataset_path" id="cloudbrain_dataset_path" value="{{.dataset_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | ||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>模型存放路径</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.model_storage_path"}}</label> | |||||
| <input name="model_path" id="cloudbrain_model_path" value="{{.model_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | <input name="model_path" id="cloudbrain_model_path" value="{{.model_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | ||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>代码存放路径</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.code_storage_path"}}</label> | |||||
| <input name="code_path" id="cloudbrain_code_path" value="{{.code_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | <input name="code_path" id="cloudbrain_code_path" value="{{.code_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | ||||
| </div> | </div> | ||||
| <div class="inline required field cloudbrain_benchmark"> | <div class="inline required field cloudbrain_benchmark"> | ||||
| <label>benchmark脚本存放路径</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.benchmark_path"}}</label> | |||||
| <input name="benchmark_path" id="cloudbrain_benchmark_path" value="{{.benchmark_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | <input name="benchmark_path" id="cloudbrain_benchmark_path" value="{{.benchmark_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | ||||
| </div> | </div> | ||||
| <div class="inline required field cloudbrain_snn4imagenet"> | <div class="inline required field cloudbrain_snn4imagenet"> | ||||
| <label>snn4imagenet脚本存放路径</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.snn4imagenet_path"}}</label> | |||||
| <input name="snn4imagenet_path" id="cloudbrain_snn4imagenet_path" value="{{.snn4imagenet_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | <input name="snn4imagenet_path" id="cloudbrain_snn4imagenet_path" value="{{.snn4imagenet_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | ||||
| </div> | </div> | ||||
| <div class="inline required field cloudbrain_brainscore"> | <div class="inline required field cloudbrain_brainscore"> | ||||
| <label>brainscore脚本存放路径</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.brainscore_path"}}</label> | |||||
| <input name="brainscore_path" id="cloudbrain_brainscore_path" value="{{.brainscore_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | <input name="brainscore_path" id="cloudbrain_brainscore_path" value="{{.brainscore_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | ||||
| </div> | </div> | ||||
| <div class="inline required field" hidden> | <div class="inline required field" hidden> | ||||
| <label>启动命令</label> | |||||
| <label>{{.i18n.Tr "cloudbrain.start_command"}}</label> | |||||
| <textarea name="command" rows="10" readonly="readonly">{{.command}}</textarea> | <textarea name="command" rows="10" readonly="readonly">{{.command}}</textarea> | ||||
| </div> | </div> | ||||
| @@ -259,7 +259,7 @@ | |||||
| </div> | </div> | ||||
| </form> | </form> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -279,7 +279,7 @@ | |||||
| $(".icon.icons").css("visibility","hidden") | $(".icon.icons").css("visibility","hidden") | ||||
| } | } | ||||
| form.onsubmit = function(e){ | form.onsubmit = function(e){ | ||||
| let value_task = $("input[name='job_name']").val() | |||||
| let value_task = $("input[name='display_job_name']").val() | |||||
| let value_image = $("input[name='image']").val() | let value_image = $("input[name='image']").val() | ||||
| let value_data = $("input[name='attachment']").val() | let value_data = $("input[name='attachment']").val() | ||||
| let re = /^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/ | let re = /^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/ | ||||
| @@ -291,9 +291,9 @@ | |||||
| return false | return false | ||||
| } | } | ||||
| let min_value_task = value_task.toLowerCase() | let min_value_task = value_task.toLowerCase() | ||||
| $("input[name='job_name']").attr("value",min_value_task) | |||||
| $("input[name='display_job_name']").attr("value",min_value_task) | |||||
| document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
| } | } | ||||
| // 页面加载完毕后遮罩层隐藏 | // 页面加载完毕后遮罩层隐藏 | ||||
| @@ -302,21 +302,21 @@ | |||||
| document.getElementById("mask").style.display = "none" | document.getElementById("mask").style.display = "none" | ||||
| } | } | ||||
| } | } | ||||
| $('#cloudbrain_benchmark_category') | $('#cloudbrain_benchmark_category') | ||||
| .dropdown({ | .dropdown({ | ||||
| placeholder: "选择数据集类别", | placeholder: "选择数据集类别", | ||||
| }) | |||||
| }) | |||||
| $('select.dropdown') | $('select.dropdown') | ||||
| .dropdown(); | .dropdown(); | ||||
| // $('#cloudbrain_image').select2({ | // $('#cloudbrain_image').select2({ | ||||
| // placeholder: "选择镜像" | // placeholder: "选择镜像" | ||||
| // }); | // }); | ||||
| $(".ui.button.reset").click(function(e){ | $(".ui.button.reset").click(function(e){ | ||||
| e.preventDefault() | e.preventDefault() | ||||
| $('#cloudbrain_benchmark_category') | $('#cloudbrain_benchmark_category') | ||||
| @@ -354,4 +354,4 @@ | |||||
| $('#store_category').attr("value", selected_value) | $('#store_category').attr("value", selected_value) | ||||
| }) | }) | ||||
| </script> | |||||
| </script> | |||||
| @@ -16,14 +16,14 @@ | |||||
| </a> | </a> | ||||
| <div class="divider"> / </div> | <div class="divider"> / </div> | ||||
| {{with .task}} | {{with .task}} | ||||
| <div class="active section">{{.JobName}}</div> | |||||
| <div class="active section">{{.DisplayJobName}}</div> | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| </h4> | </h4> | ||||
| <div> | <div> | ||||
| <div class="ui yellow segment"> | <div class="ui yellow segment"> | ||||
| {{with .task}} | {{with .task}} | ||||
| <p>任务名称: {{.JobName}}</p> | |||||
| <p>任务名称: {{.DisplayJobName}}</p> | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <div class="ui green segment"> | <div class="ui green segment"> | ||||
| @@ -189,7 +189,7 @@ | |||||
| margin-top: 0.4rem; | margin-top: 0.4rem; | ||||
| display: inline-block; | display: inline-block; | ||||
| } | } | ||||
| </style> | </style> | ||||
| <!-- 弹窗 --> | <!-- 弹窗 --> | ||||
| @@ -208,10 +208,10 @@ | |||||
| {{template "repo/header" .}} | {{template "repo/header" .}} | ||||
| {{template "base/alert" .}} | {{template "base/alert" .}} | ||||
| <!-- 提示框 --> | <!-- 提示框 --> | ||||
| <!-- 列表容器 --> | <!-- 列表容器 --> | ||||
| <div class="ui container"> | <div class="ui container"> | ||||
| <div class="ui two column stackable grid"> | <div class="ui two column stackable grid"> | ||||
| <div class="column"> | <div class="column"> | ||||
| <div class="ui blue small menu compact selectcloudbrain"> | <div class="ui blue small menu compact selectcloudbrain"> | ||||
| @@ -227,12 +227,12 @@ | |||||
| <div class="default text" style="color: rgba(0,0,0,.87);"></div> | <div class="default text" style="color: rgba(0,0,0,.87);"></div> | ||||
| <i class="dropdown icon"></i> | <i class="dropdown icon"></i> | ||||
| <div class="menu"> | <div class="menu"> | ||||
| <div class="item" data-value="all">全部</div> | |||||
| <div class="item" data-value="all">{{$.i18n.Tr "repo.gpu_type_all"}}</div> | |||||
| <div class="item" data-value="CPU/GPU">CPU/GPU</div> | <div class="item" data-value="CPU/GPU">CPU/GPU</div> | ||||
| <div class="item" data-value="NPU">NPU</div> | <div class="item" data-value="NPU">NPU</div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||||
| <a class="ui green button" href="{{.RepoLink}}/cloudbrain/create">{{$.i18n.Tr "repo.modelarts.train_job.new_debug"}}</a> | <a class="ui green button" href="{{.RepoLink}}/cloudbrain/create">{{$.i18n.Tr "repo.modelarts.train_job.new_debug"}}</a> | ||||
| {{else}} | {{else}} | ||||
| <a class="ui disabled button">{{$.i18n.Tr "repo.modelarts.train_job.new_debug"}}</a> | <a class="ui disabled button">{{$.i18n.Tr "repo.modelarts.train_job.new_debug"}}</a> | ||||
| @@ -272,29 +272,29 @@ | |||||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | ||||
| </div> | </div> | ||||
| <div class="two wide column text center"> | <div class="two wide column text center"> | ||||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||||
| </div> | </div> | ||||
| <div class="one wide column text center"> | <div class="one wide column text center"> | ||||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||||
| </div> | </div> | ||||
| <div class="five wide column text center"> | <div class="five wide column text center"> | ||||
| <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | ||||
| </div> | </div> | ||||
| </div> | |||||
| </div> | |||||
| </div> | </div> | ||||
| {{range .Tasks}} | {{range .Tasks}} | ||||
| <div class="ui grid stackable item"> | <div class="ui grid stackable item"> | ||||
| <div class="row"> | <div class="row"> | ||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="four wide column"> | <div class="four wide column"> | ||||
| <a class="title" href='{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/{{.JobName}}{{else}}{{$.RepoLink}}/modelarts/notebook/{{.JobID}}{{end}}?debugListType={{$.debugListType}}' title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted text_over" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||||
| <a class="title" href='{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}{{else}}{{$.RepoLink}}/modelarts/notebook/{{.Cloudbrain.ID}}{{end}}' title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted text_over" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <div class="two wide column text center"> | <div class="two wide column text center"> | ||||
| <!--任务状态 --> | <!--任务状态 --> | ||||
| <span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}" data-jobid="{{.JobID}}" data-resource="{{.ComputeResource}}"> | |||||
| <span><i id="{{.JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||||
| <span class="job-status" id="{{.Cloudbrain.ID}}" data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}" data-jobid="{{.Cloudbrain.ID}}" data-resource="{{.ComputeResource}}"> | |||||
| <span><i id="{{.Cloudbrain.ID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.Cloudbrain.ID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||||
| </span> | </span> | ||||
| </div> | </div> | ||||
| <div class="two wide column text center"> | <div class="two wide column text center"> | ||||
| @@ -313,22 +313,22 @@ | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <div class="five wide column text center"> | <div class="five wide column text center"> | ||||
| <div class="ui compact buttons"> | |||||
| <div class="ui compact buttons"> | |||||
| <!-- {{if and (ne .Status "WAITING") (ne .JobType "DEBUG")}} | <!-- {{if and (ne .Status "WAITING") (ne .JobType "DEBUG")}} | ||||
| <a class="ui basic button" href="{{$.Link}}/{{.JobID}}/rate" target="_blank"> | |||||
| <a class="ui basic button" href="{{$.Link}}/{{.Cloudbrain.ID}}/rate" target="_blank"> | |||||
| 评分 | 评分 | ||||
| </a> | </a> | ||||
| {{end}} --> | {{end}} --> | ||||
| <!-- 调试 --> | <!-- 调试 --> | ||||
| <form id="debugAgainForm-{{.JobID}}"> | |||||
| <form id="debugAgainForm-{{.Cloudbrain.ID}}"> | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDebug}} | {{if .CanDebug}} | ||||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | ||||
| <a style="margin: 0 1rem;" id="ai-debug-{{.JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' data-jobid="{{.JobID}}" data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/'> | |||||
| <a style="margin: 0 1rem;" id="ai-debug-{{.Cloudbrain.ID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' data-jobid="{{.Cloudbrain.ID}}" data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/'> | |||||
| {{$.i18n.Tr "repo.debug"}} | {{$.i18n.Tr "repo.debug"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| <a id="ai-debug-{{.JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' data-jobid="{{.JobID}}" data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/' data-linkpath='{{$.Link}}'> | |||||
| <a id="ai-debug-{{.Cloudbrain.ID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' data-jobid="{{.Cloudbrain.ID}}" data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/' data-linkpath='{{$.Link}}'> | |||||
| {{$.i18n.Tr "repo.debug_again"}} | {{$.i18n.Tr "repo.debug_again"}} | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| @@ -344,12 +344,12 @@ | |||||
| {{end}} | {{end}} | ||||
| {{end}} | {{end}} | ||||
| </form> | </form> | ||||
| <!-- 停止 --> | <!-- 停止 --> | ||||
| <form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | |||||
| <form id="stopForm-{{.Cloudbrain.ID}}" style="margin-left:-1px;"> | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a id="ai-stop-{{.JobID}}" class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.JobID}}/stop" data-jobid="{{.JobID}}"> | |||||
| <a id="ai-stop-{{.Cloudbrain.ID}}" class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/stop" data-jobid="{{.Cloudbrain.ID}}"> | |||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| @@ -359,11 +359,11 @@ | |||||
| {{end}} | {{end}} | ||||
| </form> | </form> | ||||
| <!-- 删除 --> | <!-- 删除 --> | ||||
| <form id="delForm-{{.JobID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}/del" method="post"> | |||||
| <form id="delForm-{{.Cloudbrain.ID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/del" method="post"> | |||||
| <input type="hidden" name="debugListType" value="{{$.ListType}}"> | <input type="hidden" name="debugListType" value="{{$.ListType}}"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a id="ai-delete-{{.JobID}}" class='ui basic ai_delete {{if eq .Status "STOPPED" "FAILED" "START_FAILED"}}blue {{else}}disabled {{end}}button' style="border-radius: .28571429rem;"> | |||||
| <a id="ai-delete-{{.Cloudbrain.ID}}" class='ui basic ai_delete {{if eq .Status "STOPPED" "FAILED" "START_FAILED"}}blue {{else}}disabled {{end}}button' style="border-radius: .28571429rem;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| @@ -371,18 +371,18 @@ | |||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </form> | |||||
| </div> | |||||
| </form> | |||||
| </div> | |||||
| <div class="ui compact buttons" style="{{if eq .ComputeResource "CPU/GPU"}} visibility: visible {{else}} visibility: hidden{{end}}"> | <div class="ui compact buttons" style="{{if eq .ComputeResource "CPU/GPU"}} visibility: visible {{else}} visibility: hidden{{end}}"> | ||||
| <div class="ui dropdown" id="model_more" style="padding: .58928571em 1.125em .58928571em;"> | <div class="ui dropdown" id="model_more" style="padding: .58928571em 1.125em .58928571em;"> | ||||
| <div class="text">更多</div> | |||||
| <div class="text">{{$.i18n.Tr "repo.more"}}</div> | |||||
| <i class="dropdown icon"></i> | <i class="dropdown icon"></i> | ||||
| <div class="menu" style="right: auto;"> | <div class="menu" style="right: auto;"> | ||||
| <div class="item" style="padding: 0 !important;"> | <div class="item" style="padding: 0 !important;"> | ||||
| <!-- 接收结果 --> | <!-- 接收结果 --> | ||||
| <iframe src="" frameborder="0" name="iframeContent" style="display: none;"></iframe> | <iframe src="" frameborder="0" name="iframeContent" style="display: none;"></iframe> | ||||
| {{if .CanDebug}} | {{if .CanDebug}} | ||||
| <a id="model-image-{{.JobID}}" class='imageBtn ui basic {{if ne .Status "RUNNING"}}disabled {{else}}blue {{end}}button'>{{$.i18n.Tr "repo.submit_image"}}</a> | |||||
| <a id="model-image-{{.Cloudbrain.ID}}" class='imageBtn ui basic {{if ne .Status "RUNNING"}}disabled {{else}}blue {{end}}button'>{{$.i18n.Tr "repo.submit_image"}}</a> | |||||
| {{else}} | {{else}} | ||||
| <a class="imageBtn ui basic disabled button">{{$.i18n.Tr "repo.submit_image"}}</a> | <a class="imageBtn ui basic disabled button">{{$.i18n.Tr "repo.submit_image"}}</a> | ||||
| {{end}} | {{end}} | ||||
| @@ -390,14 +390,14 @@ | |||||
| <div class="item" style="padding: 0 !important;"> | <div class="item" style="padding: 0 !important;"> | ||||
| <!-- 模型下载 --> | <!-- 模型下载 --> | ||||
| {{if .CanDebug}} | {{if .CanDebug}} | ||||
| <a class="ui basic blue button" href="{{$.RepoLink}}/cloudbrain/{{.JobID}}/models" target="_blank">{{$.i18n.Tr "repo.download"}}</a> | |||||
| <a class="ui basic blue button" href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/models" target="_blank">{{$.i18n.Tr "repo.download"}}</a> | |||||
| {{else}} | {{else}} | ||||
| <a class="ui basic disabled button">{{$.i18n.Tr "repo.download"}}</a> | <a class="ui basic disabled button">{{$.i18n.Tr "repo.download"}}</a> | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| {{if and (ne .JobType "DEBUG") (eq .Cloudbrain.Type 0)}} | {{if and (ne .JobType "DEBUG") (eq .Cloudbrain.Type 0)}} | ||||
| <div class="item" style="padding: 0 !important;"> | |||||
| <a class="ui basic blue button" href="{{$.RepoLink}}/cloudbrain/{{.JobID}}/rate" target="_blank"> | |||||
| <div class="item" style="padding: 0 !important;"> | |||||
| <a class="ui basic blue button" href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/rate" target="_blank"> | |||||
| 评分 | 评分 | ||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| @@ -408,28 +408,28 @@ | |||||
| </div> | </div> | ||||
| <!-- 镜像列表弹窗 --> | <!-- 镜像列表弹窗 --> | ||||
| <div id="imageModal" class="modal" style="display: none;"> | <div id="imageModal" class="modal" style="display: none;"> | ||||
| <div class="modal-content"> | |||||
| <div class="modal-content"> | |||||
| <!-- 表格 --> | <!-- 表格 --> | ||||
| <div class="ui form"> | <div class="ui form"> | ||||
| <form id="commitImageForm" action="{{$.RepoLink}}/cloudbrain/{{.JobID}}/commit_image" method="post" target="iframeContent"> | |||||
| <form id="commitImageForm" action="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/commit_image" method="post" target="iframeContent"> | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| <div class="row"> | <div class="row"> | ||||
| <p style="display: inline;">提交任务镜像</p> | <p style="display: inline;">提交任务镜像</p> | ||||
| <span class="close">×</span> | <span class="close">×</span> | ||||
| </div> | </div> | ||||
| <div class="ui divider"></div> | <div class="ui divider"></div> | ||||
| <div class="inline required field dis"> | <div class="inline required field dis"> | ||||
| <label>镜像标签:</label> | |||||
| <label> {{$.i18n.Tr "repo.cloudbrain.mirror_tag"}}:</label> | |||||
| <input name="tag" id="image_tag" tabindex="3" autofocus required maxlength="255" style="width:75%"> | <input name="tag" id="image_tag" tabindex="3" autofocus required maxlength="255" style="width:75%"> | ||||
| </div> | </div> | ||||
| <div class="inline field"> | <div class="inline field"> | ||||
| <label class="label_after">镜像描述:</label> | |||||
| <label class="label_after">{{$.i18n.Tr "repo.cloudbrain.mirror_description"}}:</label> | |||||
| <textarea name="description" maxlength="255" rows="8" style="width:75%;margin-left: 0.2em;"></textarea> | <textarea name="description" maxlength="255" rows="8" style="width:75%;margin-left: 0.2em;"></textarea> | ||||
| </div> | |||||
| <div class="ui divider"></div> | |||||
| </div> | |||||
| <div class="ui divider"></div> | |||||
| <div class="inline field"> | <div class="inline field"> | ||||
| <label></label> | <label></label> | ||||
| <button class="ui green button" onclick="showmask()"> | <button class="ui green button" onclick="showmask()"> | ||||
| @@ -438,7 +438,7 @@ | |||||
| </div> | </div> | ||||
| </form> | </form> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -483,8 +483,8 @@ | |||||
| let url={{.RepoLink}} | let url={{.RepoLink}} | ||||
| let redirect_to = {{$.Link}} | let redirect_to = {{$.Link}} | ||||
| let getParam=getQueryVariable('debugListType') | let getParam=getQueryVariable('debugListType') | ||||
| let dropdownValue = ['all','',false].includes(getParam)? '全部' : getParam | |||||
| let dropdownValue = ['all','',false].includes(getParam)? '{{$.i18n.Tr "repo.gpu_type_all"}}' : getParam | |||||
| // localStorage.setItem('all',location.href) | // localStorage.setItem('all',location.href) | ||||
| function getQueryVariable(variable) | function getQueryVariable(variable) | ||||
| { | { | ||||
| @@ -505,7 +505,7 @@ | |||||
| }) | }) | ||||
| $('.ui.selection.dropdown').dropdown({ | $('.ui.selection.dropdown').dropdown({ | ||||
| onChange:function(value){ | onChange:function(value){ | ||||
| location.href = `${url}/debugjob?debugListType=${value}` | location.href = `${url}/debugjob?debugListType=${value}` | ||||
| } | } | ||||
| }) | }) | ||||
| @@ -565,5 +565,5 @@ | |||||
| } | } | ||||
| }) | }) | ||||
| } | } | ||||
| </script> | |||||
| </script> | |||||
| @@ -105,9 +105,9 @@ | |||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="three wide column padding0"> | <div class="three wide column padding0"> | ||||
| <a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <!-- 模型版本 --> | <!-- 模型版本 --> | ||||
| @@ -174,7 +174,7 @@ | |||||
| <div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-delete-{{.JobID}}" class="ui basic ai_delete blue button" data-repopath="{{$.RepoRelPath}}/modelarts/inference-job/{{.JobID}}/del_version" data-version="{{.VersionName}}" style="border-radius: .28571429rem;"> | |||||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic ai_delete blue button" data-repopath="{{$.RepoRelPath}}/modelarts/inference-job/{{.JobID}}/del_version" data-version="{{.VersionName}}" style="border-radius: .28571429rem;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| @@ -67,7 +67,7 @@ | |||||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 60%;" name="job_name" id="trainjob_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="64"> | |||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="64"> | |||||
| <span class="tooltips" style="display: block;">请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。</span> | <span class="tooltips" style="display: block;">请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。</span> | ||||
| </div> | </div> | ||||
| @@ -414,8 +414,8 @@ | |||||
| } | } | ||||
| ] | ] | ||||
| }, | }, | ||||
| job_name:{ | |||||
| identifier : 'job_name', | |||||
| display_job_name:{ | |||||
| identifier : 'display_job_name', | |||||
| rules: [ | rules: [ | ||||
| { | { | ||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[^-]$/]', | type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[^-]$/]', | ||||
| @@ -174,7 +174,7 @@ td, th { | |||||
| {{$.i18n.Tr "repo.modelarts.infer_job"}} | {{$.i18n.Tr "repo.modelarts.infer_job"}} | ||||
| </a> | </a> | ||||
| <div class="divider"> / </div> | <div class="divider"> / </div> | ||||
| <div class="active section">{{.jobName}}</div> | |||||
| <div class="active section">{{.displayJobName}}</div> | |||||
| </div> | </div> | ||||
| </h4> | </h4> | ||||
| {{with .task}} | {{with .task}} | ||||
| @@ -199,7 +199,7 @@ td, th { | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.JobName}} | |||||
| {{.DisplayJobName}} | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -48,7 +48,7 @@ | |||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>任务名称</label> | <label>任务名称</label> | ||||
| <input name="job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||||
| <input name="display_job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| @@ -117,7 +117,7 @@ | |||||
| $('#messageInfo').css('display','none') | $('#messageInfo').css('display','none') | ||||
| form.onsubmit = function(e){ | form.onsubmit = function(e){ | ||||
| let value_task = $("input[name='job_name']").val() | |||||
| let value_task = $("input[name='display_job_name']").val() | |||||
| let re = /^[a-z0-9][a-z0-9-_]{1,36}$/ | let re = /^[a-z0-9][a-z0-9-_]{1,36}$/ | ||||
| @@ -131,7 +131,7 @@ | |||||
| let min_value_task = value_task.toLowerCase() | let min_value_task = value_task.toLowerCase() | ||||
| $("input[name='job_name']").attr("value",min_value_task) | |||||
| $("input[name='display_job_name']").attr("value",min_value_task) | |||||
| document.getElementById("mask").style.display = "block" | document.getElementById("mask").style.display = "block" | ||||
| } | } | ||||
| @@ -16,14 +16,14 @@ | |||||
| </a> | </a> | ||||
| <div class="divider"> / </div> | <div class="divider"> / </div> | ||||
| {{with .task}} | {{with .task}} | ||||
| <div class="active section">{{.JobName}}</div> | |||||
| <div class="active section">{{.DisplayJobName}}</div> | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| </h4> | </h4> | ||||
| <div> | <div> | ||||
| <div class="ui yellow segment"> | <div class="ui yellow segment"> | ||||
| {{with .task}} | {{with .task}} | ||||
| <p>任务名称: {{.JobName}}</p> | |||||
| <p>任务名称: {{.DisplayJobName}}</p> | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <div class="ui green segment"> | <div class="ui green segment"> | ||||
| @@ -102,9 +102,9 @@ | |||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="three wide column padding0"> | <div class="three wide column padding0"> | ||||
| <a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.JobName}}" style="font-size: 14px;"> | |||||
| <a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <!-- 版本数量 --> | <!-- 版本数量 --> | ||||
| @@ -157,7 +157,7 @@ | |||||
| <form class="ui compact buttons" id="delForm-{{.JobID}}" action="{{$.Link}}/{{.JobID}}/del" method="post"> | <form class="ui compact buttons" id="delForm-{{.JobID}}" action="{{$.Link}}/{{.JobID}}/del" method="post"> | ||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-delete-{{.JobID}}" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | |||||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | |||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| {{else}} | {{else}} | ||||
| @@ -80,7 +80,7 @@ | |||||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 60%;" name="job_name" id="trainjob_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | |||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | |||||
| <span class="tooltips" style="display: block;">请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。</span> | <span class="tooltips" style="display: block;">请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。</span> | ||||
| </div> | </div> | ||||
| @@ -391,8 +391,8 @@ | |||||
| } | } | ||||
| ] | ] | ||||
| }, | }, | ||||
| job_name:{ | |||||
| identifier : 'job_name', | |||||
| display_job_name:{ | |||||
| identifier : 'display_job_name', | |||||
| rules: [ | rules: [ | ||||
| { | { | ||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[^-]$/]', | type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[^-]$/]', | ||||
| @@ -183,7 +183,7 @@ td, th { | |||||
| {{$.i18n.Tr "repo.modelarts.train_job"}} | {{$.i18n.Tr "repo.modelarts.train_job"}} | ||||
| </a> | </a> | ||||
| <div class="divider"> / </div> | <div class="divider"> / </div> | ||||
| <div class="active section">{{.jobName}}</div> | |||||
| <div class="active section">{{.displayJobName}}</div> | |||||
| </div> | </div> | ||||
| </h4> | </h4> | ||||
| {{range $k ,$v := .version_list_task}} | {{range $k ,$v := .version_list_task}} | ||||
| @@ -260,7 +260,7 @@ td, th { | |||||
| </td> | </td> | ||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w"> | <div class="text-span text-span-w"> | ||||
| {{.JobName}} | |||||
| {{.DisplayJobName}} | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -558,7 +558,7 @@ td, th { | |||||
| onShow:function(){ | onShow:function(){ | ||||
| $('input[name="Version"]').addClass('model_disabled') | $('input[name="Version"]').addClass('model_disabled') | ||||
| // $('input[name="JobId"]').text(obj.JobName) | // $('input[name="JobId"]').text(obj.JobName) | ||||
| $('#JobName').val(obj.JobName).addClass('model_disabled') | |||||
| $('#JobName').val(obj.DisplayJobName).addClass('model_disabled') | |||||
| $('input[name="JobId"]').val(obj.JobID) | $('input[name="JobId"]').val(obj.JobID) | ||||
| $('input[name="VersionName"]').val(obj.VersionName).addClass('model_disabled') | $('input[name="VersionName"]').val(obj.VersionName).addClass('model_disabled') | ||||
| $('.ui.dimmer').css({"background-color":"rgb(136, 136, 136,0.7)"}) | $('.ui.dimmer').css({"background-color":"rgb(136, 136, 136,0.7)"}) | ||||
| @@ -82,11 +82,12 @@ | |||||
| {{end}} | {{end}} | ||||
| <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | ||||
| <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | ||||
| <input type="hidden" id="display_job_name" name="display_job_name" value="{{.display_job_name}}"> | |||||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input type="hidden" style="width: 60%;" name="job_name" id="trainjob_job_name" value="{{.job_name}}"> | |||||
| <input style="width: 60%;" value="{{.job_name}}" tabindex="3" disabled > | |||||
| <input type="hidden" style="width: 60%;" name="job_name" id="job_name" value="{{.job_name}}"> | |||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" value="{{.display_job_name}}" tabindex="3" disabled > | |||||
| </div> | </div> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.parents_version"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.parents_version"}}</label> | ||||
| @@ -426,6 +427,15 @@ | |||||
| } | } | ||||
| ] | ] | ||||
| }, | }, | ||||
| display_job_name:{ | |||||
| identifier : 'display_job_name', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,36}$/]', | |||||
| prompt : '只包含大小写字母、数字、_和-,最长36个字符。' | |||||
| } | |||||
| ] | |||||
| }, | |||||
| attachment:{ | attachment:{ | ||||
| identifier : 'attachment', | identifier : 'attachment', | ||||
| rules: [ | rules: [ | ||||
| @@ -483,6 +493,15 @@ | |||||
| } | } | ||||
| ] | ] | ||||
| }, | }, | ||||
| display_job_name:{ | |||||
| identifier : 'display_job_name', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,36}$/]', | |||||
| prompt : '只包含大小写字母、数字、_和-,最长36个字符。' | |||||
| } | |||||
| ] | |||||
| }, | |||||
| attachment:{ | attachment:{ | ||||
| identifier : 'attachment', | identifier : 'attachment', | ||||
| rules: [ | rules: [ | ||||
| @@ -221,15 +221,16 @@ | |||||
| } | } | ||||
| function loadTrainList(){ | function loadTrainList(){ | ||||
| $.get(`${repolink}/modelmanage/query_train_job?repoId=${repoId}`, (data) => { | $.get(`${repolink}/modelmanage/query_train_job?repoId=${repoId}`, (data) => { | ||||
| console.log(data) | |||||
| const n_length = data.length | const n_length = data.length | ||||
| let train_html='' | let train_html='' | ||||
| for (let i=0;i<n_length;i++){ | for (let i=0;i<n_length;i++){ | ||||
| train_html += `<div class="item" data-value="${data[i].JobID}">${data[i].JobName}</div>` | |||||
| train_html += `<div class="item" data-value="${data[i].JobID}">${data[i].DisplayJobName}</div>` | |||||
| train_html += '</div>' | train_html += '</div>' | ||||
| } | } | ||||
| $("#job-name").append(train_html) | $("#job-name").append(train_html) | ||||
| $(".ui.dropdown.selection.search.width83").removeClass("loading") | $(".ui.dropdown.selection.search.width83").removeClass("loading") | ||||
| $('#choice_model .default.text').text(data[0].JobName) | |||||
| $('#choice_model .default.text').text(data[0].DisplayJobName) | |||||
| $('#choice_model input[name="JobId"]').val(data[0].JobID) | $('#choice_model input[name="JobId"]').val(data[0].JobID) | ||||
| loadTrainVersion() | loadTrainVersion() | ||||
| @@ -73,7 +73,7 @@ | |||||
| {{else if eq .GetOpType 24}} | {{else if eq .GetOpType 24}} | ||||
| {{$.i18n.Tr "action.upload_dataset" .GetRepoLink .Content .RefName | Str2html}} | {{$.i18n.Tr "action.upload_dataset" .GetRepoLink .Content .RefName | Str2html}} | ||||
| {{else if eq .GetOpType 25}} | {{else if eq .GetOpType 25}} | ||||
| {{$.i18n.Tr "action.task_gpudebugjob" .GetRepoLink .RefName .RefName | Str2html}} | |||||
| {{$.i18n.Tr "action.task_gpudebugjob" .GetRepoLink .Content .RefName | Str2html}} | |||||
| {{else if eq .GetOpType 26}} | {{else if eq .GetOpType 26}} | ||||
| {{$.i18n.Tr "action.task_npudebugjob" .GetRepoLink .Content .RefName | Str2html}} | {{$.i18n.Tr "action.task_npudebugjob" .GetRepoLink .Content .RefName | Str2html}} | ||||
| {{else if eq .GetOpType 27}} | {{else if eq .GetOpType 27}} | ||||
| @@ -81,7 +81,7 @@ | |||||
| {{else if eq .GetOpType 28}} | {{else if eq .GetOpType 28}} | ||||
| {{$.i18n.Tr "action.task_inferencejob" .GetRepoLink .Content .RefName | Str2html}} | {{$.i18n.Tr "action.task_inferencejob" .GetRepoLink .Content .RefName | Str2html}} | ||||
| {{else if eq .GetOpType 29}} | {{else if eq .GetOpType 29}} | ||||
| {{$.i18n.Tr "action.task_benchmark" .GetRepoLink .RefName .RefName | Str2html}} | |||||
| {{$.i18n.Tr "action.task_benchmark" .GetRepoLink .Content .RefName | Str2html}} | |||||
| {{else if eq .GetOpType 30}} | {{else if eq .GetOpType 30}} | ||||
| {{$.i18n.Tr "action.task_createmodel" .GetRepoLink .RefName .RefName | Str2html}} | {{$.i18n.Tr "action.task_createmodel" .GetRepoLink .RefName .RefName | Str2html}} | ||||
| {{end}} | {{end}} | ||||
| @@ -3,52 +3,52 @@ export default async function initCloudrain() { | |||||
| $(document).ready(loadJobStatus); | $(document).ready(loadJobStatus); | ||||
| function loadJobStatus() { | function loadJobStatus() { | ||||
| $(".job-status").each((index, job) => { | $(".job-status").each((index, job) => { | ||||
| const jobID = job.dataset.jobid; | |||||
| const ID = job.dataset.jobid; | |||||
| const repoPath = job.dataset.repopath; | const repoPath = job.dataset.repopath; | ||||
| // const computeResource = job.dataset.resource | // const computeResource = job.dataset.resource | ||||
| const versionname = job.dataset.version | const versionname = job.dataset.version | ||||
| const status_text = $(`#${jobID}-text`).text() | |||||
| const status_text = $(`#${ID}-text`).text() | |||||
| const finalState = ['STOPPED','CREATE_FAILED','UNAVAILABLE','DELETED','RESIZE_FAILED','SUCCEEDED','IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED','SUBMIT_MODEL_FAILED','DEPLOY_SERVICE_FAILED','CHECK_FAILED'] | const finalState = ['STOPPED','CREATE_FAILED','UNAVAILABLE','DELETED','RESIZE_FAILED','SUCCEEDED','IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED','SUBMIT_MODEL_FAILED','DEPLOY_SERVICE_FAILED','CHECK_FAILED'] | ||||
| if (finalState.includes(status_text)) { | if (finalState.includes(status_text)) { | ||||
| return | return | ||||
| } | } | ||||
| // const diffResource = computeResource == "NPU" ? 'modelarts/notebook' : 'cloudbrain' | // const diffResource = computeResource == "NPU" ? 'modelarts/notebook' : 'cloudbrain' | ||||
| $.get(`/api/v1/repos/${repoPath}/${jobID}?version_name=${versionname}`, (data) => { | |||||
| const jobID = data.JobID | |||||
| $.get(`/api/v1/repos/${repoPath}/${ID}?version_name=${versionname}`, (data) => { | |||||
| const ID = data.ID || data.JobID | |||||
| const status = data.JobStatus | const status = data.JobStatus | ||||
| const duration = data.JobDuration | const duration = data.JobDuration | ||||
| $('#duration-'+jobID).text(duration) | |||||
| $('#duration-'+ID).text(duration) | |||||
| if (status != status_text) { | if (status != status_text) { | ||||
| $('#' + jobID+'-icon').removeClass().addClass(status) | |||||
| $('#' + jobID+ '-text').text(status) | |||||
| finalState.includes(status) && $('#' + jobID + '-stop').removeClass('blue').addClass('disabled') | |||||
| $('#' + ID+'-icon').removeClass().addClass(status) | |||||
| $('#' + ID+ '-text').text(status) | |||||
| finalState.includes(status) && $('#' + ID + '-stop').removeClass('blue').addClass('disabled') | |||||
| } | } | ||||
| if(status==="RUNNING"){ | if(status==="RUNNING"){ | ||||
| $('#ai-debug-'+jobID).removeClass('disabled').addClass('blue').text('调试').css("margin","0 1rem") | |||||
| $('#model-image-'+jobID).removeClass('disabled').addClass('blue') | |||||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text('调试').css("margin","0 1rem") | |||||
| $('#model-image-'+ID).removeClass('disabled').addClass('blue') | |||||
| } | } | ||||
| if(status!=="RUNNING"){ | if(status!=="RUNNING"){ | ||||
| // $('#model-debug-'+jobID).removeClass('blue') | |||||
| // $('#model-debug-'+jobID).addClass('disabled') | |||||
| $('#model-image-'+jobID).removeClass('blue').addClass('disabled') | |||||
| // $('#model-debug-'+ID).removeClass('blue') | |||||
| // $('#model-debug-'+ID).addClass('disabled') | |||||
| $('#model-image-'+ID).removeClass('blue').addClass('disabled') | |||||
| } | } | ||||
| if(["CREATING","STOPPING","WAITING","STARTING"].includes(status)){ | if(["CREATING","STOPPING","WAITING","STARTING"].includes(status)){ | ||||
| $('#ai-debug-'+jobID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-debug-'+ID).removeClass('blue').addClass('disabled') | |||||
| } | } | ||||
| if(['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED'].includes(status)){ | if(['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED'].includes(status)){ | ||||
| $('#ai-debug-'+jobID).removeClass('disabled').addClass('blue').text('再次调试').css("margin","0") | |||||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text('再次调试').css("margin","0") | |||||
| } | } | ||||
| if(["RUNNING","WAITING"].includes(status)){ | if(["RUNNING","WAITING"].includes(status)){ | ||||
| $('#ai-stop-'+jobID).removeClass('disabled').addClass('blue') | |||||
| $('#ai-stop-'+ID).removeClass('disabled').addClass('blue') | |||||
| } | } | ||||
| if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED","SUCCEEDED"].includes(status)){ | |||||
| $('#ai-stop-'+jobID).removeClass('blue').addClass('disabled') | |||||
| if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED","SUCCEEDED","COMPLETED"].includes(status)){ | |||||
| $('#ai-stop-'+ID).removeClass('blue').addClass('disabled') | |||||
| } | } | ||||
| if(["STOPPED","FAILED","START_FAILED","KILLED","COMPLETED","SUCCEEDED"].includes(status)){ | if(["STOPPED","FAILED","START_FAILED","KILLED","COMPLETED","SUCCEEDED"].includes(status)){ | ||||
| $('#ai-delete-'+jobID).removeClass('disabled').addClass('blue') | |||||
| $('#ai-delete-'+ID).removeClass('disabled').addClass('blue') | |||||
| }else{ | }else{ | ||||
| $('#ai-delete-'+jobID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-delete-'+ID).removeClass('blue').addClass('disabled') | |||||
| } | } | ||||
| }).fail(function(err) { | }).fail(function(err) { | ||||
| console.log(err); | console.log(err); | ||||
| @@ -104,25 +104,25 @@ export default async function initCloudrain() { | |||||
| assertDelete(this) | assertDelete(this) | ||||
| } | } | ||||
| }) | }) | ||||
| function stopDebug(JobID,stopUrl){ | |||||
| function stopDebug(ID,stopUrl){ | |||||
| $.ajax({ | $.ajax({ | ||||
| type:"POST", | type:"POST", | ||||
| url:stopUrl, | url:stopUrl, | ||||
| data:$('#stopForm-'+JobID).serialize(), | |||||
| data:$('#stopForm-'+ID).serialize(), | |||||
| success:function(res){ | success:function(res){ | ||||
| if(res.result_code==="0"){ | if(res.result_code==="0"){ | ||||
| $('#' + JobID+'-icon').removeClass().addClass(res.status) | |||||
| $('#' + JobID+ '-text').text(res.status) | |||||
| $('#' + ID+'-icon').removeClass().addClass(res.status) | |||||
| $('#' + ID+ '-text').text(res.status) | |||||
| if(res.status==="STOPPED"){ | if(res.status==="STOPPED"){ | ||||
| $('#ai-debug-'+JobID).removeClass('disabled').addClass('blue').text("再次调试").css("margin","0") | |||||
| $('#ai-image-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-model-debug-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-delete-'+JobID).removeClass('disabled').addClass('blue') | |||||
| $('#ai-stop-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text("再次调试").css("margin","0") | |||||
| $('#ai-image-'+ID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-model-debug-'+ID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-delete-'+ID).removeClass('disabled').addClass('blue') | |||||
| $('#ai-stop-'+ID).removeClass('blue').addClass('disabled') | |||||
| } | } | ||||
| else{ | else{ | ||||
| $('#ai-debug-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-stop-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-debug-'+ID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-stop-'+ID).removeClass('blue').addClass('disabled') | |||||
| } | } | ||||
| }else{ | }else{ | ||||
| @@ -136,42 +136,41 @@ export default async function initCloudrain() { | |||||
| }) | }) | ||||
| } | } | ||||
| $('.ui.basic.ai_stop').click(function() { | $('.ui.basic.ai_stop').click(function() { | ||||
| const jobID = this.dataset.jobid | |||||
| const ID = this.dataset.jobid | |||||
| const repoPath = this.dataset.repopath | const repoPath = this.dataset.repopath | ||||
| stopDebug(jobID,repoPath) | |||||
| stopDebug(ID,repoPath) | |||||
| }) | }) | ||||
| function stopVersion(version_name,jobID,repoPath){ | |||||
| const url = `/api/v1/repos/${repoPath}/${jobID}/stop_version` | |||||
| function stopVersion(version_name,ID,repoPath){ | |||||
| const url = `/api/v1/repos/${repoPath}/${ID}/stop_version` | |||||
| $.post(url,{version_name:version_name},(data)=>{ | $.post(url,{version_name:version_name},(data)=>{ | ||||
| if(data.StatusOK===0){ | if(data.StatusOK===0){ | ||||
| $('#ai-stop-'+jobID).removeClass('blue') | |||||
| $('#ai-stop-'+jobID).addClass('disabled') | |||||
| refreshStatus(version_name,jobID,repoPath) | |||||
| $('#ai-stop-'+ID).removeClass('blue') | |||||
| $('#ai-stop-'+ID).addClass('disabled') | |||||
| refreshStatus(version_name,ID,repoPath) | |||||
| } | } | ||||
| }).fail(function(err) { | }).fail(function(err) { | ||||
| console.log(err); | console.log(err); | ||||
| }); | }); | ||||
| } | } | ||||
| function refreshStatus(version_name,jobID,repoPath){ | |||||
| function refreshStatus(version_name,ID,repoPath){ | |||||
| const url = `/api/v1/repos/${repoPath}/${jobID}/?version_name${version_name}` | |||||
| const url = `/api/v1/repos/${repoPath}/${ID}/?version_name${version_name}` | |||||
| $.get(url,(data)=>{ | $.get(url,(data)=>{ | ||||
| $(`#${jobID}-icon`).attr("class",data.JobStatus) | |||||
| $(`#${ID}-icon`).attr("class",data.JobStatus) | |||||
| // detail status and duration | // detail status and duration | ||||
| $(`#${jobID}-text`).text(data.JobStatus) | |||||
| $(`#${ID}-text`).text(data.JobStatus) | |||||
| }).fail(function(err) { | }).fail(function(err) { | ||||
| console.log(err); | console.log(err); | ||||
| }); | }); | ||||
| } | } | ||||
| $('.ui.basic.ai_stop_version').click(function() { | $('.ui.basic.ai_stop_version').click(function() { | ||||
| const jobID = this.dataset.jobid | |||||
| const ID = this.dataset.jobid | |||||
| const repoPath = this.dataset.repopath | const repoPath = this.dataset.repopath | ||||
| const versionName = this.dataset.version | const versionName = this.dataset.version | ||||
| stopVersion(versionName,jobID,repoPath) | |||||
| stopVersion(versionName,ID,repoPath) | |||||
| }) | }) | ||||
| function getModelInfo(repoPath,modelName,versionName,jobName){ | function getModelInfo(repoPath,modelName,versionName,jobName){ | ||||
| console.log("getModelInfo") | |||||
| $.get(`${repoPath}/modelmanage/show_model_info_api?name=${modelName}`,(data)=>{ | $.get(`${repoPath}/modelmanage/show_model_info_api?name=${modelName}`,(data)=>{ | ||||
| if(data.length===0){ | if(data.length===0){ | ||||
| $(`#${jobName}`).popup('toggle') | $(`#${jobName}`).popup('toggle') | ||||
| @@ -195,27 +194,27 @@ export default async function initCloudrain() { | |||||
| const jobName = this.dataset.jobname | const jobName = this.dataset.jobname | ||||
| getModelInfo(repoPath,modelName,versionName,jobName) | getModelInfo(repoPath,modelName,versionName,jobName) | ||||
| }) | }) | ||||
| function debugAgain(JobID,debugUrl,redirect_to){ | |||||
| if($('#' + JobID+ '-text').text()==="RUNNING"){ | |||||
| function debugAgain(ID,debugUrl,redirect_to){ | |||||
| if($('#' + ID+ '-text').text()==="RUNNING"){ | |||||
| window.open(debugUrl+'debug') | window.open(debugUrl+'debug') | ||||
| }else{ | }else{ | ||||
| $.ajax({ | $.ajax({ | ||||
| type:"POST", | type:"POST", | ||||
| url:debugUrl+'restart?redirect_to='+redirect_to, | url:debugUrl+'restart?redirect_to='+redirect_to, | ||||
| data:$('#debugAgainForm-'+JobID).serialize(), | |||||
| data:$('#debugAgainForm-'+ID).serialize(), | |||||
| success:function(res){ | success:function(res){ | ||||
| if(res['WechatRedirectUrl']){ | if(res['WechatRedirectUrl']){ | ||||
| window.location.href=res['WechatRedirectUrl'] | window.location.href=res['WechatRedirectUrl'] | ||||
| } | } | ||||
| else if(res.result_code==="0"){ | else if(res.result_code==="0"){ | ||||
| if(res.job_id!==JobID){ | |||||
| if(res.id!==ID){ | |||||
| location.reload() | location.reload() | ||||
| }else{ | }else{ | ||||
| $('#' + JobID+'-icon').removeClass().addClass(res.status) | |||||
| $('#' + JobID+ '-text').text(res.status) | |||||
| $('#ai-debug-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-delete-'+JobID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-debug-'+JobID).text("调试").css("margin","0 1rem") | |||||
| $('#' + ID+'-icon').removeClass().addClass(res.status) | |||||
| $('#' + ID+ '-text').text(res.status) | |||||
| $('#ai-debug-'+ID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-delete-'+ID).removeClass('blue').addClass('disabled') | |||||
| $('#ai-debug-'+ID).text("调试").css("margin","0 1rem") | |||||
| } | } | ||||
| }else{ | }else{ | ||||
| $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | ||||
| @@ -228,10 +227,10 @@ export default async function initCloudrain() { | |||||
| } | } | ||||
| } | } | ||||
| $('.ui.basic.ai_debug').click(function() { | $('.ui.basic.ai_debug').click(function() { | ||||
| const jobID = this.dataset.jobid | |||||
| const ID = this.dataset.jobid | |||||
| const repoPath = this.dataset.repopath | const repoPath = this.dataset.repopath | ||||
| const redirect_to = this.dataset.linkpath | const redirect_to = this.dataset.linkpath | ||||
| debugAgain(jobID,repoPath,redirect_to) | |||||
| debugAgain(ID,repoPath,redirect_to) | |||||
| }) | }) | ||||
| } | } | ||||
| @@ -725,9 +725,11 @@ display: block; | |||||
| margin-bottom: -50px; | margin-bottom: -50px; | ||||
| } | } | ||||
| .repo-header .repo-buttons{ | .repo-header .repo-buttons{ | ||||
| position: absolute; | |||||
| right: 15px; | |||||
| margin-bottom: -60px; | |||||
| position: relative; | |||||
| top: 1rem; | |||||
| width: 100%; | |||||
| display: flex; | |||||
| justify-content: flex-end; | |||||
| } | } | ||||
| .repo-buttons .ui.labeled.button>.button{ | .repo-buttons .ui.labeled.button>.button{ | ||||
| box-shadow: none !important; | box-shadow: none !important; | ||||
| @@ -0,0 +1,274 @@ | |||||
| const cssnano = require('cssnano'); | |||||
| const fastGlob = require('fast-glob'); | |||||
| const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries'); | |||||
| const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | |||||
| const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); | |||||
| const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); | |||||
| const PostCSSPresetEnv = require('postcss-preset-env'); | |||||
| const PostCSSSafeParser = require('postcss-safe-parser'); | |||||
| const SpriteLoaderPlugin = require('svg-sprite-loader/plugin'); | |||||
| const TerserPlugin = require('terser-webpack-plugin'); | |||||
| const VueLoaderPlugin = require('vue-loader/lib/plugin'); | |||||
| const {statSync} = require('fs'); | |||||
| const {resolve, parse} = require('path'); | |||||
| //const {SourceMapDevToolPlugin} = require('webpack'); | |||||
| const glob = (pattern) => fastGlob.sync(pattern, {cwd: __dirname, absolute: true}); | |||||
| const themes = {}; | |||||
| for (const path of glob('web_src/less/themes/*.less')) { | |||||
| themes[parse(path).name] = [path]; | |||||
| } | |||||
| const isProduction = process.env.NODE_ENV !== 'development'; | |||||
| module.exports = { | |||||
| mode: isProduction ? 'production' : 'development', | |||||
| entry: { | |||||
| index: [ | |||||
| resolve(__dirname, 'web_src/js/index.js'), | |||||
| resolve(__dirname, 'web_src/less/index.less'), | |||||
| ], | |||||
| swagger: [ | |||||
| resolve(__dirname, 'web_src/js/standalone/swagger.js'), | |||||
| ], | |||||
| jquery: [ | |||||
| resolve(__dirname, 'web_src/js/jquery.js'), | |||||
| ], | |||||
| icons: glob('node_modules/@primer/octicons/build/svg/**/*.svg'), | |||||
| ...themes, | |||||
| }, | |||||
| devtool: false, | |||||
| output: { | |||||
| path: resolve(__dirname, 'public'), | |||||
| filename: 'js/[name].js', | |||||
| chunkFilename: 'js/[name].js', | |||||
| }, | |||||
| node:{ | |||||
| fs: 'empty' | |||||
| }, | |||||
| optimization: { | |||||
| minimize: isProduction, | |||||
| minimizer: [ | |||||
| new TerserPlugin({ | |||||
| sourceMap: true, | |||||
| extractComments: false, | |||||
| terserOptions: { | |||||
| keep_fnames: /^(HTML|SVG)/, // https://github.com/fgnass/domino/issues/144 | |||||
| output: { | |||||
| comments: false, | |||||
| }, | |||||
| }, | |||||
| }), | |||||
| new OptimizeCSSAssetsPlugin({ | |||||
| cssProcessor: cssnano, | |||||
| cssProcessorOptions: { | |||||
| parser: PostCSSSafeParser, | |||||
| }, | |||||
| cssProcessorPluginOptions: { | |||||
| preset: [ | |||||
| 'default', | |||||
| { | |||||
| discardComments: { | |||||
| removeAll: true, | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| }), | |||||
| ], | |||||
| splitChunks: { | |||||
| chunks: 'async', | |||||
| name: (_, chunks) => chunks.map((item) => item.name).join('-'), | |||||
| cacheGroups: { | |||||
| // this bundles all monaco's languages into one file instead of emitting 1-65.js files | |||||
| monaco: { | |||||
| test: /monaco-editor/, | |||||
| name: 'monaco', | |||||
| chunks: 'async' | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| module: { | |||||
| rules: [ | |||||
| { | |||||
| test: /\.vue$/, | |||||
| exclude: /node_modules/, | |||||
| loader: 'vue-loader', | |||||
| }, | |||||
| { | |||||
| test: require.resolve('jquery-datetimepicker'), | |||||
| use: 'imports-loader?define=>false,exports=>false', | |||||
| }, | |||||
| { | |||||
| test: /\.worker\.js$/, | |||||
| exclude: /monaco/, | |||||
| use: [ | |||||
| { | |||||
| loader: 'worker-loader', | |||||
| options: { | |||||
| name: '[name].js', | |||||
| inline: true, | |||||
| fallback: false, | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| { | |||||
| test: /\.ts$/, | |||||
| use: [ | |||||
| { | |||||
| loader: "ts-loader", | |||||
| } | |||||
| ], | |||||
| exclude: /node_modules/ | |||||
| }, | |||||
| { | |||||
| test: /\.js$/, | |||||
| exclude: /node_modules/, | |||||
| use: [ | |||||
| { | |||||
| loader: 'babel-loader', | |||||
| options: { | |||||
| cacheDirectory: true, | |||||
| cacheCompression: false, | |||||
| cacheIdentifier: [ | |||||
| resolve(__dirname, 'package.json'), | |||||
| resolve(__dirname, 'package-lock.json'), | |||||
| resolve(__dirname, 'webpack.config.js'), | |||||
| ].map((path) => statSync(path).mtime.getTime()).join(':'), | |||||
| sourceMaps: true, | |||||
| presets: [ | |||||
| [ | |||||
| '@babel/preset-env', | |||||
| { | |||||
| useBuiltIns: 'usage', | |||||
| corejs: 3, | |||||
| }, | |||||
| ], | |||||
| ], | |||||
| plugins: [ | |||||
| [ | |||||
| '@babel/plugin-transform-runtime', | |||||
| { | |||||
| regenerator: true, | |||||
| } | |||||
| ], | |||||
| '@babel/plugin-proposal-object-rest-spread', | |||||
| ], | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| { | |||||
| test: /\.(less|css)$/i, | |||||
| use: [ | |||||
| { | |||||
| loader: MiniCssExtractPlugin.loader, | |||||
| }, | |||||
| { | |||||
| loader: 'css-loader', | |||||
| options: { | |||||
| importLoaders: 2, | |||||
| url: (_url, resourcePath) => { | |||||
| // only resolve URLs for dependencies | |||||
| return resourcePath.includes('node_modules'); | |||||
| }, | |||||
| } | |||||
| }, | |||||
| { | |||||
| loader: 'postcss-loader', | |||||
| options: { | |||||
| plugins: () => [ | |||||
| PostCSSPresetEnv(), | |||||
| ], | |||||
| }, | |||||
| }, | |||||
| { | |||||
| loader: 'less-loader', | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| { | |||||
| test: /\.svg$/, | |||||
| use: [ | |||||
| { | |||||
| loader: 'svg-sprite-loader', | |||||
| options: { | |||||
| extract: true, | |||||
| spriteFilename: 'img/svg/icons.svg', | |||||
| symbolId: (path) => { | |||||
| const {name} = parse(path); | |||||
| if (/@primer[/\\]octicons/.test(path)) { | |||||
| return `octicon-${name}`; | |||||
| } | |||||
| return name; | |||||
| }, | |||||
| }, | |||||
| }, | |||||
| { | |||||
| loader: 'svgo-loader', | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| { | |||||
| test: /\.(ttf|woff2?)$/, | |||||
| use: [ | |||||
| { | |||||
| loader: 'file-loader', | |||||
| options: { | |||||
| name: '[name].[ext]', | |||||
| outputPath: 'fonts/', | |||||
| publicPath: (url) => `../fonts/${url}`, // seems required for monaco's font | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| plugins: [ | |||||
| new VueLoaderPlugin(), | |||||
| // avoid generating useless js output files for css- and svg-only chunks | |||||
| new FixStyleOnlyEntriesPlugin({ | |||||
| extensions: ['less', 'scss', 'css', 'svg'], | |||||
| silent: true, | |||||
| }), | |||||
| new MiniCssExtractPlugin({ | |||||
| filename: 'css/[name].css', | |||||
| chunkFilename: 'css/[name].css', | |||||
| }), | |||||
| //new SourceMapDevToolPlugin({ | |||||
| //filename: 'js/[name].js.map', | |||||
| //include: [ | |||||
| //'js/index.js', | |||||
| //], | |||||
| //}), | |||||
| new SpriteLoaderPlugin({ | |||||
| plainSprite: true, | |||||
| }), | |||||
| new MonacoWebpackPlugin({ | |||||
| filename: 'js/monaco-[name].worker.js', | |||||
| }) | |||||
| ], | |||||
| performance: { | |||||
| hints: false, | |||||
| maxEntrypointSize: Infinity, | |||||
| maxAssetSize: Infinity, | |||||
| }, | |||||
| resolve: { | |||||
| symlinks: false, | |||||
| alias: { | |||||
| vue$: 'vue/dist/vue.esm.js', // needed because vue's default export is the runtime only | |||||
| }, | |||||
| extensions: ['.tsx', '.ts', '.js'] | |||||
| }, | |||||
| watchOptions: { | |||||
| ignored: [ | |||||
| 'node_modules/**', | |||||
| ], | |||||
| }, | |||||
| stats: { | |||||
| children: false, | |||||
| }, | |||||
| }; | |||||