Browse Source

Merge remote-tracking branch 'origin/V20211228' into inference-job

tags/v1.22.1.2
liuzx 3 years ago
parent
commit
67b2bbd737
15 changed files with 533 additions and 168 deletions
  1. +4
    -1
      models/cloudbrain.go
  2. +31
    -39
      models/user_business_analysis.go
  3. +130
    -11
      modules/cloudbrain/cloudbrain.go
  4. +1
    -1
      modules/modelarts/modelarts.go
  5. +3
    -3
      modules/modelarts/resty.go
  6. +5
    -0
      modules/storage/minio.go
  7. +1
    -0
      options/locale/locale_zh-CN.ini
  8. +116
    -32
      routers/repo/cloudbrain.go
  9. +1
    -0
      routers/repo/milestone.go
  10. +89
    -36
      routers/repo/modelarts.go
  11. +2
    -1
      routers/routes/routes.go
  12. +135
    -42
      templates/repo/debugjob/index.tmpl
  13. +6
    -0
      templates/repo/header.tmpl
  14. +2
    -1
      templates/repo/home.tmpl
  15. +7
    -1
      web_src/js/components/Contributors.vue

+ 4
- 1
models/cloudbrain.go View File

@@ -89,6 +89,9 @@ type Cloudbrain struct {
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
Duration int64 Duration int64
TrainJobDuration string TrainJobDuration string
Image string //GPU镜像名称
GpuQueue string //GPU类型即GPU队列
ResourceSpecId int //GPU规格id
DeletedAt time.Time `xorm:"deleted"` DeletedAt time.Time `xorm:"deleted"`
CanDebug bool `xorm:"-"` CanDebug bool `xorm:"-"`
CanDel bool `xorm:"-"` CanDel bool `xorm:"-"`
@@ -103,7 +106,7 @@ type Cloudbrain struct {
IsLatestVersion string //是否是最新版本,1是,0否 IsLatestVersion string //是否是最新版本,1是,0否
CommitID string //提交的仓库代码id CommitID string //提交的仓库代码id
PreVersionName string //父版本名称 PreVersionName string //父版本名称
ComputeResource string //计算资源,例如npu
ComputeResource string `xorm:"-"` //计算资源,例如npu
EngineID int64 //引擎id EngineID int64 //引擎id


TrainUrl string //输出模型的obs路径 TrainUrl string //输出模型的obs路径


+ 31
- 39
models/user_business_analysis.go View File

@@ -1,7 +1,6 @@
package models package models


import ( import (
"encoding/json"
"fmt" "fmt"
"sort" "sort"
"strconv" "strconv"
@@ -202,15 +201,7 @@ func QueryUserStaticDataAll(opts *UserBusinessAnalysisQueryOptions) ([]*UserBusi
return nil, 0 return nil, 0
} }
log.Info("query return total:" + fmt.Sprint(allCount)) log.Info("query return total:" + fmt.Sprint(allCount))
if allCount == 0 {
CommitCodeSizeMap, err := GetAllUserKPIStats()
if err != nil {
log.Info("query commit code errr.")
} else {
log.Info("query commit code size, len=" + fmt.Sprint(len(CommitCodeSizeMap)))
}
RefreshUserStaticAllTabel(make(map[string]int), CommitCodeSizeMap)
}

pageSize := 1000 pageSize := 1000
totalPage := int(allCount) / pageSize totalPage := int(allCount) / pageSize
userBusinessAnalysisReturnList := UserBusinessAnalysisAllList{} userBusinessAnalysisReturnList := UserBusinessAnalysisAllList{}
@@ -370,7 +361,7 @@ func RefreshUserStaticAllTabel(wikiCountMap map[string]int, CommitCodeSizeMap ma


CodeMergeCountMap := queryPullRequest(start_unix, end_unix) CodeMergeCountMap := queryPullRequest(start_unix, end_unix)
CommitCountMap := queryCommitAction(start_unix, end_unix, 5) CommitCountMap := queryCommitAction(start_unix, end_unix, 5)
IssueCountMap := queryAction(start_unix, end_unix, 6)
IssueCountMap := queryCreateIssue(start_unix, end_unix)


CommentCountMap := queryComment(start_unix, end_unix) CommentCountMap := queryComment(start_unix, end_unix)
FocusRepoCountMap := queryWatch(start_unix, end_unix) FocusRepoCountMap := queryWatch(start_unix, end_unix)
@@ -395,7 +386,7 @@ func RefreshUserStaticAllTabel(wikiCountMap map[string]int, CommitCodeSizeMap ma
var indexTotal int64 var indexTotal int64
indexTotal = 0 indexTotal = 0
for { for {
sess.Select("`user`.*").Table("user").Where(cond).Limit(Page_SIZE, int(indexTotal))
sess.Select("`user`.*").Table("user").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
userList := make([]*User, 0) userList := make([]*User, 0)
sess.Find(&userList) sess.Find(&userList)
for i, userRecord := range userList { for i, userRecord := range userList {
@@ -528,7 +519,7 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time,
DataDate := startTime.Format("2006-01-02") DataDate := startTime.Format("2006-01-02")
CodeMergeCountMap := queryPullRequest(start_unix, end_unix) CodeMergeCountMap := queryPullRequest(start_unix, end_unix)
CommitCountMap := queryCommitAction(start_unix, end_unix, 5) CommitCountMap := queryCommitAction(start_unix, end_unix, 5)
IssueCountMap := queryAction(start_unix, end_unix, 6)
IssueCountMap := queryCreateIssue(start_unix, end_unix)


CommentCountMap := queryComment(start_unix, end_unix) CommentCountMap := queryComment(start_unix, end_unix)
FocusRepoCountMap := queryWatch(start_unix, end_unix) FocusRepoCountMap := queryWatch(start_unix, end_unix)
@@ -559,7 +550,7 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time,
var indexTotal int64 var indexTotal int64
indexTotal = 0 indexTotal = 0
for { for {
sess.Select("`user`.*").Table("user").Where(cond).Limit(Page_SIZE, int(indexTotal))
sess.Select("`user`.*").Table("user").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
userList := make([]*User, 0) userList := make([]*User, 0)
sess.Find(&userList) sess.Find(&userList)


@@ -709,7 +700,7 @@ func querySolveIssue(start_unix int64, end_unix int64) map[int64]int {
issueAssigneesList := make([]*IssueAssignees, 0) issueAssigneesList := make([]*IssueAssignees, 0)
sess.Select("issue_assignees.*").Table("issue_assignees"). sess.Select("issue_assignees.*").Table("issue_assignees").
Join("inner", "issue", "issue.id=issue_assignees.issue_id"). Join("inner", "issue", "issue.id=issue_assignees.issue_id").
Where(cond).Limit(Page_SIZE, int(indexTotal))
Where(cond).OrderBy("issue_assignees.id asc").Limit(Page_SIZE, int(indexTotal))


sess.Find(&issueAssigneesList) sess.Find(&issueAssigneesList)


@@ -744,7 +735,7 @@ func queryPullRequest(start_unix int64, end_unix int64) map[int64]int {
indexTotal = 0 indexTotal = 0
for { for {
issueList := make([]*Issue, 0) issueList := make([]*Issue, 0)
sess.Select("issue.*").Table("issue").Join("inner", "pull_request", "issue.id=pull_request.issue_id").Where(cond).Limit(Page_SIZE, int(indexTotal))
sess.Select("issue.*").Table("issue").Join("inner", "pull_request", "issue.id=pull_request.issue_id").Where(cond).OrderBy("issue.id asc").Limit(Page_SIZE, int(indexTotal))
sess.Find(&issueList) sess.Find(&issueList)
log.Info("query issue(PR) size=" + fmt.Sprint(len(issueList))) log.Info("query issue(PR) size=" + fmt.Sprint(len(issueList)))
for _, issueRecord := range issueList { for _, issueRecord := range issueList {
@@ -777,7 +768,7 @@ func queryCommitAction(start_unix int64, end_unix int64, actionType int64) map[i
var indexTotal int64 var indexTotal int64
indexTotal = 0 indexTotal = 0
for { for {
sess.Select("id,user_id,op_type,act_user_id").Table("action").Where(cond).Limit(Page_SIZE, int(indexTotal))
sess.Select("id,user_id,op_type,act_user_id").Table("action").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
actionList := make([]*Action, 0) actionList := make([]*Action, 0)
sess.Find(&actionList) sess.Find(&actionList)


@@ -799,29 +790,30 @@ func queryCommitAction(start_unix int64, end_unix int64, actionType int64) map[i
return resultMap return resultMap
} }


func queryAction(start_unix int64, end_unix int64, actionType int64) map[int64]int {
func queryCreateIssue(start_unix int64, end_unix int64) map[int64]int {

sess := x.NewSession() sess := x.NewSession()
defer sess.Close() defer sess.Close()
resultMap := make(map[int64]int) resultMap := make(map[int64]int)
cond := "op_type=" + fmt.Sprint(actionType) + " and created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)
cond := "is_pull=false and created_unix>=" + fmt.Sprint(start_unix) + " and created_unix<=" + fmt.Sprint(end_unix)


count, err := sess.Where(cond).Count(new(Action))
count, err := sess.Where(cond).Count(new(Issue))
if err != nil { if err != nil {
log.Info("query Action error. return.")
log.Info("query Issue error. return.")
return resultMap return resultMap
} }
var indexTotal int64 var indexTotal int64
indexTotal = 0 indexTotal = 0
for { for {
sess.Select("id,user_id,op_type,act_user_id").Table("action").Where(cond).Limit(Page_SIZE, int(indexTotal))
actionList := make([]*Action, 0)
sess.Find(&actionList)
log.Info("query action size=" + fmt.Sprint(len(actionList)))
for _, actionRecord := range actionList {
if _, ok := resultMap[actionRecord.UserID]; !ok {
resultMap[actionRecord.UserID] = 1
sess.Select("id,poster_id").Table("issue").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
issueList := make([]*Issue, 0)
sess.Find(&issueList)
log.Info("query issue size=" + fmt.Sprint(len(issueList)))
for _, issueRecord := range issueList {
if _, ok := resultMap[issueRecord.PosterID]; !ok {
resultMap[issueRecord.PosterID] = 1
} else { } else {
resultMap[actionRecord.UserID] += 1
resultMap[issueRecord.PosterID] += 1
} }
} }
indexTotal += Page_SIZE indexTotal += Page_SIZE
@@ -830,6 +822,7 @@ func queryAction(start_unix int64, end_unix int64, actionType int64) map[int64]i
} }
} }
return resultMap return resultMap

} }


func queryComment(start_unix int64, end_unix int64) map[int64]int { func queryComment(start_unix int64, end_unix int64) map[int64]int {
@@ -846,7 +839,7 @@ func queryComment(start_unix int64, end_unix int64) map[int64]int {
var indexTotal int64 var indexTotal int64
indexTotal = 0 indexTotal = 0
for { for {
sess.Select("id,type,poster_id").Table("comment").Where(cond).Limit(Page_SIZE, int(indexTotal))
sess.Select("id,type,poster_id").Table("comment").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
commentList := make([]*Comment, 0) commentList := make([]*Comment, 0)
sess.Find(&commentList) sess.Find(&commentList)
log.Info("query Comment size=" + fmt.Sprint(len(commentList))) log.Info("query Comment size=" + fmt.Sprint(len(commentList)))
@@ -882,7 +875,7 @@ func queryWatch(start_unix int64, end_unix int64) map[int64]int {
indexTotal = 0 indexTotal = 0
for { for {
watchList := make([]*Watch, 0) watchList := make([]*Watch, 0)
sess.Select("id,user_id,repo_id").Table("watch").Where(cond).Limit(Page_SIZE, int(indexTotal))
sess.Select("id,user_id,repo_id").Table("watch").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
sess.Find(&watchList) sess.Find(&watchList)


log.Info("query Watch size=" + fmt.Sprint(len(watchList))) log.Info("query Watch size=" + fmt.Sprint(len(watchList)))
@@ -920,7 +913,7 @@ func queryStar(start_unix int64, end_unix int64) map[int64]int {
var indexTotal int64 var indexTotal int64
indexTotal = 0 indexTotal = 0
for { for {
sess.Select("id,uid,repo_id").Table("star").Where(cond).Limit(Page_SIZE, int(indexTotal))
sess.Select("id,uid,repo_id").Table("star").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
starList := make([]*Star, 0) starList := make([]*Star, 0)
sess.Find(&starList) sess.Find(&starList)


@@ -956,7 +949,7 @@ func queryFollow(start_unix int64, end_unix int64) map[int64]int {
var indexTotal int64 var indexTotal int64
indexTotal = 0 indexTotal = 0
for { for {
sess.Select("id,user_id,follow_id").Table("follow").Where(cond).Limit(Page_SIZE, int(indexTotal))
sess.Select("id,user_id,follow_id").Table("follow").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
followList := make([]*Follow, 0) followList := make([]*Follow, 0)
sess.Find(&followList) sess.Find(&followList)


@@ -992,7 +985,7 @@ func queryDatasetSize(start_unix int64, end_unix int64) map[int64]int {
var indexTotal int64 var indexTotal int64
indexTotal = 0 indexTotal = 0
for { for {
sess.Select("id,uploader_id,size").Table("attachment").Where(cond).Limit(Page_SIZE, int(indexTotal))
sess.Select("id,uploader_id,size").Table("attachment").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
attachmentList := make([]*Attachment, 0) attachmentList := make([]*Attachment, 0)
sess.Find(&attachmentList) sess.Find(&attachmentList)


@@ -1028,7 +1021,7 @@ func queryUserCreateRepo(start_unix int64, end_unix int64) map[int64]int {
var indexTotal int64 var indexTotal int64
indexTotal = 0 indexTotal = 0
for { for {
sess.Select("id,owner_id,name").Table("repository").Where(cond).Limit(Page_SIZE, int(indexTotal))
sess.Select("id,owner_id,name").Table("repository").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
repoList := make([]*Repository, 0) repoList := make([]*Repository, 0)
sess.Find(&repoList) sess.Find(&repoList)
log.Info("query Repository size=" + fmt.Sprint(len(repoList))) log.Info("query Repository size=" + fmt.Sprint(len(repoList)))
@@ -1099,8 +1092,7 @@ func queryUserRepoOpenIIndex(start_unix int64, end_unix int64) map[int64]float64
} }
} }


userMapJson, _ := json.Marshal(userMap)
log.Info("userMapJson=" + string(userMapJson))
log.Info("user openi index size=" + fmt.Sprint(len(userMap)))


return userMap return userMap
} }
@@ -1119,7 +1111,7 @@ func queryLoginCount(start_unix int64, end_unix int64) map[int64]int {
var indexTotal int64 var indexTotal int64
indexTotal = 0 indexTotal = 0
for { for {
statictisSess.Select("id,u_id").Table("user_login_log").Where(cond).Limit(Page_SIZE, int(indexTotal))
statictisSess.Select("id,u_id").Table("user_login_log").Where(cond).OrderBy("id asc").Limit(Page_SIZE, int(indexTotal))
userLoginLogList := make([]*UserLoginLog, 0) userLoginLogList := make([]*UserLoginLog, 0)
statictisSess.Find(&userLoginLogList) statictisSess.Find(&userLoginLogList)
log.Info("query user login size=" + fmt.Sprint(len(userLoginLogList))) log.Info("query user login size=" + fmt.Sprint(len(userLoginLogList)))
@@ -1135,7 +1127,7 @@ func queryLoginCount(start_unix int64, end_unix int64) map[int64]int {
break break
} }
} }
log.Info("user login size=" + fmt.Sprint(len(resultMap)))
return resultMap return resultMap
} }




+ 130
- 11
modules/cloudbrain/cloudbrain.go View File

@@ -1,6 +1,8 @@
package cloudbrain package cloudbrain


import ( import (
"code.gitea.io/gitea/modules/storage"
"encoding/json"
"errors" "errors"
"strconv" "strconv"


@@ -107,6 +109,9 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath,
uuid uuid


var resourceSpec *models.ResourceSpec var resourceSpec *models.ResourceSpec
if ResourceSpecs == nil {
json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs)
}
for _, spec := range ResourceSpecs.ResourceSpec { for _, spec := range ResourceSpecs.ResourceSpec {
if resourceSpecId == spec.Id { if resourceSpecId == spec.Id {
resourceSpec = spec resourceSpec = spec
@@ -185,28 +190,142 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath,
}, },
}) })
if err != nil { if err != nil {
log.Error("CreateJob failed:", err.Error())
log.Error("CreateJob failed:", err.Error(), ctx.Data["MsgID"])
return err return err
} }
if jobResult.Code != Success { if jobResult.Code != Success {
log.Error("CreateJob(%s) failed:%s", jobName, jobResult.Msg)
log.Error("CreateJob(%s) failed:%s", jobName, jobResult.Msg, ctx.Data["MsgID"])
return errors.New(jobResult.Msg) return errors.New(jobResult.Msg)
} }


var jobID = jobResult.Payload["jobId"].(string) var jobID = jobResult.Payload["jobId"].(string)
err = models.CreateCloudbrain(&models.Cloudbrain{ err = models.CreateCloudbrain(&models.Cloudbrain{
Status: string(models.JobWaiting),
UserID: ctx.User.ID,
RepoID: ctx.Repo.Repository.ID,
JobID: jobID,
JobName: jobName,
SubTaskName: SubTaskName,
JobType: jobType,
Type: models.TypeCloudBrainOne,
Uuid: uuid,
Status: string(models.JobWaiting),
UserID: ctx.User.ID,
RepoID: ctx.Repo.Repository.ID,
JobID: jobID,
JobName: jobName,
SubTaskName: SubTaskName,
JobType: jobType,
Type: models.TypeCloudBrainOne,
Uuid: uuid,
Image: image,
GpuQueue: gpuQueue,
ResourceSpecId: resourceSpecId,
})

if err != nil {
return err
}

return nil
}

func RestartTask(ctx *context.Context, task *models.Cloudbrain) error {
dataActualPath := setting.Attachment.Minio.RealPath +
setting.Attachment.Minio.Bucket + "/" +
setting.Attachment.Minio.BasePath +
models.AttachmentRelativePath(task.Uuid) +
task.Uuid
jobName := task.JobName

var resourceSpec *models.ResourceSpec
if ResourceSpecs == nil {
json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs)
}
for _, spec := range ResourceSpecs.ResourceSpec {
if task.ResourceSpecId == spec.Id {
resourceSpec = spec
}
}

if resourceSpec == nil {
log.Error("no such resourceSpecId(%d)", task.ResourceSpecId, ctx.Data["MsgID"])
return errors.New("no such resourceSpec")
}

jobResult, err := CreateJob(jobName, models.CreateJobParams{
JobName: jobName,
RetryCount: 1,
GpuType: task.GpuQueue,
Image: task.Image,
TaskRoles: []models.TaskRole{
{
Name: SubTaskName,
TaskNumber: 1,
MinSucceededTaskCount: 1,
MinFailedTaskCount: 1,
CPUNumber: resourceSpec.CpuNum,
GPUNumber: resourceSpec.GpuNum,
MemoryMB: resourceSpec.MemMiB,
ShmMB: resourceSpec.ShareMemMiB,
Command: Command,
NeedIBDevice: false,
IsMainRole: false,
UseNNI: false,
},
},
Volumes: []models.Volume{
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, CodeMountPath + "/"),
MountPath: CodeMountPath,
ReadOnly: false,
},
},
{
HostPath: models.StHostPath{
Path: dataActualPath,
MountPath: DataSetMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, ModelMountPath + "/"),
MountPath: ModelMountPath,
ReadOnly: false,
},
},
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, BenchMarkMountPath + "/"),
MountPath: BenchMarkMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, Snn4imagenetMountPath + "/"),
MountPath: Snn4imagenetMountPath,
ReadOnly: true,
},
},
{
HostPath: models.StHostPath{
Path: storage.GetMinioPath(jobName, BrainScoreMountPath + "/"),
MountPath: BrainScoreMountPath,
ReadOnly: true,
},
},
},
}) })
if err != nil {
log.Error("CreateJob failed:", err.Error(), ctx.Data["MsgID"])
return err
}
if jobResult.Code != Success {
log.Error("CreateJob(%s) failed:%s", jobName, jobResult.Msg, ctx.Data["MsgID"])
return errors.New(jobResult.Msg)
}

var jobID = jobResult.Payload["jobId"].(string)
task.JobID = jobID
task.Status = string(models.JobWaiting)
err = models.UpdateJob(task)


if err != nil { if err != nil {
log.Error("UpdateJob(%s) failed:%v", jobName, err.Error(), ctx.Data["MsgID"])
return err return err
} }




+ 1
- 1
modules/modelarts/modelarts.go View File

@@ -306,7 +306,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error
DatasetName: attach.Name, DatasetName: attach.Name,
CommitID: req.CommitID, CommitID: req.CommitID,
IsLatestVersion: req.IsLatestVersion, IsLatestVersion: req.IsLatestVersion,
ComputeResource: NPUResource,
//ComputeResource: NPUResource,
EngineID: req.EngineID, EngineID: req.EngineID,
TrainUrl: req.TrainUrl, TrainUrl: req.TrainUrl,
BranchName: req.BranchName, BranchName: req.BranchName,


+ 3
- 3
modules/modelarts/resty.go View File

@@ -174,7 +174,7 @@ sendjob:
return &result, nil return &result, nil
} }


func StopJob(jobID string, param models.NotebookAction) (*models.NotebookActionResult, error) {
func ManageNotebook(jobID string, param models.NotebookAction) (*models.NotebookActionResult, error) {
checkSetting() checkSetting()
client := getRestyClient() client := getRestyClient()
var result models.NotebookActionResult var result models.NotebookActionResult
@@ -207,8 +207,8 @@ sendjob:
} }


if len(response.ErrorCode) != 0 { if len(response.ErrorCode) != 0 {
log.Error("StopJob failed(%s): %s", response.ErrorCode, response.ErrorMsg)
return &result, fmt.Errorf("StopJob failed(%s): %s", response.ErrorCode, response.ErrorMsg)
log.Error("ManageNotebook failed(%s): %s", response.ErrorCode, response.ErrorMsg)
return &result, fmt.Errorf("ManageNotebook failed(%s): %s", response.ErrorCode, response.ErrorMsg)
} }


return &result, nil return &result, nil


+ 5
- 0
modules/storage/minio.go View File

@@ -11,6 +11,7 @@ import (
"strings" "strings"
"time" "time"


"code.gitea.io/gitea/modules/setting"
"github.com/minio/minio-go" "github.com/minio/minio-go"
) )


@@ -128,3 +129,7 @@ func (m *MinioStorage) UploadObject(fileName, filePath string) error {
_, err := m.client.FPutObject(m.bucket, fileName, filePath, minio.PutObjectOptions{}) _, err := m.client.FPutObject(m.bucket, fileName, filePath, minio.PutObjectOptions{})
return err return err
} }

func GetMinioPath(jobName, suffixPath string) string {
return setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix + jobName + suffixPath
}

+ 1
- 0
options/locale/locale_zh-CN.ini View File

@@ -787,6 +787,7 @@ model_noright=无权限操作
model_rename=模型名称重复,请修改模型名称 model_rename=模型名称重复,请修改模型名称


debug=调试 debug=调试
debug_again=再次调试
stop=停止 stop=停止
delete=删除 delete=删除
model_download=模型下载 model_download=模型下载


+ 116
- 32
routers/repo/cloudbrain.go View File

@@ -206,7 +206,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
} }
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
downloadCode(repo, codePath) downloadCode(repo, codePath)
uploadCodeToMinio(codePath+"/", jobName, "/code/")
uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/")


modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath + "/" modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath + "/"
mkModelPath(modelPath) mkModelPath(modelPath)
@@ -236,9 +236,10 @@ 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, codePath, getMinioPath(jobName, cloudbrain.ModelMountPath+"/"),
getMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), getMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"),
getMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, resourceSpecId)
err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"),
storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"),
storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"),
storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, resourceSpecId)
if err != nil { if err != nil {
cloudBrainNewDataPrepare(ctx) cloudBrainNewDataPrepare(ctx)
ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form)
@@ -247,6 +248,72 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob") ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")
} }


func CloudBrainRestart(ctx *context.Context) {
var jobID = ctx.Params(":jobid")
var resultCode = "0"
var errorMsg = ""
var status = ""

for {
task, err := models.GetCloudbrainByJobID(jobID)
if err != nil {
log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error(), ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "system error"
break
}

if task.Status != string(models.JobStopped) && task.Status != string(models.JobSucceeded) && task.Status != string(models.JobFailed) {
log.Error("the job(%s) is not stopped", task.JobName, ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "the job is not stopped"
break
}

if task.Image == "" || task.GpuQueue == "" || task.Type != models.TypeCloudBrainOne {
log.Error("the job(%s) version is too old", task.JobName, ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "the job's version is too old and can not be restarted"
break
}

count, err := models.GetCloudbrainCountByUserID(ctx.User.ID)
if err != nil {
log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "system error"
break
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "the user already has running or waiting task"
break
}
}

err = cloudbrain.RestartTask(ctx, task)
if err != nil {
log.Error("RestartTask failed:%v", err.Error(), ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "system error"
break
}

status = task.Status
jobID = task.JobID

break
}

ctx.JSON(200, map[string]string{
"result_code": resultCode,
"error_msg": errorMsg,
"status": status,
"job_id": jobID,
})
}

func CloudBrainShow(ctx *context.Context) { func CloudBrainShow(ctx *context.Context) {
ctx.Data["PageIsCloudBrain"] = true ctx.Data["PageIsCloudBrain"] = true


@@ -351,32 +418,53 @@ func CloudBrainCommitImage(ctx *context.Context, form auth.CommitImageCloudBrain


func CloudBrainStop(ctx *context.Context) { func CloudBrainStop(ctx *context.Context) {
var jobID = ctx.Params(":jobid") var jobID = ctx.Params(":jobid")
task, err := models.GetCloudbrainByJobID(jobID)
if err != nil {
ctx.ServerError("GetCloudbrainByJobID failed", err)
return
}
var resultCode = "0"
var errorMsg = ""
var status = ""


if task.Status == string(models.JobStopped) || task.Status == string(models.JobFailed) {
log.Error("the job(%s) has been stopped", task.JobName, ctx.Data["msgID"])
ctx.ServerError("the job has been stopped", errors.New("the job has been stopped"))
return
}
for {
task, err := models.GetCloudbrainByJobID(jobID)
if err != nil {
log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err, ctx.Data["msgID"])
resultCode = "-1"
errorMsg = "system error"
break
}


err = cloudbrain.StopJob(jobID)
if err != nil {
log.Error("StopJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["msgID"])
ctx.ServerError("StopJob failed", err)
return
}
if task.Status == string(models.JobStopped) || task.Status == string(models.JobFailed) {
log.Error("the job(%s) has been stopped", task.JobName, ctx.Data["msgID"])
resultCode = "-1"
errorMsg = "system error"
break
}


task.Status = string(models.JobStopped)
err = models.UpdateJob(task)
if err != nil {
ctx.ServerError("UpdateJob failed", err)
return
err = cloudbrain.StopJob(jobID)
if err != nil {
log.Error("StopJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"])
resultCode = "-1"
errorMsg = "system error"
break
}

task.Status = string(models.JobStopped)
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"])
resultCode = "-1"
errorMsg = "system error"
break
}

status = task.Status
break
} }
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")

ctx.JSON(200, map[string]string{
"result_code": resultCode,
"error_msg": errorMsg,
"status": status,
"job_id": jobID,
})
} }


func StopJobsByUserID(userID int64) { func StopJobsByUserID(userID int64) {
@@ -423,7 +511,7 @@ func StopJobs(cloudBrains []*models.Cloudbrain) {
Action: models.ActionStop, Action: models.ActionStop,
} }
err := retry(3, time.Second*30, func() error { err := retry(3, time.Second*30, func() error {
_, err := modelarts.StopJob(taskInfo.JobID, param)
_, err := modelarts.ManageNotebook(taskInfo.JobID, param)
return err return err
}) })
logErrorAndUpdateJobStatus(err, taskInfo) logErrorAndUpdateJobStatus(err, taskInfo)
@@ -560,7 +648,7 @@ func getImages(ctx *context.Context, imageType string) {


func GetModelDirs(jobName string, parentDir string) (string, error) { func GetModelDirs(jobName string, parentDir string) (string, error) {
var req string var req string
modelActualPath := getMinioPath(jobName, cloudbrain.ModelMountPath+"/")
modelActualPath := storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/")
if parentDir == "" { if parentDir == "" {
req = "baseDir=" + modelActualPath req = "baseDir=" + modelActualPath
} else { } else {
@@ -570,10 +658,6 @@ func GetModelDirs(jobName string, parentDir string) (string, error) {
return getDirs(req) return getDirs(req)
} }


func getMinioPath(jobName, suffixPath string) string {
return setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix + jobName + suffixPath
}

func CloudBrainDownloadModel(ctx *context.Context) { func CloudBrainDownloadModel(ctx *context.Context) {
parentDir := ctx.Query("parentDir") parentDir := ctx.Query("parentDir")
fileName := ctx.Query("fileName") fileName := ctx.Query("fileName")


+ 1
- 0
routers/repo/milestone.go View File

@@ -268,6 +268,7 @@ func MilestoneIssuesAndPulls(ctx *context.Context) {


ctx.Data["CanWriteIssues"] = ctx.Repo.CanWriteIssuesOrPulls(false) ctx.Data["CanWriteIssues"] = ctx.Repo.CanWriteIssuesOrPulls(false)
ctx.Data["CanWritePulls"] = ctx.Repo.CanWriteIssuesOrPulls(true) ctx.Data["CanWritePulls"] = ctx.Repo.CanWriteIssuesOrPulls(true)
ctx.Data["PageIsIssueList"] = true


ctx.HTML(200, tplMilestoneIssues) ctx.HTML(200, tplMilestoneIssues)
} }

+ 89
- 36
routers/repo/modelarts.go View File

@@ -47,6 +47,7 @@ const (


func DebugJobIndex(ctx *context.Context) { func DebugJobIndex(ctx *context.Context) {
debugListType := ctx.Query("debugListType") debugListType := ctx.Query("debugListType")
ctx.Data["ListType"] = debugListType
MustEnableCloudbrain(ctx) MustEnableCloudbrain(ctx)
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
page := ctx.QueryInt("page") page := ctx.QueryInt("page")
@@ -78,21 +79,19 @@ func DebugJobIndex(ctx *context.Context) {
} }


for i, task := range ciTasks { for i, task := range ciTasks {
ciTasks[i].CanDebug = cloudbrain.CanCreateOrDebugJob(ctx)
ciTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)

if task.Cloudbrain.Type == models.TypeCloudBrainOne { if task.Cloudbrain.Type == models.TypeCloudBrainOne {
ciTasks[i].CanDebug = cloudbrain.CanCreateOrDebugJob(ctx)
ciTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)
ciTasks[i].Cloudbrain.ComputeResource = modelarts.GPUResource ciTasks[i].Cloudbrain.ComputeResource = modelarts.GPUResource
}
if task.Cloudbrain.Type == models.TypeCloudBrainTwo {
ciTasks[i].CanDebug = cloudbrain.CanCreateOrDebugJob(ctx)
ciTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)
} else if task.Cloudbrain.Type == models.TypeCloudBrainTwo {
ciTasks[i].Cloudbrain.ComputeResource = modelarts.NPUResource ciTasks[i].Cloudbrain.ComputeResource = modelarts.NPUResource
} }

} }


pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5) pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)
pager.SetDefaultParams(ctx)
//pager.SetDefaultParams(ctx)
pager.AddParam(ctx, "debugListType", "ListType")
ctx.Data["Page"] = pager ctx.Data["Page"] = pager
ctx.Data["PageIsCloudBrain"] = true ctx.Data["PageIsCloudBrain"] = true
ctx.Data["Tasks"] = ciTasks ctx.Data["Tasks"] = ciTasks
@@ -237,38 +236,91 @@ func NotebookDebug(ctx *context.Context) {
ctx.Redirect(debugUrl) ctx.Redirect(debugUrl)
} }


func NotebookStop(ctx *context.Context) {
func NotebookManage(ctx *context.Context) {
var jobID = ctx.Params(":jobid") var jobID = ctx.Params(":jobid")
log.Info(jobID)
task, err := models.GetCloudbrainByJobID(jobID)
if err != nil {
ctx.ServerError("GetCloudbrainByJobID failed", err)
return
}
var action = ctx.Params(":action")
var resultCode = "0"
var errorMsg = ""
var status = ""


if task.Status != string(models.JobRunning) {
log.Error("the job(%s) is not running", task.JobName)
ctx.ServerError("the job is not running", errors.New("the job is not running"))
return
}
for {
task, err := models.GetCloudbrainByJobID(jobID)
if err != nil {
log.Error("GetCloudbrainByJobID failed:%v", err, ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "system error"
break
}


param := models.NotebookAction{
Action: models.ActionStop,
}
res, err := modelarts.StopJob(jobID, param)
if err != nil {
log.Error("StopJob(%s) failed:%v", task.JobName, err.Error())
ctx.ServerError("StopJob failed", err)
return
}
if action == models.ActionStop {
if task.Status != string(models.ModelArtsRunning) {
log.Error("the job(%s) is not running", task.JobName, ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "the job is not running"
break
}
} else if action == models.ActionRestart {
if task.Status != string(models.ModelArtsStopped) && task.Status != string(models.ModelArtsStartFailed) && task.Status != string(models.ModelArtsCreateFailed) {
log.Error("the job(%s) is not stopped", task.JobName, ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "the job is not stopped"
break
}


task.Status = res.CurrentStatus
err = models.UpdateJob(task)
if err != nil {
ctx.ServerError("UpdateJob failed", err)
return
count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID)
if err != nil {
log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "system error"
break
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "you have already a running or waiting task, can not create more"
break
}
}

action = models.ActionStart
} else {
log.Error("the action(%s) is illegal", action, ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "非法操作"
break
}

param := models.NotebookAction{
Action: action,
}
res, err := modelarts.ManageNotebook(jobID, param)
if err != nil {
log.Error("ManageNotebook(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "启动失败"
break
}

task.Status = res.CurrentStatus
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"])
resultCode = "-1"
errorMsg = "system error"
break
}

status = task.Status

break
} }
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")

ctx.JSON(200, map[string]string{
"result_code": resultCode,
"error_msg": errorMsg,
"status": status,
"job_id": jobID,
})
} }


func NotebookDel(ctx *context.Context) { func NotebookDel(ctx *context.Context) {
@@ -279,7 +331,7 @@ func NotebookDel(ctx *context.Context) {
return return
} }


if task.Status != string(models.JobStopped) {
if task.Status != string(models.ModelArtsCreateFailed) && task.Status != string(models.ModelArtsStartFailed) && task.Status != string(models.ModelArtsStopped){
log.Error("the job(%s) has not been stopped", task.JobName) log.Error("the job(%s) has not been stopped", task.JobName)
ctx.ServerError("the job has not been stopped", errors.New("the job has not been stopped")) ctx.ServerError("the job has not been stopped", errors.New("the job has not been stopped"))
return return
@@ -328,6 +380,7 @@ func TrainJobIndex(ctx *context.Context) {
for i, task := range tasks { for i, task := range tasks {
tasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) tasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)
tasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain) tasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain)
tasks[i].ComputeResource = modelarts.NPUResource
} }


pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5) pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)


+ 2
- 1
routers/routes/routes.go View File

@@ -968,6 +968,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/commit_image", cloudbrain.AdminOrOwnerOrJobCreaterRight, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) m.Post("/commit_image", cloudbrain.AdminOrOwnerOrJobCreaterRight, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage)
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainDel) m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainDel)
m.Post("/restart", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainRestart)
m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate) m.Get("/rate", reqRepoCloudBrainReader, repo.GetRate)
m.Get("/models", reqRepoCloudBrainReader, repo.CloudBrainShowModels) m.Get("/models", reqRepoCloudBrainReader, repo.CloudBrainShowModels)
m.Get("/download_model", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainDownloadModel) m.Get("/download_model", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainDownloadModel)
@@ -1003,7 +1004,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/:jobid", func() { m.Group("/:jobid", func() {
m.Get("", reqRepoCloudBrainReader, repo.NotebookShow) m.Get("", reqRepoCloudBrainReader, repo.NotebookShow)
m.Get("/debug", reqRepoCloudBrainWriter, repo.NotebookDebug) m.Get("/debug", reqRepoCloudBrainWriter, repo.NotebookDebug)
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.NotebookStop)
m.Post("/:action", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.NotebookManage)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.NotebookDel) m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.NotebookDel)
}) })
m.Get("/create", reqRepoCloudBrainWriter, repo.NotebookNew) m.Get("/create", reqRepoCloudBrainWriter, repo.NotebookNew)


+ 135
- 42
templates/repo/debugjob/index.tmpl View File

@@ -202,14 +202,20 @@
<div class="rect5"></div> <div class="rect5"></div>
</div> </div>
</div> </div>
<!-- 提示框 -->
<div class="alert"></div>



<div class="repository release dataset-list view"> <div class="repository release dataset-list view">
{{template "repo/header" .}} {{template "repo/header" .}}
<!-- {{template "base/alert" .}} -->
<!-- 提示框 -->
<!-- 列表容器 --> <!-- 列表容器 -->
<div class="ui container"> <div class="ui container">
<div class="ui two column stackable grid ">
<div class="ui negative message" style="display: none;">
<i class="close icon"></i>
<p></p>
</div>
<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">
<a class="active item" href="{{.RepoLink}}/debugjob?debugListType=all">{{$.i18n.Tr "repo.modelarts.notebook"}}</a> <a class="active item" href="{{.RepoLink}}/debugjob?debugListType=all">{{$.i18n.Tr "repo.modelarts.notebook"}}</a>
@@ -282,7 +288,7 @@
<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{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}' title="{{.JobName}}" style="font-size: 14px;">
<a class="title" href='{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}' title="{{.JobName}}" style="font-size: 14px;">
<span class="fitted text_over" style="width: 90%;vertical-align: middle;">{{.JobName}}</span> <span class="fitted text_over" style="width: 90%;vertical-align: middle;">{{.JobName}}</span>
</a> </a>
</div> </div>
@@ -315,34 +321,44 @@
</a> </a>
{{end}} --> {{end}} -->
<!-- 调试 --> <!-- 调试 -->
{{if .CanDebug}}
{{if eq .ComputeResource "CPU/GPU"}}
<a id="model-debug-{{.JobID}}" class='ui basic {{if ne .Status "RUNNING"}} disabled {{else}}blue {{end}}button' href="{{$.RepoLink}}/cloudbrain/{{.JobID}}/debug" target="_blank">
{{$.i18n.Tr "repo.debug"}}
</a>
<form id="debugAgainForm-{{.JobID}}">
{{$.CsrfTokenHtml}}
{{if .CanDebug}}
{{if eq .Status "RUNNING"}}
<a style="margin: 0 1rem;" id="model-debug-{{.JobID}}" class='ui basic blue 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}}/")'>
{{$.i18n.Tr "repo.debug_again"}}
</a>
{{end}}
{{else}} {{else}}
<a id="model-debug-{{.JobID}}" class='ui basic {{if ne .Status "RUNNING"}} disabled {{else}}blue {{end}}button' href="{{$.RepoLink}}/modelarts/notebook/{{.JobID}}/debug" target="_blank">
{{$.i18n.Tr "repo.debug"}}
<a class="ui basic disabled button">
{{$.i18n.Tr "repo.debug_again"}}
</a> </a>
{{end}} {{end}}
{{else}}
<a class="ui basic disabled button">
{{$.i18n.Tr "repo.debug"}}
</a>
{{end}}
</form>
<!-- 停止 --> <!-- 停止 -->
<form id="stopForm-{{.JobID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}/stop" method="post" style="margin-left:-1px;">
<form id="stopForm-{{.JobID}}" style="margin-left:-1px;">
{{$.CsrfTokenHtml}} {{$.CsrfTokenHtml}}
{{if .CanDel}} {{if .CanDel}}
<a id="stop-model-debug-{{.JobID}}" class='ui basic {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING"}}disabled {{else}}blue {{end}}button' onclick="document.getElementById('stopForm-{{.JobID}}').submit();">
{{$.i18n.Tr "repo.stop"}}
</a>
{{if eq .ComputeResource "CPU/GPU" }}
<a id="stop-model-debug-{{.JobID}}" class='ui basic {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING"}}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"}}disabled {{else}}blue {{end}}button' onclick='stopDebug("{{.JobID}}","{{$.RepoLink}}/modelarts/notebook/{{.JobID}}/stop")'>
{{$.i18n.Tr "repo.stop"}}
</a>
{{end}}
{{else}} {{else}}
<a class="ui basic disabled button" onclick="document.getElementById('stopForm-{{.JobID}}').submit();">
<a class="ui basic disabled button">
{{$.i18n.Tr "repo.stop"}} {{$.i18n.Tr "repo.stop"}}
</a> </a>
{{end}} {{end}}
<input type="hidden" name="debugListType" value="all">
</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-{{.JobID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.JobID}}/del" method="post">
@@ -463,10 +479,21 @@


<script> <script>
// 调试和评分新开窗口 // 调试和评分新开窗口
const {AppSubUrl, StaticUrlPrefix, csrf} = window.config;
let url={{.RepoLink}} let url={{.RepoLink}}
let getParam=location.search.split('?debugListType=').pop()
let getParam=getQueryVariable('debugListType')
let dropdownValue = getParam==='all'||getParam==='' ? '全部' : getParam let dropdownValue = getParam==='all'||getParam==='' ? '全部' : getParam
localStorage.setItem('all',location.href) localStorage.setItem('all',location.href)
function getQueryVariable(variable)
{
let query = window.location.search.substring(1);
let vars = query.split("&");
for (let i=0;i<vars.length;i++) {
let pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
function stop(obj) { function stop(obj) {
if (obj.style.color != "rgb(204, 204, 204)") { if (obj.style.color != "rgb(204, 204, 204)") {
obj.target = '_blank' obj.target = '_blank'
@@ -499,7 +526,68 @@
.modal('show') .modal('show')
} }
} }
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)
$('#model-debug-'+JobID).removeClass('blue').addClass('disabled')
$('#model-delete-'+JobID).removeClass('blue').addClass('disabled')
}
}else{
$(".ui.negative.message").css("display","block")
$(".ui.negative.message p").text(res.error_msg)
setTimeout("$('.message .close').click()",3000)
}
},
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"){
$('#model-debug-'+JobID).removeClass('blue').addClass('disabled').text("再次调试").css("margin","0")
$('#model-image-'+JobID).removeClass('blue').addClass('disabled')
$('#stop-model-debug-'+JobID).removeClass('blue').addClass('disabled')
}
else{
$('#model-debug-'+JobID).removeClass('blue').addClass('disabled')
$('#stop-model-debug-'+JobID).removeClass('blue').addClass('disabled')
}
}else{
$("ui.negative.message").text(res.error_msg)
}
},
error :function(res){
console.log(res)

}
})

}
// 加载任务状态 // 加载任务状态
var timeid = window.setInterval(loadJobStatus, 15000); var timeid = window.setInterval(loadJobStatus, 15000);
$(document).ready(loadJobStatus); $(document).ready(loadJobStatus);
@@ -508,8 +596,9 @@
const jobID = job.dataset.jobid; const jobID = job.dataset.jobid;
const repoPath = job.dataset.repopath; const repoPath = job.dataset.repopath;
const computeResource = job.dataset.resource const computeResource = job.dataset.resource
const initArray = ['STOPPED','FAILED','START_FAILED','CREATE_FAILED']
const initArray = ['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED']
if (initArray.includes(job.textContent.trim())) { if (initArray.includes(job.textContent.trim())) {
return return
} }
const diffResource = computeResource == "NPU" ? 'modelarts/notebook' : 'cloudbrain' const diffResource = computeResource == "NPU" ? 'modelarts/notebook' : 'cloudbrain'
@@ -521,32 +610,30 @@
$('#' + jobID+ '-text').text(status) $('#' + jobID+ '-text').text(status)
} }
if(status==="RUNNING"){ if(status==="RUNNING"){
$('#model-debug-'+jobID).removeClass('disabled')
$('#model-debug-'+jobID).addClass('blue')
$('#model-image-'+jobID).removeClass('disabled')
$('#model-image-'+jobID).addClass('blue')
$('#model-debug-'+jobID).removeClass('disabled').addClass('blue').text('调试').css("margin","0 1rem")
$('#model-image-'+jobID).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')
$('#model-image-'+jobID).addClass('disabled')

// $('#model-debug-'+jobID).removeClass('blue')
// $('#model-debug-'+jobID).addClass('disabled')
$('#model-image-'+jobID).removeClass('blue').addClass('disabled')
}
if(["CREATING","STOPPING","WAITING","STARTING"].includes(status)){
$('#model-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")
} }
if(["RUNNING","WAITING"].includes(status)){ if(["RUNNING","WAITING"].includes(status)){
$('#stop-model-debug-'+jobID).removeClass('disabled')
$('#stop-model-debug-'+jobID).addClass('blue')
$('#stop-model-debug-'+jobID).removeClass('disabled').addClass('blue')
} }
if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED"].includes(status)){ if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED"].includes(status)){
$('#stop-model-debug-'+jobID).removeClass('blue')
$('#stop-model-debug-'+jobID).addClass('disabled')
$('#stop-model-debug-'+jobID).removeClass('blue').addClass('disabled')
} }
if(status==="STOPPED" || status==="FAILED"|| status==="START_FAILED"){ if(status==="STOPPED" || status==="FAILED"|| status==="START_FAILED"){
$('#model-delete-'+jobID).removeClass('disabled')
$('#model-delete-'+jobID).addClass('blue')
$('#model-delete-'+jobID).removeClass('disabled').addClass('blue')
}else{ }else{
$('#model-delete-'+jobID).removeClass('blue')
$('#model-delete-'+jobID).addClass('disabled')
$('#model-delete-'+jobID).removeClass('blue').addClass('disabled')
} }
}).fail(function(err) { }).fail(function(err) {
console.log(err); console.log(err);
@@ -554,6 +641,7 @@
}); });
}; };
$(document).ready(function(){ $(document).ready(function(){
dropdownValue = dropdownValue==="CPU%2FGPU"? 'CPU/GPU' : dropdownValue
$('.default.text').text(dropdownValue) $('.default.text').text(dropdownValue)
$('.ui.dropdown') $('.ui.dropdown')
.dropdown({ .dropdown({
@@ -564,6 +652,12 @@
location.href = `${url}/debugjob?debugListType=${value}` location.href = `${url}/debugjob?debugListType=${value}`
} }
}) })
$('.message .close')
.on('click', function() {
$(this)
.closest('.message')
.transition('fade')
})
}) })
@@ -601,7 +695,6 @@
// 显示弹窗,弹出相应的信息 // 显示弹窗,弹出相应的信息
function showmask() { function showmask() {
var image_tag = !$('#image_tag').val() var image_tag = !$('#image_tag').val()
console.log("image_tag",image_tag)
if(image_tag){ if(image_tag){
return return
} }


+ 6
- 0
templates/repo/header.tmpl View File

@@ -149,6 +149,12 @@
{{.i18n.Tr "repo.model_manager"}} {{.i18n.Tr "repo.model_manager"}}
</a> </a>
{{end}} {{end}}
{{if .Permission.CanRead $.UnitTypeModelManage}}
<a class="{{if .isModelManage}}active{{end}} item" href="{{.RepoLink}}/modelmanage/show_model">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"/><path d="M3.741 1.408l18.462 10.154a.5.5 0 0 1 0 .876L3.741 22.592A.5.5 0 0 1 3 22.154V1.846a.5.5 0 0 1 .741-.438zM5 13v6.617L18.85 12 5 4.383V11h5v2H5z"/></svg>
{{.i18n.Tr "repo.model_manager"}}
</a>
{{end}}
{{if .Permission.CanRead $.UnitTypeCloudBrain}} {{if .Permission.CanRead $.UnitTypeCloudBrain}}
<a class="{{if .PageIsCloudBrain}}active{{end}} item" href="{{.RepoLink}}/debugjob?debugListType=all"> <a class="{{if .PageIsCloudBrain}}active{{end}} item" href="{{.RepoLink}}/debugjob?debugListType=all">
<span> <span>


+ 2
- 1
templates/repo/home.tmpl View File

@@ -337,7 +337,8 @@
{{end}} {{end}}
<div class="ui right"> <div class="ui right">
<a class="membersmore text grey" href="{{.RepoLink}}/contributors">全部 {{svg "octicon-chevron-right" 16}}</a>
<!-- <a class="membersmore text grey" href="{{.RepoLink}}/contributors">全部 {{svg "octicon-chevron-right" 16}}</a> -->
<a class="membersmore text grey" href="{{.RepoLink}}/contributors?type={{if .IsViewBranch}}branch{{else}}tag{{end}}&name={{.BranchName}}">全部 {{svg "octicon-chevron-right" 16}}</a>
</div> </div>
</h4> </h4>
<div class="ui members" id="contributorInfo"> <div class="ui members" id="contributorInfo">


+ 7
- 1
web_src/js/components/Contributors.vue View File

@@ -45,6 +45,8 @@ export default {
data() { data() {
return { return {
url:'', url:'',
url_infor:'',
href_:'',
contributors_list:[], contributors_list:[],
contributors_list_page:[], contributors_list_page:[],
currentPage:1, currentPage:1,
@@ -56,7 +58,7 @@ export default {
methods: { methods: {


getContributorsList(){ getContributorsList(){
this.$axios.get(this.url+'/list').then((res)=>{
this.$axios.get(this.url+'/list?'+this.url_infor).then((res)=>{
this.contributors_list = res.data.contributor_info this.contributors_list = res.data.contributor_info
this.totalNum = this.contributors_list.length this.totalNum = this.contributors_list.length
this.contributors_list_page = this.contributors_list.slice(0,this.pageSize) this.contributors_list_page = this.contributors_list.slice(0,this.pageSize)
@@ -78,6 +80,10 @@ created(){
this.url = url; this.url = url;
let strIndex = this.url.indexOf("contributors") let strIndex = this.url.indexOf("contributors")
this.url_code = this.url.substr(0,strIndex) this.url_code = this.url.substr(0,strIndex)
this.href_ = window.location.href;
let index = this.href_.indexOf("?")
this.url_infor = this.href_.substring(index+1,this.href_.length)
this.getContributorsList() this.getContributorsList()
}, },


Loading…
Cancel
Save