| @@ -219,17 +219,20 @@ type GetImagesPayload struct { | |||
| type CloudbrainsOptions struct { | |||
| ListOptions | |||
| RepoID int64 // include all repos if empty | |||
| UserID int64 | |||
| JobID string | |||
| SortType string | |||
| CloudbrainIDs []int64 | |||
| // JobStatus CloudbrainStatus | |||
| RepoID int64 // include all repos if empty | |||
| UserID int64 | |||
| JobID string | |||
| SortType string | |||
| CloudbrainIDs []int64 | |||
| JobStatus []string | |||
| JobStatusNot bool | |||
| Keyword string | |||
| Type int | |||
| JobTypes []string | |||
| VersionName string | |||
| IsLatestVersion string | |||
| JobTypeNot bool | |||
| NeedRepoInfo bool | |||
| } | |||
| type TaskPod struct { | |||
| @@ -1081,7 +1084,32 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { | |||
| cond = cond.And(builder.In("cloudbrain.id", opts.CloudbrainIDs)) | |||
| } | |||
| count, err := sess.Where(cond).Count(new(Cloudbrain)) | |||
| if len(opts.JobStatus) > 0 { | |||
| if opts.JobStatusNot { | |||
| cond = cond.And( | |||
| builder.NotIn("cloudbrain.status", opts.JobStatus), | |||
| ) | |||
| } else { | |||
| cond = cond.And( | |||
| builder.In("cloudbrain.status", opts.JobStatus), | |||
| ) | |||
| } | |||
| } | |||
| var count int64 | |||
| var err error | |||
| condition := "cloudbrain.user_id = `user`.id" | |||
| if len(opts.Keyword) == 0 { | |||
| count, err = sess.Where(cond).Count(new(Cloudbrain)) | |||
| } else { | |||
| lowerKeyWord := strings.ToLower(opts.Keyword) | |||
| cond = cond.And(builder.Or(builder.Like{"LOWER(cloudbrain.job_name)", lowerKeyWord}, builder.Like{"`user`.lower_name", lowerKeyWord})) | |||
| count, err = sess.Table(&Cloudbrain{}).Where(cond). | |||
| Join("left", "`user`", condition).Count(new(CloudbrainInfo)) | |||
| } | |||
| if err != nil { | |||
| return nil, 0, fmt.Errorf("Count: %v", err) | |||
| } | |||
| @@ -1099,11 +1127,25 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { | |||
| sess.OrderBy("cloudbrain.created_unix DESC") | |||
| cloudbrains := make([]*CloudbrainInfo, 0, setting.UI.IssuePagingNum) | |||
| if err := sess.Table(&Cloudbrain{}).Where(cond). | |||
| Join("left", "`user`", "cloudbrain.user_id = `user`.id"). | |||
| Join("left", "`user`", condition). | |||
| Find(&cloudbrains); err != nil { | |||
| return nil, 0, fmt.Errorf("Find: %v", err) | |||
| } | |||
| if opts.NeedRepoInfo { | |||
| var ids []int64 | |||
| for _, task := range cloudbrains { | |||
| ids = append(ids, task.RepoID) | |||
| } | |||
| repositoryMap, err := GetRepositoriesMapByIDs(ids) | |||
| if err == nil { | |||
| for _, task := range cloudbrains { | |||
| task.Repo = repositoryMap[task.RepoID] | |||
| } | |||
| } | |||
| } | |||
| return cloudbrains, count, nil | |||
| } | |||
| @@ -864,9 +864,13 @@ confirm_choice = confirm | |||
| cloudbran1_tips = Only data in zip format can create cloudbrain tasks | |||
| cloudbrain_creator=Creator | |||
| cloudbrain_task = Task Name | |||
| cloudbrain_task_type = Task Type | |||
| cloudbrain_task_name=Cloud Brain Task Name | |||
| cloudbrain_operate = Operate | |||
| cloudbrain_status_createtime = Status/Createtime | |||
| 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_query_fail=Failed to query cloudbrain information. | |||
| record_begintime_get_err=Can not get the record begin time. | |||
| parameter_is_wrong=The input parameter is wrong. | |||
| @@ -868,10 +868,13 @@ confirm_choice=确定 | |||
| cloudbran1_tips=只有zip格式的数据集才能发起云脑任务 | |||
| cloudbrain_creator=创建者 | |||
| cloudbrain_task=任务名称 | |||
| cloudbrain_task_type=任务类型 | |||
| cloudbrain_task_name=云脑侧任务名称 | |||
| cloudbrain_operate=操作 | |||
| cloudbrain_status_createtime=状态/创建时间 | |||
| cloudbrain_status_runtime = 运行时长 | |||
| cloudbrain_jobname_err=只能以小写字母或数字开头且只包含小写字母、数字、_和-,不能以_结尾,最长36个字符。 | |||
| cloudbrain_query_fail=查询云脑任务失败。 | |||
| record_begintime_get_err=无法获取统计开始时间。 | |||
| parameter_is_wrong=输入参数错误,请检查输入参数。 | |||
| @@ -13869,6 +13869,130 @@ | |||
| "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", | |||
| "dev": true | |||
| }, | |||
| "ts-loader": { | |||
| "version": "4.0.0", | |||
| "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-4.0.0.tgz", | |||
| "integrity": "sha512-iissbnuJkqbB3YAmnWyEbmdNcGcoiiXopKHKyqdoCrFQVi9pnplXeveQDXJnQOCYNNcb2pjT2zzSYTX6c9QtAA==", | |||
| "dev": true, | |||
| "requires": { | |||
| "chalk": "^2.3.0", | |||
| "enhanced-resolve": "^4.0.0", | |||
| "loader-utils": "^1.0.2", | |||
| "micromatch": "^3.1.4", | |||
| "semver": "^5.0.1" | |||
| }, | |||
| "dependencies": { | |||
| "braces": { | |||
| "version": "2.3.2", | |||
| "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", | |||
| "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", | |||
| "dev": true, | |||
| "requires": { | |||
| "arr-flatten": "^1.1.0", | |||
| "array-unique": "^0.3.2", | |||
| "extend-shallow": "^2.0.1", | |||
| "fill-range": "^4.0.0", | |||
| "isobject": "^3.0.1", | |||
| "repeat-element": "^1.1.2", | |||
| "snapdragon": "^0.8.1", | |||
| "snapdragon-node": "^2.0.1", | |||
| "split-string": "^3.0.2", | |||
| "to-regex": "^3.0.1" | |||
| }, | |||
| "dependencies": { | |||
| "extend-shallow": { | |||
| "version": "2.0.1", | |||
| "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", | |||
| "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", | |||
| "dev": true, | |||
| "requires": { | |||
| "is-extendable": "^0.1.0" | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| "fill-range": { | |||
| "version": "4.0.0", | |||
| "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", | |||
| "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", | |||
| "dev": true, | |||
| "requires": { | |||
| "extend-shallow": "^2.0.1", | |||
| "is-number": "^3.0.0", | |||
| "repeat-string": "^1.6.1", | |||
| "to-regex-range": "^2.1.0" | |||
| }, | |||
| "dependencies": { | |||
| "extend-shallow": { | |||
| "version": "2.0.1", | |||
| "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", | |||
| "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", | |||
| "dev": true, | |||
| "requires": { | |||
| "is-extendable": "^0.1.0" | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| "is-number": { | |||
| "version": "3.0.0", | |||
| "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", | |||
| "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", | |||
| "dev": true, | |||
| "requires": { | |||
| "kind-of": "^3.0.2" | |||
| }, | |||
| "dependencies": { | |||
| "kind-of": { | |||
| "version": "3.2.2", | |||
| "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", | |||
| "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", | |||
| "dev": true, | |||
| "requires": { | |||
| "is-buffer": "^1.1.5" | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| "isobject": { | |||
| "version": "3.0.1", | |||
| "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", | |||
| "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", | |||
| "dev": true | |||
| }, | |||
| "micromatch": { | |||
| "version": "3.1.10", | |||
| "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", | |||
| "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", | |||
| "dev": true, | |||
| "requires": { | |||
| "arr-diff": "^4.0.0", | |||
| "array-unique": "^0.3.2", | |||
| "braces": "^2.3.1", | |||
| "define-property": "^2.0.2", | |||
| "extend-shallow": "^3.0.2", | |||
| "extglob": "^2.0.4", | |||
| "fragment-cache": "^0.2.1", | |||
| "kind-of": "^6.0.2", | |||
| "nanomatch": "^1.2.9", | |||
| "object.pick": "^1.3.0", | |||
| "regex-not": "^1.0.0", | |||
| "snapdragon": "^0.8.1", | |||
| "to-regex": "^3.0.2" | |||
| } | |||
| }, | |||
| "to-regex-range": { | |||
| "version": "2.1.1", | |||
| "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", | |||
| "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", | |||
| "dev": true, | |||
| "requires": { | |||
| "is-number": "^3.0.0", | |||
| "repeat-string": "^1.6.1" | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| "tslib": { | |||
| "version": "1.13.0", | |||
| "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", | |||
| @@ -13928,6 +14052,12 @@ | |||
| "is-typedarray": "^1.0.0" | |||
| } | |||
| }, | |||
| "typescript": { | |||
| "version": "4.5.5", | |||
| "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", | |||
| "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", | |||
| "dev": true | |||
| }, | |||
| "ua-parser-js": { | |||
| "version": "0.7.21", | |||
| "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", | |||
| @@ -69,6 +69,8 @@ | |||
| "script-loader": "0.7.2", | |||
| "stylelint": "13.3.3", | |||
| "stylelint-config-standard": "20.0.0", | |||
| "ts-loader": "4.0.0", | |||
| "typescript": "4.5.5", | |||
| "updates": "10.2.11" | |||
| }, | |||
| "browserslist": [ | |||
| @@ -0,0 +1,215 @@ | |||
| package admin | |||
| import ( | |||
| "net/http" | |||
| "net/url" | |||
| "strconv" | |||
| "strings" | |||
| "time" | |||
| "github.com/360EntSecGroup-Skylar/excelize/v2" | |||
| "code.gitea.io/gitea/modules/modelarts" | |||
| "code.gitea.io/gitea/models" | |||
| "code.gitea.io/gitea/modules/base" | |||
| "code.gitea.io/gitea/modules/context" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| ) | |||
| const ( | |||
| tplCloudBrains base.TplName = "admin/cloudbrain/list" | |||
| EXCEL_DATE_FORMAT = "20060102150405" | |||
| CREATE_TIME_FORMAT = "2006/01/02 15:04:05.00" | |||
| ) | |||
| func CloudBrains(ctx *context.Context) { | |||
| ctx.Data["Title"] = ctx.Tr("admin.cloudBrains") | |||
| ctx.Data["PageIsAdmin"] = true | |||
| ctx.Data["PageIsAdminCloudBrains"] = true | |||
| listType := ctx.Query("listType") | |||
| jobType := ctx.Query("jobType") | |||
| jobStatus := ctx.Query("jobStatus") | |||
| ctx.Data["ListType"] = listType | |||
| ctx.Data["JobType"] = jobType | |||
| ctx.Data["JobStatus"] = jobStatus | |||
| page := ctx.QueryInt("page") | |||
| if page <= 0 { | |||
| page = 1 | |||
| } | |||
| debugType := modelarts.DebugType | |||
| if listType == models.GPUResource { | |||
| debugType = models.TypeCloudBrainOne | |||
| } else if listType == models.NPUResource { | |||
| debugType = models.TypeCloudBrainTwo | |||
| } | |||
| var jobTypes []string | |||
| jobTypeNot := false | |||
| if jobType == string(models.JobTypeDebug) { | |||
| jobTypes = append(jobTypes, string(models.JobTypeSnn4imagenet), string(models.JobTypeBrainScore), string(models.JobTypeDebug)) | |||
| } else if jobType != "all" && jobType != "" { | |||
| jobTypes = append(jobTypes, jobType) | |||
| } | |||
| var jobStatuses []string | |||
| jobStatusNot := false | |||
| if jobStatus == "other" { | |||
| jobStatusNot = true | |||
| jobStatuses = append(jobStatuses, string(models.ModelArtsTrainJobWaiting), string(models.ModelArtsTrainJobFailed), string(models.ModelArtsRunning), string(models.ModelArtsTrainJobCompleted), | |||
| string(models.ModelArtsStarting), string(models.ModelArtsRestarting), string(models.ModelArtsStartFailed), | |||
| string(models.ModelArtsStopping), string(models.ModelArtsStopped)) | |||
| } else if jobStatus != "all" && jobStatus != "" { | |||
| jobStatuses = append(jobStatuses, jobStatus) | |||
| } | |||
| keyword := strings.Trim(ctx.Query("q"), " ") | |||
| ciTasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{ | |||
| ListOptions: models.ListOptions{ | |||
| Page: page, | |||
| PageSize: setting.UI.IssuePagingNum, | |||
| }, | |||
| Keyword: keyword, | |||
| Type: debugType, | |||
| JobTypeNot: jobTypeNot, | |||
| JobStatusNot: jobStatusNot, | |||
| JobStatus: jobStatuses, | |||
| JobTypes: jobTypes, | |||
| NeedRepoInfo: true, | |||
| }) | |||
| if err != nil { | |||
| ctx.ServerError("Get job failed:", err) | |||
| return | |||
| } | |||
| for i, task := range ciTasks { | |||
| ciTasks[i].CanDebug = true | |||
| ciTasks[i].CanDel = true | |||
| ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource | |||
| } | |||
| pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, getTotalPage(count, setting.UI.IssuePagingNum)) | |||
| pager.SetDefaultParams(ctx) | |||
| pager.AddParam(ctx, "listType", "ListType") | |||
| ctx.Data["Page"] = pager | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| ctx.Data["Tasks"] = ciTasks | |||
| ctx.Data["CanCreate"] = true | |||
| ctx.Data["Keyword"] = keyword | |||
| ctx.HTML(200, tplCloudBrains) | |||
| } | |||
| func DownloadCloudBrains(ctx *context.Context) { | |||
| page := 1 | |||
| pageSize := 300 | |||
| var cloudBrain = ctx.Tr("repo.cloudbrain") | |||
| fileName := getFileName(cloudBrain) | |||
| _, total, err := models.Cloudbrains(&models.CloudbrainsOptions{ | |||
| ListOptions: models.ListOptions{ | |||
| Page: page, | |||
| PageSize: 1, | |||
| }, | |||
| Type: modelarts.DebugType, | |||
| NeedRepoInfo: false, | |||
| }) | |||
| if err != nil { | |||
| log.Warn("Can not get cloud brain info", err) | |||
| ctx.Error(http.StatusBadRequest, ctx.Tr("repo.cloudbrain_query_fail")) | |||
| return | |||
| } | |||
| totalPage := getTotalPage(total, pageSize) | |||
| f := excelize.NewFile() | |||
| index := f.NewSheet(cloudBrain) | |||
| f.DeleteSheet("Sheet1") | |||
| for k, v := range allHeader(ctx) { | |||
| f.SetCellValue(cloudBrain, k, v) | |||
| } | |||
| var row = 2 | |||
| for i := 0; i < totalPage; i++ { | |||
| pageRecords, _, err := models.Cloudbrains(&models.CloudbrainsOptions{ | |||
| ListOptions: models.ListOptions{ | |||
| Page: page, | |||
| PageSize: pageSize, | |||
| }, | |||
| Type: modelarts.DebugType, | |||
| NeedRepoInfo: true, | |||
| }) | |||
| if err != nil { | |||
| log.Warn("Can not get cloud brain info", err) | |||
| continue | |||
| } | |||
| for _, record := range pageRecords { | |||
| for k, v := range allValues(row, record, ctx) { | |||
| f.SetCellValue(cloudBrain, k, v) | |||
| } | |||
| row++ | |||
| } | |||
| page++ | |||
| } | |||
| f.SetActiveSheet(index) | |||
| ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(fileName)) | |||
| ctx.Resp.Header().Set("Content-Type", "application/octet-stream") | |||
| f.WriteTo(ctx.Resp) | |||
| } | |||
| 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.Status, getCellName("C", row): rs.JobType, 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): rs.Repo.OwnerName + "/" + rs.Repo.Alias, getCellName("I", row): rs.JobName, | |||
| } | |||
| } | |||
| func getDurationTime(rs *models.CloudbrainInfo) string { | |||
| if rs.JobType == "TRAIN" || rs.JobType == "INFERENCE" { | |||
| return rs.TrainJobDuration | |||
| } else { | |||
| return "-" | |||
| } | |||
| } | |||
| func getFileName(baseName string) string { | |||
| return baseName + "_" + time.Now().Format(EXCEL_DATE_FORMAT) + ".xlsx" | |||
| } | |||
| func getTotalPage(total int64, pageSize int) int { | |||
| another := 0 | |||
| if int(total)%pageSize != 0 { | |||
| another = 1 | |||
| } | |||
| return int(total)/pageSize + another | |||
| } | |||
| func allHeader(ctx *context.Context) map[string]string { | |||
| return map[string]string{"A1": ctx.Tr("repo.cloudbrain_task"), "B1": ctx.Tr("repo.modelarts.status"), "C1": ctx.Tr("repo.cloudbrain_task_type"), "D1": ctx.Tr("repo.modelarts.createtime"), "E1": ctx.Tr("repo.modelarts.train_job.dura_time"), "F1": ctx.Tr("repo.modelarts.computing_resources"), "G1": ctx.Tr("repo.cloudbrain_creator"), "H1": ctx.Tr("repo.repo_name"), "I1": ctx.Tr("repo.cloudbrain_task_name")} | |||
| } | |||
| func getCellName(col string, row int) string { | |||
| return col + strconv.Itoa(row) | |||
| } | |||
| @@ -507,6 +507,10 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("", admin.Datasets) | |||
| // m.Post("/delete", admin.DeleteDataset) | |||
| }) | |||
| m.Group("/cloudbrains", func() { | |||
| m.Get("", admin.CloudBrains) | |||
| m.Get("/download", admin.DownloadCloudBrains) | |||
| }) | |||
| m.Group("/^:configType(hooks|system-hooks)$", func() { | |||
| m.Get("", admin.DefaultOrSystemWebhooks) | |||
| @@ -0,0 +1,489 @@ | |||
| <style> | |||
| .el-pagination.is-background .el-pager li:not(.disabled).active { | |||
| background-color: #5bb973 !important; | |||
| color: #FFF !important; | |||
| } | |||
| /* .el-pagination.is-background .el-pager li.active { | |||
| color: #fff; | |||
| cursor: default; | |||
| } */ | |||
| .el-pagination.is-background .el-pager li:hover { | |||
| color: #5bb973 !important; | |||
| } | |||
| /* .el-pagination.is-background .el-pager li:not(.disabled):hover { | |||
| color: #5bb973; | |||
| } | |||
| .el-pagination.is-background .el-pager li:not(.disabled).active:hover { | |||
| background-color: #5bb973; | |||
| color: #FFF; | |||
| } */ | |||
| </style> | |||
| {{template "base/head" .}} | |||
| <!-- 弹窗 --> | |||
| <div id="mask"> | |||
| <div id="loadingPage"> | |||
| <div class="rect1"></div> | |||
| <div class="rect2"></div> | |||
| <div class="rect3"></div> | |||
| <div class="rect4"></div> | |||
| <div class="rect5"></div> | |||
| </div> | |||
| </div> | |||
| <!-- 提示框 --> | |||
| <div class="alert"></div> | |||
| <div class="admin user"> | |||
| {{template "admin/navbar" .}} | |||
| <div class="ui container" style="width: 80%;"> | |||
| {{template "base/alert" .}} | |||
| <div class="ui grid" > | |||
| <div class="row" style="border: 1px solid #d4d4d5;margin-top: 15px;padding-top: 0;"> | |||
| <div class="ui attached segment"> | |||
| <form class="ui form ignore-dirty" style="max-width: 90%"> | |||
| <div class="ui fluid action input"> | |||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..." autofocus> | |||
| <button class="ui blue button">{{.i18n.Tr "explore.search"}}</button> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| <div class="ui six wide column" style="margin: 1rem 0;" id="adminCloud"> | |||
| <div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||
| <div class="default text" style="color: rgba(0,0,0,.87);">全部任务类型</div> | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="全部任务类型">全部任务类型</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=DEBUG&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="DEBUG">DEBUG</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=TRAIN&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="TRAIN">TRAIN</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=INFERENCE&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="INFERENCE">INFERENCE</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||
| <div class="default text" style="color: rgba(0,0,0,.87);">全部计算资源</div> | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=&jobStatus={{$.JobStatus}}" data-value="全部计算资源">全部计算资源</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=CPU/GPU&jobStatus={{$.JobStatus}}" data-value="CPU/GPU">CPU/GPU</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType=NPU&jobStatus={{$.JobStatus}}" data-value="NPU">NPU</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||
| <div class="default text" style="color: rgba(0,0,0,.87);">全部状态</div> | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=" data-value="all">全部状态</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=STARTING" data-value="CPU/GPU">STARTING</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=RESTARTING" data-value="NPU">RESTARTING </a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=START_FAILED" data-value="all">START_FAILED</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=STOPPING" data-value="CPU/GPU">STOPPING</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=STOPPED}" data-value="NPU">STOPPED</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=WAITING" data-value="all">WAITING</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=COMPLETED" data-value="CPU/GPU">COMPLETED</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=FAILED" data-value="NPU">FAILED </a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType={{$.JobType}}&listType={{$.ListType}}&jobStatus=OTHER" data-value="NPU">OTHER</a> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="ui ten wide column right aligned" style="margin: 1rem 0;"> | |||
| <!-- <a href="/admin/cloudbrains/download"><i class="ri-download-line" style="display: inline-block;"></i>下载此报告</a> --> | |||
| <a class="ui compact blue basic icon button" style="box-shadow: none !important; padding: 0.8em;" href="/admin/cloudbrains/download"><i class="ri-download-line middle aligned icon"></i>下载此报告</a> | |||
| </div> | |||
| <div class="ui sixteen wide column"> | |||
| <!-- 任务展示 --> | |||
| <div class="dataset list"> | |||
| <!-- 表头 --> | |||
| <div class="ui grid stackable" style="background: #f0f0f0;;"> | |||
| <div class="row"> | |||
| <div class="two wide column padding0"> | |||
| <span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task"}}</span> | |||
| </div> | |||
| <div class="one wide column text center padding0"> | |||
| <span style="margin:0 6px">任务类型</span> | |||
| </div> | |||
| <div class="two wide column text center padding0" style="width: 10% !important;"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.status"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0" style="width: 10% !important;"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | |||
| </div> | |||
| <div class="one wide column text center padding0"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | |||
| </div> | |||
| <div class="one wide column text center padding0"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||
| </div> | |||
| <div class="one wide column text center padding0"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0"> | |||
| <span>项目</span> | |||
| </div> | |||
| <div class="two wide column text center padding0"> | |||
| <span>云脑侧名称</span> | |||
| </div> | |||
| <div class="two wide column text center padding0" style="width: 17.5%!important;"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{range .Tasks}} | |||
| <div class="ui grid stackable item"> | |||
| <div class="row"> | |||
| <!-- 任务名 --> | |||
| <div class="two wide column padding0"> | |||
| {{if eq .JobType "DEBUG"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}/cloudbrain/{{.JobID}}" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "INFERENCE"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}/modelarts/inference-job/{{.JobID}}" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "TRAIN"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}/modelarts/train-job/{{.JobID}}" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "BENCHMARK"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}/cloudbrain/benchmark/{{.JobID}}" title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> | |||
| </a> | |||
| {{end}} | |||
| </div> | |||
| <!-- 任务类型 --> | |||
| <div class="one wide column text center padding0"> | |||
| <span style="font-size: 12px;">{{.JobType}} </span> | |||
| </div> | |||
| <!-- 任务状态 --> | |||
| <div class="two wide column text center padding0" style="padding-left: 2.2rem !important; width: 10% !important;"> | |||
| <span class="job-status" id="{{.JobID}}" data-repopath='{{.Repo.OwnerName}}/{{.Repo.Alias}}{{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> | |||
| </div> | |||
| <!-- 任务创建时间 --> | |||
| <div class="two wide column text center padding0" style="width: 10% !important;"> | |||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | |||
| </div> | |||
| <!-- 任务运行时间 --> | |||
| <div class="one wide column text center padding0"> | |||
| <span style="font-size: 12px;" id="duration-{{.JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 计算资源 --> | |||
| <div class="one wide column text center padding0"> | |||
| <span style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 创建者 --> | |||
| <div class="one wide column text center padding0"> | |||
| {{if .User.Name}} | |||
| <a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | |||
| {{else}} | |||
| <a title="Ghost"><img class="ui avatar image" src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a> | |||
| {{end}} | |||
| </div> | |||
| <!-- 项目 --> | |||
| <div class="two wide column text center padding0"> | |||
| <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}" title="{{.Repo.OwnerName}}/{{.Repo.Alias}}">{{.Repo.OwnerName}}/{{.Repo.Alias}}</a> | |||
| </div> | |||
| <!-- 云脑侧名称 --> | |||
| <div class="two wide column text center padding0" style="overflow: hidden;text-overflow:ellipsis;"> | |||
| <span class="fitted">{{.JobName}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0" style="width: 17.5%!important;"> | |||
| {{if eq .JobType "DEBUG"}} | |||
| <div class="ui compact buttons"> | |||
| <form id="debugAgainForm-{{.JobID}}"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{.JobID}}" class='ui basic {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' onclick='debugAgain("{{.JobID}}","{{if eq .ComputeResource "CPU/GPU"}}{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}/cloudbrain{{else}}{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}/modelarts/notebook{{end}}/{{.JobID}}/")'> | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{else}} | |||
| <a id="ai-debug-{{.JobID}}" class='ui basic {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' onclick='debugAgain("{{.JobID}}","{{if eq .ComputeResource "CPU/GPU"}}{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}/cloudbrain{{else}}{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}/modelarts/notebook{{end}}/{{.JobID}}/")'> | |||
| {{$.i18n.Tr "repo.debug_again"}} | |||
| </a> | |||
| {{end}} | |||
| </form> | |||
| </div> | |||
| {{end}} | |||
| <!-- 停止任务 --> | |||
| <div class="ui compact buttons"> | |||
| {{if eq .JobType "DEBUG" "BENCHMARK"}} | |||
| <form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | |||
| {{$.CsrfTokenHtml}} | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class='ui basic {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED" "STOPPING"}}disabled {{else}} blue {{end}}button' onclick='stopDebug("{{.JobID}}","{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}/{{.JobID}}/stop")'> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| </form> | |||
| {{else}} | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class="ui basic {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED"}}disabled {{else}} blue {{end}}button" onclick='stopVersion({{.VersionName}},{{.JobID}},{{.Repo.OwnerName}},{{.Repo.Alias}})'> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| {{end}} | |||
| </div> | |||
| <!-- 下载 --> | |||
| <!-- {{if eq .JobType "INFERENCE"}} | |||
| <div class="ui compact buttons"> | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-download-{{.JobID}}" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}/modelarts/inference-job/{{.JobID}}/downloadall?version_name={{.VersionName}}" class="ui basic blue button" style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.model_download"}} | |||
| </a> | |||
| </div> | |||
| {{else if eq .JobType "DEBUG"}} | |||
| <div class="ui compact buttons"> | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-download-{{.JobID}}" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}/modelarts/inference-job/{{.JobID}}/downloadall?version_name={{.VersionName}}" class="ui basic blue button" style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.download"}} | |||
| </a> | |||
| </div> | |||
| {{end}} --> | |||
| <!-- 删除任务 --> | |||
| <form class="ui compact buttons" id="delForm-{{.JobID}}" action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU"}}/modelarts/notebook{{else if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "TRAIN"}}modelarts/train-job{{end}}/{{.JobID}}/del' method="post"> | |||
| {{$.CsrfTokenHtml}} | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic blue button" onclick="assertDelete(this,{{.VersionName}},{{.JobID}},{{.Repo.OwnerName}},{{.Repo.Alias}})" style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| <div id="app" style="margin-top: 2rem;"> | |||
| <div class="center"> | |||
| <el-pagination | |||
| background | |||
| @current-change="handleCurrentChange" | |||
| :current-page="page" | |||
| :page-sizes="[10]" | |||
| :page-size="10" | |||
| layout="total, sizes, prev, pager, next, jumper" | |||
| :total="{{.Page.Paginater.Total}}"> | |||
| </el-pagination> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <!-- 确认模态框 --> | |||
| <div id="deletemodel"> | |||
| <div class="ui basic modal"> | |||
| <div class="ui icon header"> | |||
| <i class="trash icon"></i> 删除任务 | |||
| </div> | |||
| <div class="content"> | |||
| <p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||
| </div> | |||
| <div class="actions"> | |||
| <div class="ui red basic inverted cancel button"> | |||
| <i class="remove icon"></i> 取消操作 | |||
| </div> | |||
| <div class="ui green basic inverted ok button"> | |||
| <i class="checkmark icon"></i> 确定操作 | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| // 删除时用户确认 | |||
| console.log({{.Tasks}}) | |||
| function deleteVersion(version_name,jobID,repoOwner,repoName){ | |||
| const url = '/api/v1/repos/'+repoOwner+'/'+repoName+'/modelarts/inference-job/'+jobID+'/del_version' | |||
| $.post(url,{version_name:version_name},(data)=>{ | |||
| if(data.StatusOK===0){ | |||
| location.reload() | |||
| } | |||
| }).fail(function(err) { | |||
| console.log(err); | |||
| }); | |||
| } | |||
| function assertDelete(obj,version_name,jobID,repoOwner,repoName) { | |||
| if (obj.style.color == "rgb(204, 204, 204)") { | |||
| return | |||
| } else { | |||
| const delId = obj.parentNode.id | |||
| flag = 1; | |||
| $('.ui.basic.modal') | |||
| .modal({ | |||
| onDeny: function() { | |||
| flag = false | |||
| }, | |||
| onApprove: function() { | |||
| if(!version_name){ | |||
| document.getElementById(delId).submit() | |||
| } | |||
| else{ | |||
| deleteVersion(version_name,jobID,repoOwner,repoName) | |||
| } | |||
| flag = true | |||
| }, | |||
| onHidden: function() { | |||
| if (flag == false) { | |||
| $('.alert').html('您已取消操作').removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut(); | |||
| } | |||
| } | |||
| }) | |||
| .modal('show') | |||
| } | |||
| } | |||
| function getParams(){ | |||
| const params = new URLSearchParams(window.location.search) | |||
| let jobType = !params.get('jobType')? '全部任务类型' : params.get('jobType') | |||
| let listType = !params.get('listType')? '全部计算资源' : params.get('listType') | |||
| let jobStatus = !params.get('jobStatus')? '全部状态' : params.get('jobStatus') | |||
| const dropdownValueArray = [jobType,listType,jobStatus] | |||
| $('#adminCloud .default.text ').each(function(index,e){ | |||
| $(e).text(dropdownValueArray[index]) | |||
| }) | |||
| } | |||
| getParams() | |||
| function debugAgain(JobID,debugUrl){ | |||
| if($('#' + JobID+ '-text').text()==="RUNNING"){ | |||
| window.open(debugUrl+'debug') | |||
| }else{ | |||
| $.ajax({ | |||
| type:"POST", | |||
| url:debugUrl+'restart', | |||
| data:$('#debugAgainForm-'+JobID).serialize(), | |||
| success:function(res){ | |||
| if(res.result_code==="0"){ | |||
| if(res.job_id!==JobID){ | |||
| location.reload() | |||
| }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") | |||
| } | |||
| }else{ | |||
| $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | |||
| } | |||
| }, | |||
| error :function(res){ | |||
| console.log(res) | |||
| } | |||
| }) | |||
| } | |||
| } | |||
| function stopDebug(JobID,stopUrl){ | |||
| $.ajax({ | |||
| type:"POST", | |||
| url:stopUrl, | |||
| data:$('#stopForm-'+JobID).serialize(), | |||
| success:function(res){ | |||
| if(res.result_code==="0"){ | |||
| $('#' + JobID+'-icon').removeClass().addClass(res.status) | |||
| $('#' + JobID+ '-text').text(res.status) | |||
| 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') | |||
| } | |||
| else{ | |||
| $('#ai-debug-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-stop-'+JobID).removeClass('blue').addClass('disabled') | |||
| } | |||
| }else{ | |||
| $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | |||
| } | |||
| }, | |||
| error :function(res){ | |||
| console.log(res) | |||
| } | |||
| }) | |||
| } | |||
| function stopVersion(version_name,jobID,repoOwner,repoName){ | |||
| const url = `/api/v1/repos/${repoOwner}/${repoName}/modelarts/inference-job/${jobID}/stop_version` | |||
| $.post(url,{version_name:version_name},(data)=>{ | |||
| if(data.StatusOK===0){ | |||
| $('#ai-stop-'+jobID).removeClass('blue') | |||
| $('#ai-stop-'+jobID).addClass('disabled') | |||
| refreshStatus(version_name,jobID,repoOwner,repoName) | |||
| } | |||
| }).fail(function(err) { | |||
| console.log(err); | |||
| }); | |||
| } | |||
| function refreshStatus(version_name,jobID,repoOwner,repoName){ | |||
| const url = `/api/v1/repos/${repoOwner}/${repoName}/modelarts/inference-job/${jobID}/?version_name${version_name}` | |||
| $.get(url,(data)=>{ | |||
| $(`#${jobID}-icon`).attr("class",data.JobStatus) | |||
| // detail status and duration | |||
| $(`#${jobID}-text`).text(data.JobStatus) | |||
| }).fail(function(err) { | |||
| console.log(err); | |||
| }); | |||
| } | |||
| var timeid = window.setInterval(loadJobStatus, 15000); | |||
| $(document).ready(loadJobStatus); | |||
| function loadJobStatus() { | |||
| $(".job-status").each((index, job) => { | |||
| const jobID = job.dataset.jobid; | |||
| const repoPath = job.dataset.repopath; | |||
| const computeResource = job.dataset.resource | |||
| const versionname = job.dataset.version | |||
| 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(job.textContent.trim())) { | |||
| return | |||
| } | |||
| // const diffResource = computeResource == "NPU" ? 'modelarts/notebook' : 'cloudbrain' | |||
| $.get(`/api/v1/repos/${repoPath}/${jobID}?version_name=${versionname}`, (data) => { | |||
| const jobID = data.JobID | |||
| const status = data.JobStatus | |||
| if (status != job.textContent.trim()) { | |||
| $('#' + jobID+'-icon').removeClass().addClass(status) | |||
| $('#' + jobID+ '-text').text(status) | |||
| } | |||
| if(status==="RUNNING"){ | |||
| $('#ai-debug-'+jobID).removeClass('disabled').addClass('blue').text('调试').css("margin","0 1rem") | |||
| $('#model-image-'+jobID).removeClass('disabled').addClass('blue') | |||
| } | |||
| if(status!=="RUNNING"){ | |||
| // $('#model-debug-'+jobID).removeClass('blue') | |||
| // $('#model-debug-'+jobID).addClass('disabled') | |||
| $('#model-image-'+jobID).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(["CREATING","STOPPING","WAITING","STARTING"].includes(status)){ | |||
| $('#ai-debug-'+jobID).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED'].includes(status)){ | |||
| $('#ai-debug-'+jobID).removeClass('disabled').addClass('blue').text('再次调试').css("margin","0") | |||
| } | |||
| if(["RUNNING","WAITING"].includes(status)){ | |||
| $('#ai-stop-'+jobID).removeClass('disabled').addClass('blue') | |||
| } | |||
| if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED","SUCCEEDED"].includes(status)){ | |||
| $('#ai-stop-'+jobID).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(status==="STOPPED" || status==="FAILED"|| status==="START_FAILED" || status==="KILLED" || status==="COMPLETED"){ | |||
| $('#ai-delete-'+jobID).removeClass('disabled').addClass('blue') | |||
| }else{ | |||
| $('#ai-delete-'+jobID).removeClass('blue').addClass('disabled') | |||
| } | |||
| }).fail(function(err) { | |||
| console.log(err); | |||
| }); | |||
| }); | |||
| }; | |||
| </script> | |||
| @@ -14,6 +14,9 @@ | |||
| <a class="{{if .PageIsAdminDatasets}}active{{end}} item" href="{{AppSubUrl}}/admin/datasets"> | |||
| {{.i18n.Tr "admin.datasets"}} | |||
| </a> | |||
| <a class="{{if .PageIsAdminCloudBrains}}active{{end}} item" href="{{AppSubUrl}}/admin/cloudbrains"> | |||
| 云脑任务 | |||
| </a> | |||
| <a class="{{if .PageIsAdminHooks}}active{{end}} item" href="{{AppSubUrl}}/admin/hooks"> | |||
| {{.i18n.Tr "admin.hooks"}} | |||
| </a> | |||
| @@ -120,7 +120,6 @@ | |||
| <script> | |||
| function show_bt(bt_id){ | |||
| console.log(bt_id) | |||
| document.getElementById(""+bt_id).getElementsByClassName("button_leaveOrg")[0].style.display="inline-block"; | |||
| } | |||
| @@ -223,7 +223,6 @@ | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| console.log({{.Tasks}}) | |||
| // 调试和评分新开窗口 | |||
| function stop(obj) { | |||
| if (obj.style.color != "rgb(204, 204, 204)") { | |||
| @@ -183,7 +183,6 @@ | |||
| function setChildType(){ | |||
| let type_id = $('#benchmark_types_id').val(); | |||
| $.get(`${repolink}/cloudbrain/benchmark/get_child_types?benchmark_type_id=${type_id}`, (data) => { | |||
| console.log(JSON.stringify(data)) | |||
| const n_length = data['child_types'].length | |||
| let html='' | |||
| for (let i=0;i<n_length;i++){ | |||
| @@ -94,7 +94,6 @@ $(document).ready(function(){ | |||
| $('#course_label_item').empty() | |||
| }else{ | |||
| $.get(`/api/v1/topics/search?q=${query}`,(data)=>{ | |||
| console.log(data) | |||
| if(data.topics.length!==0){ | |||
| let html='' | |||
| $('#course_label_item').empty() | |||
| @@ -107,5 +106,4 @@ $(document).ready(function(){ | |||
| } | |||
| }); | |||
| }) | |||
| console.log() | |||
| </script> | |||
| @@ -324,11 +324,11 @@ | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDebug}} | |||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | |||
| <a style="margin: 0 1rem;" id="model-debug-{{.JobID}}" class='ui basic {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' onclick='debugAgain("{{.JobID}}","{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}/")'> | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{.JobID}}" class='ui basic {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' onclick='debugAgain("{{.JobID}}","{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}/")'> | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{else}} | |||
| <a id="model-debug-{{.JobID}}" class='ui basic {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' onclick='debugAgain("{{.JobID}}","{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}/")'> | |||
| <a id="ai-debug-{{.JobID}}" class='ui basic {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' onclick='debugAgain("{{.JobID}}","{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}/")'> | |||
| {{$.i18n.Tr "repo.debug_again"}} | |||
| </a> | |||
| {{end}} | |||
| @@ -350,11 +350,11 @@ | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| {{if eq .ComputeResource "CPU/GPU" }} | |||
| <a id="stop-model-debug-{{.JobID}}" class='ui basic {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' onclick='stopDebug("{{.JobID}}","{{$.RepoLink}}/cloudbrain/{{.JobID}}/stop")'> | |||
| <a id="ai-stop-{{.JobID}}" class='ui basic {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' onclick='stopDebug("{{.JobID}}","{{$.RepoLink}}/cloudbrain/{{.JobID}}/stop")'> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| {{else}} | |||
| <a id="stop-model-debug-{{.JobID}}" class='ui basic {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' onclick='stopDebug("{{.JobID}}","{{$.RepoLink}}/modelarts/notebook/{{.JobID}}/stop")'> | |||
| <a id="ai-stop-{{.JobID}}" class='ui basic {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' onclick='stopDebug("{{.JobID}}","{{$.RepoLink}}/modelarts/notebook/{{.JobID}}/stop")'> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| {{end}} | |||
| @@ -369,7 +369,7 @@ | |||
| <input type="hidden" name="debugListType" value="all"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a id="model-delete-{{.JobID}}" class='ui basic {{if eq .Status "STOPPED" "FAILED" "START_FAILED"}}blue {{else}}disabled {{end}}button' onclick="assertDelete(this)" style="border-radius: .28571429rem;"> | |||
| <a id="ai-delete-{{.JobID}}" class='ui basic {{if eq .Status "STOPPED" "FAILED" "START_FAILED"}}blue {{else}}disabled {{end}}button' onclick="assertDelete(this)" style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| {{else}} | |||
| @@ -490,7 +490,6 @@ | |||
| <script> | |||
| // 调试和评分新开窗口 | |||
| console.log({{.Tasks}}) | |||
| const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; | |||
| let url={{.RepoLink}} | |||
| let getParam=getQueryVariable('debugListType') | |||
| @@ -554,9 +553,9 @@ | |||
| }else{ | |||
| $('#' + JobID+'-icon').removeClass().addClass(res.status) | |||
| $('#' + JobID+ '-text').text(res.status) | |||
| $('#model-debug-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#model-delete-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#model-debug-'+JobID).text("调试").css("margin","0 1rem") | |||
| $('#ai-debug-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-delete-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-debug-'+JobID).text("调试").css("margin","0 1rem") | |||
| } | |||
| }else{ | |||
| $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | |||
| @@ -580,14 +579,14 @@ | |||
| $('#' + JobID+'-icon').removeClass().addClass(res.status) | |||
| $('#' + JobID+ '-text').text(res.status) | |||
| if(res.status==="STOPPED"){ | |||
| $('#model-debug-'+JobID).removeClass('disabled').addClass('blue').text("再次调试").css("margin","0") | |||
| $('#ai-debug-'+JobID).removeClass('disabled').addClass('blue').text("再次调试").css("margin","0") | |||
| $('#model-image-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#stop-model-debug-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#model-delete-'+JobID).removeClass('disabled').addClass('blue') | |||
| $('#ai-stop-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-delete-'+JobID).removeClass('disabled').addClass('blue') | |||
| } | |||
| else{ | |||
| $('#model-debug-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#stop-model-debug-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-debug-'+JobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-stop-'+JobID).removeClass('blue').addClass('disabled') | |||
| } | |||
| }else{ | |||
| @@ -623,7 +622,7 @@ | |||
| $('#' + jobID+ '-text').text(status) | |||
| } | |||
| if(status==="RUNNING"){ | |||
| $('#model-debug-'+jobID).removeClass('disabled').addClass('blue').text('调试').css("margin","0 1rem") | |||
| $('#ai-debug-'+jobID).removeClass('disabled').addClass('blue').text('调试').css("margin","0 1rem") | |||
| $('#model-image-'+jobID).removeClass('disabled').addClass('blue') | |||
| } | |||
| if(status!=="RUNNING"){ | |||
| @@ -632,21 +631,21 @@ | |||
| $('#model-image-'+jobID).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(["CREATING","STOPPING","WAITING","STARTING"].includes(status)){ | |||
| $('#model-debug-'+jobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-debug-'+jobID).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED'].includes(status)){ | |||
| $('#model-debug-'+jobID).removeClass('disabled').addClass('blue').text('再次调试').css("margin","0") | |||
| $('#ai-debug-'+jobID).removeClass('disabled').addClass('blue').text('再次调试').css("margin","0") | |||
| } | |||
| if(["RUNNING","WAITING"].includes(status)){ | |||
| $('#stop-model-debug-'+jobID).removeClass('disabled').addClass('blue') | |||
| $('#ai-stop-'+jobID).removeClass('disabled').addClass('blue') | |||
| } | |||
| if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED","SUCCEEDED"].includes(status)){ | |||
| $('#stop-model-debug-'+jobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-stop-'+jobID).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(status==="STOPPED" || status==="FAILED"|| status==="START_FAILED"){ | |||
| $('#model-delete-'+jobID).removeClass('disabled').addClass('blue') | |||
| $('#ai-delete-'+jobID).removeClass('disabled').addClass('blue') | |||
| }else{ | |||
| $('#model-delete-'+jobID).removeClass('blue').addClass('disabled') | |||
| $('#ai-delete-'+jobID).removeClass('blue').addClass('disabled') | |||
| } | |||
| }).fail(function(err) { | |||
| console.log(err); | |||
| @@ -209,7 +209,6 @@ | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| console.log({{.Tasks}}) | |||
| // 调试和评分新开窗口 | |||
| function stop(obj) { | |||
| if (obj.style.color != "rgb(204, 204, 204)") { | |||
| @@ -186,7 +186,6 @@ | |||
| <div class='ui breadcrumb model_file_bread' id='file_breadcrumb'> | |||
| <div class="active section"></div> | |||
| <div class="divider"> / </div> | |||
| </div> | |||
| <div id="dir_list"> | |||
| @@ -52,6 +52,4 @@ | |||
| </div> | |||
| <script> | |||
| console.log({{$.Err_Alias}}) | |||
| </script> | |||
| @@ -208,6 +208,3 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| console.log({{.Issues}}) | |||
| </script> | |||
| @@ -117,6 +117,3 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| console.log({{.Milestones}}) | |||
| </script> | |||
| @@ -141,6 +141,7 @@ | |||
| {{if eq .TabName "activity"}} | |||
| {{if .EnableHeatmap}} | |||
| <div id="user-heatmap" style="padding-right: 40px"> | |||
| <activity-heatmap :locale="locale" :suburl="suburl" :user="heatmapUser"> | |||
| <div slot="loading"> | |||
| @@ -310,7 +310,6 @@ export default { | |||
| }, | |||
| handleCurrentChange(val){ | |||
| console.log(val) | |||
| this.params.page = val | |||
| this.getImageList() | |||
| @@ -350,7 +349,6 @@ export default { | |||
| }) | |||
| }, | |||
| copyUrl(url){ | |||
| console.log(url) | |||
| const cInput = document.createElement('input') | |||
| cInput.value = url | |||
| document.body.appendChild(cInput) | |||
| @@ -380,16 +378,13 @@ export default { | |||
| clearP(value){ | |||
| console.log("sorce value",value) | |||
| if(!value) return '' | |||
| const reg = /\<\/?p\>/g; | |||
| value = value.replace(reg,'') | |||
| console.log("repalace:",value) | |||
| return value | |||
| }, | |||
| transformTimestamp(timestamp){ | |||
| console.log("timestamp",timestamp) | |||
| let a = new Date(timestamp).getTime(); | |||
| const date = new Date(a); | |||
| const Y = date.getFullYear() + '-'; | |||
| @@ -200,7 +200,6 @@ | |||
| var saveFileName='' | |||
| var Date=(this.params.startDate).split('-') | |||
| var startDate=Date[0]+''+Date[1]+''+Date[2] | |||
| console.log(startDate) | |||
| Date=(this.params.endDate).split('-') | |||
| var endDate=Date[0]+Date[1]+Date[2] | |||
| saveFileName = '用户分析_'+this.search+''+startDate+'_'+endDate | |||
| @@ -258,7 +257,6 @@ | |||
| getUserList(type_val,index){ | |||
| this.type_val = type_val | |||
| this.dynamic = index; | |||
| console.log("dj:"+type_val) | |||
| var now = new Date(); // 当前日期 | |||
| var nowDayOfWeek = now.getDay(); // 今天本周的第几天 | |||
| var nowDay = now.getDate(); // 当前日 | |||
| @@ -324,7 +322,6 @@ | |||
| // console.log("res.data:"+res.data.data) | |||
| this.totalNum = res.data.count | |||
| console.log("res.count:"+res.data.count) | |||
| }) | |||
| @@ -354,9 +351,7 @@ | |||
| }, | |||
| filters:{ | |||
| transformTimestamp(timestamp){ | |||
| console.log("timestamp",timestamp) | |||
| let a = new Date(timestamp*1000); | |||
| const date = new Date(a); | |||
| const Y = date.getFullYear() + '/'; | |||
| @@ -366,7 +361,6 @@ | |||
| const m = (date.getMinutes() <10 ? '0'+date.getMinutes() : date.getMinutes());// + ':' ; | |||
| // const s = (date.getSeconds() <10 ? '0'+date.getSeconds() : date.getSeconds()) ; // 秒 | |||
| const dateString = Y + M + D + h + m ;//+ s; | |||
| console.log('dateString', dateString); // > dateString 2021-07-06 14:23 | |||
| return dateString; | |||
| }, | |||
| }, | |||
| @@ -100,7 +100,6 @@ export function export_table_to_excel(id) { | |||
| /* original data */ | |||
| var data = oo[0]; | |||
| var ws_name = "SheetJS"; | |||
| console.log(data); | |||
| var wb = new Workbook(), ws = sheet_from_array_of_arrays(data); | |||
| @@ -118,7 +117,7 @@ export function export_table_to_excel(id) { | |||
| } | |||
| function formatJson(jsonData) { | |||
| console.log(jsonData) | |||
| } | |||
| export function export_json_to_excel(th, jsonData, defaultTitle) { | |||
| @@ -3,7 +3,6 @@ export function export2Excel(columns,list,filename){ | |||
| const { export_json_to_excel } = require('./Export2Excel'); | |||
| let tHeader = [] | |||
| let filterVal = [] | |||
| console.log(columns) | |||
| if(!columns){ | |||
| return; | |||
| } | |||
| @@ -41,6 +41,7 @@ import DataAnalysis from './components/DataAnalysis.vue' | |||
| import Contributors from './components/Contributors.vue' | |||
| import Model from './components/Model.vue'; | |||
| Vue.use(ElementUI); | |||
| Vue.prototype.$axios = axios; | |||
| Vue.prototype.qs = qs; | |||
| @@ -3584,14 +3585,16 @@ function initVueApp() { | |||
| } | |||
| initVueComponents(); | |||
| new Vue({ | |||
| delimiters: ['${', '}'], | |||
| el, | |||
| data: { | |||
| page:parseInt(new URLSearchParams(window.location.search).get('page')), | |||
| searchLimit: Number( | |||
| (document.querySelector('meta[name=_search_limit]') || {}).content | |||
| ), | |||
| page:1, | |||
| suburl: AppSubUrl, | |||
| uid: Number( | |||
| (document.querySelector('meta[name=_context_uid]') || {}).content | |||
| @@ -3600,6 +3603,15 @@ function initVueApp() { | |||
| }, | |||
| components: { | |||
| ActivityTopAuthors | |||
| }, | |||
| mounted(){ | |||
| this.page = parseInt(new URLSearchParams(window.location.search).get('page')) | |||
| }, | |||
| methods:{ | |||
| handleCurrentChange:function (val) { | |||
| window.location.href='/admin/cloudbrains?page='+val | |||
| this.page = val | |||
| } | |||
| } | |||
| }); | |||
| } | |||
| @@ -3688,8 +3700,6 @@ function initVueModel() { | |||
| } | |||
| function initVueDataAnalysis() { | |||
| const el = document.getElementById('data_analysis'); | |||
| console.log("el",el) | |||
| if (!el) { | |||
| return; | |||
| } | |||
| @@ -3756,7 +3766,6 @@ function initFilterBranchTagDropdown(selector) { | |||
| }); | |||
| }); | |||
| $data.remove(); | |||
| console.log("-this",this) | |||
| new Vue({ | |||
| delimiters: ['${', '}'], | |||
| el: this, | |||
| @@ -115,6 +115,15 @@ module.exports = { | |||
| }, | |||
| ], | |||
| }, | |||
| { | |||
| test: /\.ts$/, | |||
| use: [ | |||
| { | |||
| loader: "ts-loader", | |||
| } | |||
| ], | |||
| exclude: /node_modules/ | |||
| }, | |||
| { | |||
| test: /\.js$/, | |||
| exclude: /node_modules/, | |||
| @@ -252,6 +261,7 @@ module.exports = { | |||
| alias: { | |||
| vue$: 'vue/dist/vue.esm.js', // needed because vue's default export is the runtime only | |||
| }, | |||
| extensions: ['.tsx', '.ts', '.js'] | |||
| }, | |||
| watchOptions: { | |||
| ignored: [ | |||