Browse Source

Merge remote-tracking branch 'origin/V20220926' into zouap

pull/2977/head
zouap 2 years ago
parent
commit
9f86b3bc3c
37 changed files with 536 additions and 236 deletions
  1. +7
    -16
      models/action.go
  2. +41
    -28
      models/cloudbrain.go
  3. +7
    -3
      models/cloudbrain_spec.go
  4. +9
    -0
      models/repo_watch.go
  5. +23
    -4
      models/reward_operate_record.go
  6. +64
    -5
      models/task_config.go
  7. +1
    -1
      models/wechat_bind.go
  8. +1
    -0
      modules/auth/modelarts.go
  9. +37
    -1
      modules/grampus/grampus.go
  10. +8
    -31
      modules/notification/action/action.go
  11. +7
    -2
      options/locale/locale_en-US.ini
  12. +7
    -2
      options/locale/locale_zh-CN.ini
  13. +13
    -2
      public/home/home.js
  14. +1
    -1
      routers/repo/cloudbrain.go
  15. +16
    -15
      routers/repo/grampus.go
  16. +2
    -2
      routers/repo/modelarts.go
  17. +2
    -2
      routers/reward/point/point.go
  18. +2
    -2
      routers/task/config.go
  19. +15
    -3
      services/reward/cloudbrain_deduct.go
  20. +22
    -24
      services/reward/operator.go
  21. +14
    -12
      services/socketwrap/clientManager.go
  22. +46
    -12
      services/task/task.go
  23. +1
    -1
      templates/repo/cloudbrain/trainjob/new.tmpl
  24. +0
    -2
      templates/repo/datasets/index.tmpl
  25. +1
    -1
      templates/repo/grampus/trainjob/gpu/new.tmpl
  26. +1
    -1
      templates/repo/grampus/trainjob/npu/new.tmpl
  27. +2
    -2
      templates/repo/modelarts/trainjob/new.tmpl
  28. +2
    -2
      templates/repo/modelarts/trainjob/show.tmpl
  29. +6
    -2
      templates/repo/modelarts/trainjob/version_new.tmpl
  30. +14
    -14
      templates/reward/point/rule.tmpl
  31. +4
    -0
      templates/user/dashboard/feeds.tmpl
  32. +80
    -10
      web_src/js/features/cloudbrainShow.js
  33. +22
    -3
      web_src/js/standalone/cloudbrainNew.js
  34. +2
    -2
      web_src/vuepages/const/index.js
  35. +4
    -0
      web_src/vuepages/langs/config/en-US.js
  36. +4
    -0
      web_src/vuepages/langs/config/zh-CN.js
  37. +48
    -28
      web_src/vuepages/pages/reward/point/utils.js

+ 7
- 16
models/action.go View File

@@ -61,13 +61,10 @@ const (
ActionCreateGrampusNPUTrainTask //32
ActionCreateGrampusGPUTrainTask //33
ActionBindWechat //34
ActionCreateCloudbrainTask //35
ActionDatasetRecommended //36
ActionCreateImage //37
ActionImageRecommend //38
ActionChangeUserAvatar //39
ActionPushCommits //40
ActionForkRepo //41
ActionDatasetRecommended //35
ActionCreateImage //36
ActionImageRecommend //37
ActionChangeUserAvatar //38

)

@@ -95,6 +92,7 @@ type Action struct {

type ActionShow struct {
OpType ActionType
TaskType TaskType
RepoLink string
ShortRepoFullDisplayName string
Content string
@@ -241,7 +239,8 @@ func (a *Action) GetRepoLink() string {

func (a *Action) ToShow() *ActionShow {
actionShow := &ActionShow{}
actionShow.OpType = GetTaskOptType(*a)
actionShow.OpType = a.OpType
actionShow.TaskType = GetTaskTypeFromAction(a.OpType)
actionShow.Content = a.Content
actionShow.RefName = a.RefName

@@ -272,14 +271,6 @@ func (a *Action) ToShow() *ActionShow {
return actionShow
}

func GetTaskOptType(action Action) ActionType {
//Convert all types of cloudbrain tasks action into ActionCreateCloudbrainTask
if action.IsCloudbrainAction() {
return ActionCreateCloudbrainTask
}
return action.OpType
}

// GetRepositoryFromMatch returns a *Repository from a username and repo strings
func GetRepositoryFromMatch(ownerName string, repoName string) (*Repository, error) {
var err error


+ 41
- 28
models/cloudbrain.go View File

@@ -203,16 +203,17 @@ type Cloudbrain struct {
}

type CloudbrainShow struct {
ID int64
JobID string
RepoFullName string
Type int
JobType string
DisplayJobName string
Duration string
ResourceSpec *Specification
ComputeResource string
AiCenter string
ID int64
JobID string
RepoFullName string
Type int
JobType string
DisplayJobName string
Duration string
ResourceSpec *Specification
ComputeResource string
AiCenter string
WorkServerNumber int
}

type CloudbrainShow4Action struct {
@@ -225,15 +226,20 @@ type CloudbrainShow4Action struct {
}

func (task *Cloudbrain) ToShow() *CloudbrainShow {
n := 1
if task.WorkServerNumber > 1 {
n = task.WorkServerNumber
}
c := &CloudbrainShow{
ID: task.ID,
JobID: task.JobID,
JobType: task.JobType,
Type: task.Type,
DisplayJobName: task.DisplayJobName,
Duration: task.TrainJobDuration,
ResourceSpec: task.Spec,
ComputeResource: task.ComputeResource,
ID: task.ID,
JobID: task.JobID,
JobType: task.JobType,
Type: task.Type,
DisplayJobName: task.DisplayJobName,
Duration: task.TrainJobDuration,
ResourceSpec: task.Spec,
ComputeResource: task.ComputeResource,
WorkServerNumber: n,
}
if task.Repo != nil {
c.RepoFullName = task.Repo.FullName()
@@ -657,8 +663,6 @@ type FlavorInfo struct {
UnitPrice int64 `json:"unitPrice"`
}



type SpecialPools struct {
Pools []*SpecialPool `json:"pools"`
}
@@ -1476,14 +1480,23 @@ type GrampusStopJobResponse struct {
}

type GrampusTasks struct {
Command string `json:"command"`
Name string `json:"name"`
ImageId string `json:"imageId"`
ResourceSpecId string `json:"resourceSpecId"`
ImageUrl string `json:"imageUrl"`
CenterID []string `json:"centerID"`
CenterName []string `json:"centerName"`
ReplicaNum int `json:"replicaNum"`
Command string `json:"command"`
Name string `json:"name"`
ImageId string `json:"imageId"`
ResourceSpecId string `json:"resourceSpecId"`
ImageUrl string `json:"imageUrl"`
CenterID []string `json:"centerID"`
CenterName []string `json:"centerName"`
ReplicaNum int `json:"replicaNum"`
Datasets []GrampusDataset `json:"datasets"`
Models []GrampusDataset `json:"models"`
}

type GrampusDataset struct {
Name string `json:"name"`
Bucket string `json:"bucket"`
EndPoint string `json:"endPoint"`
ObjectKey string `json:"objectKey"`
}

type CreateGrampusJobRequest struct {


+ 7
- 3
models/cloudbrain_spec.go View File

@@ -123,10 +123,14 @@ func GetResourceSpecMapByCloudbrainIDs(ids []int64) (map[int64]*Specification, e
return r, nil
}

func GetCloudbrainTaskUnitPrice(cloudbrainId int64) (int, error) {
s, err := GetCloudbrainSpecByID(cloudbrainId)
func GetCloudbrainTaskUnitPrice(task Cloudbrain) (int, error) {
s, err := GetCloudbrainSpecByID(task.ID)
if err != nil {
return 0, err
}
return s.UnitPrice, nil
var n = 1
if task.WorkServerNumber > 1 {
n = task.WorkServerNumber
}
return s.UnitPrice * n, nil
}

+ 9
- 0
models/repo_watch.go View File

@@ -183,6 +183,7 @@ func notifyWatchers(e Engine, actions ...*Action) error {
var permCode []bool
var permIssue []bool
var permPR []bool
var permDataset []bool

for _, act := range actions {
repoChanged := repo == nil || repo.ID != act.RepoID
@@ -234,12 +235,14 @@ func notifyWatchers(e Engine, actions ...*Action) error {
permCode = make([]bool, len(watchers))
permIssue = make([]bool, len(watchers))
permPR = make([]bool, len(watchers))
permDataset = make([]bool, len(watchers))
for i, watcher := range watchers {
user, err := getUserByID(e, watcher.UserID)
if err != nil {
permCode[i] = false
permIssue[i] = false
permPR[i] = false
permDataset[i] = false
continue
}
perm, err := getUserRepoPermission(e, repo, user)
@@ -247,11 +250,13 @@ func notifyWatchers(e Engine, actions ...*Action) error {
permCode[i] = false
permIssue[i] = false
permPR[i] = false
permDataset[i] = false
continue
}
permCode[i] = perm.CanRead(UnitTypeCode)
permIssue[i] = perm.CanRead(UnitTypeIssues)
permPR[i] = perm.CanRead(UnitTypePullRequests)
permDataset[i] = perm.CanRead(UnitTypeDatasets)
}
}

@@ -276,6 +281,10 @@ func notifyWatchers(e Engine, actions ...*Action) error {
if !permPR[i] {
continue
}
case ActionDatasetRecommended:
if !permDataset[i] {
continue
}
}

if _, err = e.InsertOne(act); err != nil {


+ 23
- 4
models/reward_operate_record.go View File

@@ -1,8 +1,8 @@
package models

import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"fmt"
"strconv"
"strings"
"xorm.io/builder"
@@ -355,7 +355,7 @@ type RewardRecordListOpts struct {
OperateType RewardOperateType
RewardType RewardType
SourceType string
ActionType int
TaskType string
SerialNo string
OrderBy RewardOperateOrderBy
IsAdmin bool
@@ -381,8 +381,8 @@ func (opts *RewardRecordListOpts) toCond() builder.Cond {
if opts.SourceType != "" {
cond = cond.And(builder.Eq{"reward_operate_record.source_type": opts.SourceType})
}
if opts.ActionType > 0 {
cond = cond.And(builder.Eq{"reward_operate_record.source_template_id": fmt.Sprint(opts.ActionType)})
if opts.TaskType != "" {
cond = cond.And(builder.Eq{"reward_operate_record.source_template_id": opts.TaskType})
}
if opts.SerialNo != "" {
cond = cond.And(builder.Like{"reward_operate_record.serial_no", opts.SerialNo})
@@ -457,3 +457,22 @@ func GetAdminRewardRecordShowList(opts *RewardRecordListOpts) (RewardRecordShowL
RewardRecordShowList(r).loadAttribute(true)
return r, count, nil
}

func IsWechatOpenIdRewarded(wechatOpenId string) bool {
actions := make([]Action, 0)
err := x.Where(" op_type = ? and content = ?", ActionBindWechat, wechatOpenId).Find(&actions)

if err != nil {
log.Error("IsWechatOpenIdRewarded find actions err.%v", err)
return true
}
if len(actions) == 0 {
return false
}
actionIds := make([]int64, len(actions))
for i, v := range actions {
actionIds[i] = v.ID
}
n, _ := x.Where(builder.Eq{"source_type": SourceTypeAccomplishTask}.And(builder.In("source_id", actionIds))).Count(&RewardOperateRecord{})
return n > 0
}

+ 64
- 5
models/task_config.go View File

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

import (
"code.gitea.io/gitea/modules/timeutil"
"fmt"
"xorm.io/builder"
)

@@ -11,6 +10,66 @@ const (
PeriodDaily = "DAILY"
)

type TaskType string

const (
TaskCreatePublicRepo TaskType = "CreatePublicRepo"
TaskCreateIssue TaskType = "CreateIssue"
TaskCreatePullRequest TaskType = "CreatePullRequest"
TaskCommentIssue TaskType = "CommentIssue"
TaskUploadAttachment TaskType = "UploadAttachment"
TaskCreateNewModelTask TaskType = "CreateNewModelTask"
TaskBindWechat TaskType = "BindWechat"
TaskCreateCloudbrainTask TaskType = "CreateCloudbrainTask"
TaskDatasetRecommended TaskType = "DatasetRecommended"
TaskCreateImage TaskType = "CreateImage"
TaskImageRecommend TaskType = "ImageRecommend"
TaskChangeUserAvatar TaskType = "ChangeUserAvatar"
TaskPushCommits TaskType = "PushCommits"
)

func GetTaskTypeFromAction(a ActionType) TaskType {
switch a {
case ActionCreateDebugGPUTask,
ActionCreateDebugNPUTask,
ActionCreateTrainTask,
ActionCreateInferenceTask,
ActionCreateBenchMarkTask,
ActionCreateGPUTrainTask,
ActionCreateGrampusNPUTrainTask,
ActionCreateGrampusGPUTrainTask:
return TaskCreateCloudbrainTask
case ActionCreateRepo:
return TaskCreatePublicRepo
case ActionCreatePullRequest:
return TaskCreatePullRequest
case ActionCommentIssue:
return TaskCommentIssue
case ActionUploadAttachment:
return TaskUploadAttachment
case ActionCreateNewModelTask:
return TaskCreateNewModelTask
case ActionBindWechat:
return TaskBindWechat
case ActionDatasetRecommended:
return TaskDatasetRecommended
case ActionImageRecommend:
return TaskImageRecommend
case ActionCreateImage:
return TaskCreateImage
case ActionChangeUserAvatar:
return TaskChangeUserAvatar
case ActionCommitRepo,
ActionDeleteBranch,
ActionPushTag,
ActionDeleteTag:
return TaskPushCommits
case ActionCreateIssue:
return TaskCreateIssue
}
return ""
}

//PointTaskConfig Only add and delete are allowed, edit is not allowed
//so if you want to edit config for some task code,please delete first and add new one
type TaskConfig struct {
@@ -124,8 +183,8 @@ func GetTaskConfigList() ([]*TaskConfig, error) {

type GetTaskConfigOpts struct {
ListOptions
Status int //1 normal 2 deleted
ActionType int
Status int //1 normal 2 deleted
TaskType string
}

func GetTaskConfigPageWithDeleted(opt GetTaskConfigOpts) ([]*TaskAndLimiterConfig, int64, error) {
@@ -133,8 +192,8 @@ func GetTaskConfigPageWithDeleted(opt GetTaskConfigOpts) ([]*TaskAndLimiterConfi
opt.Page = 1
}
cond := builder.NewCond()
if opt.ActionType > 0 {
cond = cond.And(builder.Eq{"task_code": fmt.Sprint(opt.ActionType)})
if opt.TaskType != "" {
cond = cond.And(builder.Eq{"task_code": opt.TaskType})
}

var count int64


+ 1
- 1
models/wechat_bind.go View File

@@ -98,5 +98,5 @@ func UnbindWechatOpenId(userId int64, oldWechatOpenID string) error {
}

func CountWechatBindLog(wechatOpenId string, action WechatBindAction) (int64, error) {
return x.Where("wechat_open_id = ? and action = ?", action, wechatOpenId).Count(&WechatBindLog{})
return x.Where("wechat_open_id = ? and action = ?", wechatOpenId, action).Count(&WechatBindLog{})
}

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

@@ -33,6 +33,7 @@ type CreateModelArtsTrainJobForm struct {
DisplayJobName string `form:"display_job_name" binding:"Required"`
JobName string `form:"job_name" binding:"Required"`
Attachment string `form:"attachment" binding:"Required"`
DatasetName string `form:"dataset_name"`
BootFile string `form:"boot_file" binding:"Required"`
WorkServerNumber int `form:"work_server_number" binding:"Required"`
EngineID int `form:"engine_id" binding:"Required"`


+ 37
- 1
modules/grampus/grampus.go View File

@@ -75,12 +75,46 @@ type GenerateTrainJobReq struct {
Spec *models.Specification
}

func getEndPoint() string {
index := strings.Index(setting.Endpoint, "//")
endpoint := setting.Endpoint[index+2:]
return endpoint
}

func getDatasetGrampus(datasetInfos map[string]models.DatasetInfo) []models.GrampusDataset {
var datasetGrampus []models.GrampusDataset
endPoint := getEndPoint()
for _, datasetInfo := range datasetInfos {
datasetGrampus = append(datasetGrampus, models.GrampusDataset{
Name: datasetInfo.FullName,
Bucket: setting.Bucket,
EndPoint: endPoint,
ObjectKey: datasetInfo.DataLocalPath + datasetInfo.FullName,
})

}
return datasetGrampus
}

func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error) {
createTime := timeutil.TimeStampNow()

centerID, centerName := getCentersParamter(ctx, req)

log.Info("grampus Command:" + req.Command)
var datasetGrampus, modelGrampus []models.GrampusDataset
if ProcessorTypeNPU == req.ProcessType {
datasetGrampus = getDatasetGrampus(req.DatasetInfos)
if len(req.ModelName) != 0 {
modelGrampus = []models.GrampusDataset{
{
Name: req.ModelName,
Bucket: setting.Bucket,
EndPoint: getEndPoint(),
ObjectKey: req.PreTrainModelPath,
},
}
}
}

jobResult, err := createJob(models.CreateGrampusJobRequest{
Name: req.JobName,
@@ -94,6 +128,8 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error
CenterID: centerID,
CenterName: centerName,
ReplicaNum: 1,
Datasets: datasetGrampus,
Models: modelGrampus,
},
},
})


+ 8
- 31
modules/notification/action/action.go View File

@@ -363,22 +363,15 @@ func (t *actionNotifier) NotifyWechatBind(user *models.User, wechatOpenId string
func (t *actionNotifier) NotifyDatasetRecommend(optUser *models.User, dataset *models.Dataset, action string) {
switch action {
case "recommend":
users, err := models.GetAllDatasetContributorByDatasetId(dataset.ID)
if err != nil {
return
}
var actions = make([]*models.Action, 0)
for _, user := range users {
actions = append(actions, &models.Action{
OpType: models.ActionDatasetRecommended,
ActUserID: user.ID,
ActUser: user,
RepoID: dataset.RepoID,
Repo: dataset.Repo,
Content: fmt.Sprintf("%d|%s", dataset.ID, dataset.Title),
})
act := &models.Action{
OpType: models.ActionDatasetRecommended,
ActUserID: dataset.UserID,
RepoID: dataset.RepoID,
IsPrivate: false,
Content: fmt.Sprintf("%d|%s", dataset.ID, dataset.Title),
}
if err := models.NotifyWatchers(actions...); err != nil {

if err := models.NotifyWatchers(act); err != nil {
log.Error("notifyWatchers: %v", err)
}
}
@@ -428,19 +421,3 @@ func (t *actionNotifier) NotifyChangeUserAvatar(user *models.User, form auth.Ava
log.Error("notifyWatchers: %v", err)
}
}

func (t *actionNotifier) NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) {
act := &models.Action{
ActUserID: pusher.ID,
ActUser: pusher,
OpType: models.ActionPushCommits,
RepoID: repo.ID,
Repo: repo,
RefName: refName,
IsPrivate: repo.IsPrivate,
Content: fmt.Sprintf("%s|%s", oldCommitID, newCommitID),
}
if err := models.NotifyWatchers(act); err != nil {
log.Error("notifyWatchers: %v", err)
}
}

+ 7
- 2
options/locale/locale_en-US.ini View File

@@ -3083,6 +3083,11 @@ task_createmodel=`created new model <a href="%s/modelmanage/show_model_info?name
task_gputrainjob=`created CPU/GPU training task <a href="%s/cloudbrain/train-job/%s">%s</a>`
task_c2netnputrainjob=`created NPU training task <a href="%s/grampus/train-job/%s">%s</a>`
task_c2netgputrainjob=`created CPU/GPU training task <a href="%s/grampus/train-job/%s">%s</a>`
binded_wechat=binded WeChat
dataset_recommended=`created dataset <a href="%s/datasets">%s</a> was set as recommended dataset`
create_image=`committed image <span style="font-weight:bold;">%s</span>`
image_recommended=`committed image <span style="font-weight:bold;">%s</span> was set as recommended image`
update_user_avatar=updated avatar

[tool]
ago = %s ago
@@ -3202,7 +3207,7 @@ wrong_specification=You cannot use this specification, please choose another ite
resource_use=Resource Occupancy

job_name_rule = Please enter letters, numbers, _ and - up to 64 characters and cannot end with a dash (-).
train_dataset_path_rule = The dataset location is stored in the environment variable <strong style="color:#010101">data_url</strong>, and the output path is stored in the environment variable <strong style="color:#010101">train_url</strong>.
train_dataset_path_rule = The dataset location is stored in the environment variable <strong style="color:#010101">data_url</strong>, the pre-trained model is storaged in the environment <strong style="color:#010101">ckpt_url</strong>, and the output path is stored in the environment variable <strong style="color:#010101">train_url</strong>.
infer_dataset_path_rule = The dataset location is stored in the environment variable <strong style="color:#010101">data_url</strong>, and the output path is stored in the environment variable <strong style="color:#010101">result_url</strong>.
view_sample = View sample
inference_output_path_rule = The inference output path is stored in the environment variable result_url.
@@ -3239,7 +3244,7 @@ Stopped_success_update_status_fail=Succeed in stopping th job, but failed to upd
load_code_failed=Fail to load code, please check if the right branch is selected.

error.dataset_select = dataset select error:the count exceed the limit or has same name
new_train_gpu_tooltips = The code is storaged in <strong style="color:#010101">%s</strong>, the dataset is storaged in <strong style="color:#010101">%s</strong>, and please put your model into <strong style="color:#010101">%s</strong> then you can download it online
new_train_gpu_tooltips = The code is storaged in <strong style="color:#010101">%s</strong>, the dataset is storaged in <strong style="color:#010101">%s</strong>, the pre-trained model is storaged in the environment <strong style="color:#010101">%s</strong>, and please put your model into <strong style="color:#010101">%s</strong> then you can download it online
new_infer_gpu_tooltips = The dataset is stored in <strong style="color:#010101">%s</strong>, the model file is stored in <strong style="color:#010101">%s</strong>, please store the inference output in <strong style="color:#010101">%s</strong> for subsequent downloads.

[points]


+ 7
- 2
options/locale/locale_zh-CN.ini View File

@@ -3100,6 +3100,11 @@ task_createmodel=`导入了新模型 <a href="%s/modelmanage/show_model_info?nam
task_gputrainjob=`创建了CPU/GPU类型训练任务 <a href="%s/cloudbrain/train-job/%s">%s</a>`
task_c2netnputrainjob=`创建了NPU类型训练任务 <a href="%s/grampus/train-job/%s">%s</a>`
task_c2netgputrainjob=`创建了CPU/GPU类型训练任务 <a href="%s/grampus/train-job/%s">%s</a>`
binded_wechat=绑定微信
dataset_recommended=`创建的数据集<a href="%s/datasets">%s</a>被设置为推荐数据集`
create_image=`提交了镜像<span style="font-weight:bold;">%s</span>`
image_recommended=`提交的镜像<span style="font-weight:bold;">%s</span>被设置为推荐镜像`
update_user_avatar=更新了头像

[tool]
ago=%s前
@@ -3220,7 +3225,7 @@ card_type = 卡类型
wrong_specification=您目前不能使用这个资源规格,请选择其他资源规格。

job_name_rule = 请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。
train_dataset_path_rule = 数据集位置存储在环境变量<strong style="color:#010101">data_url</strong>中,训练输出路径存储在环境变量<strong style="color:#010101">train_url</strong>中。
train_dataset_path_rule = 数据集位置存储在环境变量<strong style="color:#010101">data_url</strong>中,预训练模型存放在环境变量<strong style="color:#010101">ckpt_url</strong>中,训练输出路径存储在环境变量<strong style="color:#010101">train_url</strong>中。
infer_dataset_path_rule = 数据集位置存储在环境变量<strong style="color:#010101">data_url</strong>中,推理输出路径存储在环境变量<strong style="color:#010101">result_url</strong>中。
view_sample = 查看样例
inference_output_path_rule = 推理输出路径存储在环境变量result_url中。
@@ -3258,7 +3263,7 @@ load_code_failed=代码加载失败,请确认选择了正确的分支。


error.dataset_select = 数据集选择错误:数量超过限制或者有同名数据集
new_train_gpu_tooltips =训练脚本存储在<strong style="color:#010101">%s</strong>中,数据集存储在<strong style="color:#010101">%s</strong>中,训练输出请存储在<strong style="color:#010101">%s</strong>中以供后续下载。
new_train_gpu_tooltips =训练脚本存储在<strong style="color:#010101">%s</strong>中,数据集存储在<strong style="color:#010101">%s</strong>中,预训练模型存放在环境变量<strong style="color:#010101">%s</strong>中,训练输出请存储在<strong style="color:#010101">%s</strong>中以供后续下载。
new_infer_gpu_tooltips = 数据集存储在<strong style="color:#010101">%s</strong>中,模型文件存储在<strong style="color:#010101">%s</strong>中,推理输出请存储在<strong style="color:#010101">%s</strong>中以供后续下载。

[points]


+ 13
- 2
public/home/home.js View File

@@ -163,6 +163,11 @@ document.onreadystatechange = function () {
html += recordPrefix + actionName;
html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>"
}
else if(record.OpType == "35"){
var datasetLink = "<a href=\"" + getRepoLink(record) + "/datasets" + "\" rel=\"nofollow\">" + record.Content.split('|')[1] + "</a>";
actionName = actionName.replace('{dataset}', datasetLink);
html += recordPrefix + actionName;
}
else{
continue;
}
@@ -354,7 +359,10 @@ var actionNameZH={
"30":"导入了新模型",
"31":"创建了CPU/GPU类型训练任务",
"32":"创建了NPU类型训练任务",
"33":"创建了CPU/GPU类型训练任务"
"33":"创建了CPU/GPU类型训练任务",
"35":"创建的数据集 {dataset} 被设置为推荐数据集",
"36":"提交了镜像 {image}",
"37":"提交的镜像 {image} 被设置为推荐镜像",
};

var actionNameEN={
@@ -382,7 +390,10 @@ var actionNameEN={
"30":" created new model",
"31":" created CPU/GPU type training task",
"32":" created NPU type training task",
"33":" created CPU/GPU type training task"
"33":" created CPU/GPU type training task",
"35":" created dataset {dataset} was set as recommended dataset",
"36":"committed image {image}",
"37":"committed image {image} was set as recommended image",
};

var repoAndOrgZH={


+ 1
- 1
routers/repo/cloudbrain.go View File

@@ -2769,7 +2769,7 @@ func getTrainJobCommand(form auth.CreateCloudBrainForm) (string, error) {
}
}
if form.CkptName != "" {
param += " --pretrainmodelname" + "=" + form.CkptName
param += " --ckpt_url" + "=" + "/pretrainmodel/" + form.CkptName
}

command += "python /code/" + bootFile + param + " > " + cloudbrain.ModelMountPath + "/" + form.DisplayJobName + "-" + cloudbrain.LogFile


+ 16
- 15
routers/repo/grampus.go View File

@@ -18,7 +18,6 @@ import (

"code.gitea.io/gitea/services/reward/point/account"


"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/grampus"
@@ -721,7 +720,7 @@ func grampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
req.CkptName = form.CkptName
req.ModelVersion = form.ModelVersion
req.PreTrainModelUrl = form.PreTrainModelUrl
req.PreTrainModelPath = preTrainModelPath
}

err = grampus.GenerateTrainJob(ctx, req)
@@ -986,8 +985,7 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo
command += "pwd;cd " + workDir + fmt.Sprintf(grampus.CommandPrepareScript, setting.Grampus.SyncScriptProject, setting.Grampus.SyncScriptProject)
//download code & dataset
if processorType == grampus.ProcessorTypeNPU {
commandDownload := "./downloader_for_obs " + setting.Bucket + " " + codeRemotePath + " " + grampus.CodeArchiveName + " '" + dataRemotePath + "' '" + datasetName + "'"
commandDownload = processPretrainModelParameter(pretrainModelPath, pretrainModelFileName, commandDownload)
commandDownload := "./downloader_for_obs " + setting.Bucket + " " + codeRemotePath + " " + grampus.CodeArchiveName + ";"
command += commandDownload
} else if processorType == grampus.ProcessorTypeGPU {
commandDownload := "./downloader_for_minio " + setting.Grampus.Env + " " + codeRemotePath + " " + grampus.CodeArchiveName + " '" + dataRemotePath + "' '" + datasetName + "'"
@@ -996,10 +994,14 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo
}

//unzip code & dataset
unZipDatasetCommand := generateDatasetUnzipCommand(datasetName)

commandUnzip := "cd " + workDir + "code;unzip -q master.zip;echo \"start to unzip dataset\";cd " + workDir + "dataset;" + unZipDatasetCommand
command += commandUnzip
if processorType == grampus.ProcessorTypeNPU {
commandUnzip := "cd " + workDir + "code;unzip -q master.zip;"
command += commandUnzip
} else if processorType == grampus.ProcessorTypeGPU {
unZipDatasetCommand := generateDatasetUnzipCommand(datasetName)
commandUnzip := "cd " + workDir + "code;unzip -q master.zip;echo \"start to unzip dataset\";cd " + workDir + "dataset;" + unZipDatasetCommand
command += commandUnzip
}

command += "echo \"unzip finished;start to exec code;\";"

@@ -1029,14 +1031,13 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo
}
}

if pretrainModelFileName != "" {
paramCode += " --pretrainmodelname" + "=" + pretrainModelFileName
}

var commandCode string
if processorType == grampus.ProcessorTypeNPU {
commandCode = "/bin/bash /home/work/run_train_for_openi.sh " + workDir + "code/" + strings.ToLower(repoName) + "/" + bootFile + " /tmp/log/train.log" + paramCode + ";"
} else if processorType == grampus.ProcessorTypeGPU {
if pretrainModelFileName != "" {
paramCode += " --ckpt_url" + "=" + workDir + "pretrainmodel/" + pretrainModelFileName
}
commandCode = "cd " + workDir + "code/" + strings.ToLower(repoName) + ";python " + bootFile + paramCode + ";"
}

@@ -1077,14 +1078,14 @@ func generateDatasetUnzipCommand(datasetName string) string {
datasetNameArray := strings.Split(datasetName, ";")
if len(datasetNameArray) == 1 { //单数据集
unZipDatasetCommand = "unzip -q '" + datasetName + "';"
if strings.HasSuffix(datasetName, ".tar.gz") {
if strings.HasSuffix(datasetNameArray[0], ".tar.gz") {
unZipDatasetCommand = "tar --strip-components=1 -zxvf '" + datasetName + "';"
}

} else { //多数据集
for _, datasetNameTemp := range datasetNameArray {
if strings.HasSuffix(datasetName, ".tar.gz") {
unZipDatasetCommand = unZipDatasetCommand + "tar -zxvf '" + datasetName + "';"
if strings.HasSuffix(datasetNameTemp, ".tar.gz") {
unZipDatasetCommand = unZipDatasetCommand + "tar -zxvf '" + datasetNameTemp + "';"
} else {
unZipDatasetCommand = unZipDatasetCommand + "unzip -q '" + datasetNameTemp + "' -d './" + strings.TrimSuffix(datasetNameTemp, ".zip") + "';"
}


+ 2
- 2
routers/repo/modelarts.go View File

@@ -1052,9 +1052,9 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
ctx.RenderWithErr("Resource specification not available", tplModelArtsTrainJobNew, &form)
return
}
if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) {
if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice*form.WorkServerNumber) {
log.Error("point balance is not enough,userId=%d specId=%d", ctx.User.ID, spec.ID)
cloudBrainNewDataPrepare(ctx)
trainJobNewDataPrepare(ctx)
ctx.RenderWithErr(ctx.Tr("points.insufficient_points_balance"), tplModelArtsTrainJobNew, &form)
return
}


+ 2
- 2
routers/reward/point/point.go View File

@@ -141,7 +141,7 @@ func GetAdminRewardList(ctx *context.Context) {
func buildAdminRewardRecordListOpts(ctx *context.Context) (*models.RewardRecordListOpts, error) {
operateType := ctx.Query("operate")
sourceType := ctx.Query("source")
actionType := ctx.QueryInt("action")
taskType := ctx.Query("action")
serialNo := ctx.Query("serialNo")
status := ctx.Query("status")

@@ -161,7 +161,7 @@ func buildAdminRewardRecordListOpts(ctx *context.Context) (*models.RewardRecordL
RewardType: models.RewardTypePoint,
OrderBy: orderBy,
SourceType: sourceType,
ActionType: actionType,
TaskType: taskType,
SerialNo: serialNo,
IsAdmin: true,
Status: status,


+ 2
- 2
routers/task/config.go View File

@@ -13,11 +13,11 @@ import (
func GetTaskConfigList(ctx *context.Context) {
page := ctx.QueryInt("Page")
status := ctx.QueryInt("Status")
action := ctx.QueryInt("Action")
action := ctx.Query("Action")
r, err := task.GetTaskConfigWithLimitList(models.GetTaskConfigOpts{
ListOptions: models.ListOptions{PageSize: 20, Page: page},
Status: status,
ActionType: action,
TaskType: action,
})
if err != nil {
log.Error("GetTaskConfigList error.%v", err)


+ 15
- 3
services/reward/cloudbrain_deduct.go View File

@@ -25,20 +25,32 @@ func AcceptStatusChangeAction() {
}

func StartAndGetCloudBrainPointDeductTask(task models.Cloudbrain) (*models.RewardPeriodicTask, error) {
sourceId := getCloudBrainPointTaskSourceId(task)
r, err := GetPeriodicTask(models.SourceTypeRunCloudbrainTask, sourceId, sourceId, models.OperateTypeDecrease)
if err != nil {
return nil, err
}

if r != nil {
log.Debug("PeriodicTask is already exist.cloudbrain.ID = %d", task.ID)
return r, nil
}

if !setting.CloudBrainPaySwitch {
log.Debug("CloudBrainPaySwitch is off")
return nil, nil
}

unitPrice, err := models.GetCloudbrainTaskUnitPrice(task.ID)
unitPrice, err := models.GetCloudbrainTaskUnitPrice(task)
if err != nil {
return nil, err
}
if unitPrice == 0 {
log.Debug("finish StartAndGetCloudBrainPointDeductTask, UnitPrice = 0 task.ID=%d", task.ID)
log.Debug("Finish startAndGetCloudBrainPointDeductTask, UnitPrice = 0 task.ID=%d", task.ID)
return nil, nil
}

return StartAndGetPeriodicTask(&models.StartPeriodicTaskOpts{
return StartPeriodicTask(&models.StartPeriodicTaskOpts{
SourceType: models.SourceTypeRunCloudbrainTask,
SourceId: getCloudBrainPointTaskSourceId(task),
TargetUserId: task.UserID,


+ 22
- 24
services/reward/operator.go View File

@@ -180,43 +180,41 @@ func UpdateRewardRecordToFinalStatus(sourceType, requestId, newStatus string) er
return nil
}

func StartPeriodicTaskAsyn(opts *models.StartPeriodicTaskOpts) {
go StartAndGetPeriodicTask(opts)
func GetPeriodicTask(sourceType models.SourceType, sourceId, requestId string, operateType models.RewardOperateType) (*models.RewardPeriodicTask, error) {
_, err := models.GetPointOperateRecordBySourceTypeAndRequestId(sourceType.Name(), requestId, operateType.Name())
if err == nil {
task, err := models.GetPeriodicTaskBySourceIdAndType(sourceType, sourceId, operateType)
if err != nil {
log.Error("GetPeriodicTaskBySourceIdAndType error,%v", err)
return nil, err
}
return task, nil
}

if err != nil && !models.IsErrRecordNotExist(err) {
log.Error("GetPointOperateRecordBySourceTypeAndRequestId error,%v", err)
return nil, err
}
return nil, nil
}

func StartAndGetPeriodicTask(opts *models.StartPeriodicTaskOpts) (*models.RewardPeriodicTask, error) {
defer func() {
if err := recover(); err != nil {
combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2))
log.Error("PANIC:%v", combinedErr)
}
}()
func StartPeriodicTask(opts *models.StartPeriodicTaskOpts) (*models.RewardPeriodicTask, error) {
//add lock
var rewardLock = redis_lock.NewDistributeLock(redis_key.RewardOperateLock(opts.RequestId, opts.SourceType.Name(), opts.OperateType.Name()))
isOk, err := rewardLock.Lock(3 * time.Second)
if err != nil {
log.Error("StartAndGetPeriodicTask RewardOperateLock error. %v", err)
return nil, err
}
if !isOk {
log.Info("duplicated operate request,targetUserId=%d requestId=%s", opts.TargetUserId, opts.RequestId)
return nil, nil
}
defer rewardLock.UnLock()

_, err = models.GetPointOperateRecordBySourceTypeAndRequestId(opts.SourceType.Name(), opts.RequestId, opts.OperateType.Name())
if err == nil {
task, err := models.GetPeriodicTaskBySourceIdAndType(opts.SourceType, opts.SourceId, opts.OperateType)
if err != nil {
log.Error("GetPeriodicTaskBySourceIdAndType error,%v", err)
return nil, err
}
return task, nil
r, err := GetPeriodicTask(opts.SourceType, opts.SourceId, opts.RequestId, opts.OperateType)
if err != nil {
return nil, err
}

if err != nil && !models.IsErrRecordNotExist(err) {
log.Error("operate is handled error,%v", err)
return nil, err
if r != nil {
return r, nil
}

//new reward operate record


+ 14
- 12
services/socketwrap/clientManager.go View File

@@ -10,7 +10,7 @@ import (
"github.com/elliotchance/orderedmap"
)

var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33}
var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35}

type ClientsManager struct {
Clients *orderedmap.OrderedMap
@@ -107,16 +107,18 @@ func initActionQueue() {

func filterUserPrivateInfo(action *models.Action) {
action.Comment = nil
action.ActUser.Email = ""
action.ActUser.Passwd = ""
action.ActUser.PasswdHashAlgo = ""
action.ActUser.PrivateKey = ""
action.ActUser.PublicKey = ""
action.ActUser.Salt = ""
action.ActUser.FullName = ""
action.ActUser.AvatarEmail = ""
action.ActUser.IsAdmin = false
action.ActUser.EmailNotificationsPreference = ""
action.ActUser.IsOperator = false
if action.ActUser != nil {
action.ActUser.Email = ""
action.ActUser.Passwd = ""
action.ActUser.PasswdHashAlgo = ""
action.ActUser.PrivateKey = ""
action.ActUser.PublicKey = ""
action.ActUser.Salt = ""
action.ActUser.FullName = ""
action.ActUser.AvatarEmail = ""
action.ActUser.IsAdmin = false
action.ActUser.EmailNotificationsPreference = ""
action.ActUser.IsOperator = false
}

}

+ 46
- 12
services/task/task.go View File

@@ -6,6 +6,8 @@ import (
"code.gitea.io/gitea/services/reward"
"code.gitea.io/gitea/services/reward/limiter"
"fmt"
"strconv"
"strings"
)

func Accomplish(action models.Action) {
@@ -15,46 +17,78 @@ func Accomplish(action models.Action) {
log.Error("PANIC:%v", combinedErr)
}
}()
action.OpType = models.GetTaskOptType(action)
switch action.OpType {
taskType := models.GetTaskTypeFromAction(action.OpType)
if taskType == "" {
log.Info("Accomplish finished.taskType is not exist.action.ID=%d", action.ID)
return
}
actions := make([]models.Action, 0)
actions = append(actions, action)
switch taskType {
//only creating public repo can be rewarded
case models.ActionCreateRepo:
case models.TaskCreatePublicRepo:
if action.Repo.IsPrivate {
return
}
//only creating public image can be rewarded
case models.ActionCreateImage:
case models.TaskCreateImage:
if action.IsPrivate {
return
}
case models.ActionBindWechat:
case models.TaskBindWechat:
n, err := models.CountWechatBindLog(action.Content, models.WECHAT_BIND)
if err != nil {
log.Error("CountWechatBindLog error when accomplish task,err=%v", err)
return
}
//if wechatOpenId has been bound before,the action can not get reward
if n > 1 {
if n > 1 && models.IsWechatOpenIdRewarded(action.Content) {

log.Debug("the wechat account has been bound before,wechatOpenId = %s", action.Content)
return
}
case models.TaskDatasetRecommended:
datasetIdStr := strings.Split(action.Content, "|")[0]
datasetId, _ := strconv.ParseInt(datasetIdStr, 10, 64)
users, err := models.GetAllDatasetContributorByDatasetId(datasetId)
if err != nil {
return
}
for _, user := range users {
if user.ID == action.ActUserID {
continue
}
actions = append(actions, models.Action{
ID: action.ID,
OpType: models.ActionDatasetRecommended,
ActUserID: action.UserID,
UserID: user.ID,
RepoID: action.RepoID,
Content: action.Content,
})
}

}
batchAccomplish(taskType, actions...)
}

func batchAccomplish(taskType models.TaskType, actions ...models.Action) {
for _, act := range actions {
go accomplish(act, taskType)
}
go accomplish(action)
}

func accomplish(action models.Action) error {
func accomplish(action models.Action, taskType models.TaskType) error {
defer func() {
if err := recover(); err != nil {
combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2))
log.Error("PANIC:%v", combinedErr)
}
}()
userId := action.ActUserID
taskType := fmt.Sprint(action.OpType)
userId := action.UserID

//get task config
config, err := GetTaskConfig(taskType)
config, err := GetTaskConfig(string(taskType))
if err != nil {
log.Error("GetTaskConfig error,%v", err)
return err
@@ -86,7 +120,7 @@ func accomplish(action models.Action) error {
reward.Operate(&models.RewardOperateContext{
SourceType: models.SourceTypeAccomplishTask,
SourceId: fmt.Sprint(action.ID),
SourceTemplateId: fmt.Sprint(action.OpType),
SourceTemplateId: string(taskType),
Title: config.Title,
Reward: models.Reward{
Amount: config.AwardAmount,


+ 1
- 1
templates/repo/cloudbrain/trainjob/new.tmpl View File

@@ -122,7 +122,7 @@
{{template "custom/task_wait_count" .}}
<div style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;">
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i>
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/code" "/dataset" "/model" | Safe}}</span>
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/code" "/dataset" "ckpt_url" "/model" | Safe}}</span>
</div>
</div>
<div class="required min_title inline field" style="margin-bottom: 0rem !important;">


+ 0
- 2
templates/repo/datasets/index.tmpl View File

@@ -203,7 +203,6 @@
</div>
{{end}}
<div class="row" style="align-items: center;">
{{if or (.dataset.Category) (.dataset.Task) (.dataset.License)}}
<div class="column ten wide" style="padding:0">
{{if .dataset.Category}}
{{$category := .dataset.Category}}
@@ -220,7 +219,6 @@
href="{{AppSubUrl}}/explore/datasets?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{.dataset.License}}">{{.dataset.License}}</a>
{{end}}
</div>
{{end}}
<div class="column six wide right aligned" style="padding:0">
<el-select v-model="datasetType" style="width: 40%;" size="small" @change="changeDatasetType">
<i slot="prefix" style="display: inline-block;color: #101010;"


+ 1
- 1
templates/repo/grampus/trainjob/gpu/new.tmpl View File

@@ -113,7 +113,7 @@
{{template "custom/task_wait_count" .}}
<div style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;">
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i>
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/tmp/code" "/tmp/dataset" "/tmp/output" | Safe}}</span>
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/tmp/code" "/tmp/dataset" "ckpt_url" "/tmp/output" | Safe}}</span>
</div>
</div>
<div class="required min_title inline field" style="margin-bottom: 0rem !important;">


+ 1
- 1
templates/repo/grampus/trainjob/npu/new.tmpl View File

@@ -106,7 +106,7 @@
{{template "custom/task_wait_count" .}}
<div style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;">
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i>
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/cache/code" "/cache/dataset" "/cache/output" | Safe}}</span>
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_train_gpu_tooltips" "/cache/code" "/cache/dataset" "ckpt_url" "/cache/output" | Safe}}</span>
</div>
</div>
<div class="required min_title inline field" style="margin-bottom: 0rem !important;">


+ 2
- 2
templates/repo/modelarts/trainjob/new.tmpl View File

@@ -196,8 +196,8 @@

<div class="inline field min_title required">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
{{if .bootFile}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" >
{{if .boot_file}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.boot_file}}" tabindex="3" autofocus required maxlength="255" >
{{else}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" >
{{end}}


+ 2
- 2
templates/repo/modelarts/trainjob/show.tmpl View File

@@ -256,7 +256,7 @@

{{if .CanModify}}
<a class="ti-action-menu-item"
href="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/create_version?version_name={{.VersionName}}">{{$.i18n.Tr "repo.modelarts.modify"}}</a>
href="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/create_version?version_name={{.VersionName}}&path=show">{{$.i18n.Tr "repo.modelarts.modify"}}</a>
{{else}}
<a class="ti-action-menu-item disabled"
href="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/create_version?version_name={{.VersionName}}">{{$.i18n.Tr "repo.modelarts.modify"}}</a>
@@ -650,7 +650,7 @@

<div class="two inline fields ">
<div class="required ten wide field">
<label style="margin-left: -23px;">{{.i18n.Tr "repo.modelarts.train_job"}}</label>
<label>{{.i18n.Tr "repo.modelarts.train_job"}}</label>&nbsp;
<input type="hidden" class="width83" id="JobId" name="JobId" readonly required>
<input class="width83" id="JobName" readonly required>



+ 6
- 2
templates/repo/modelarts/trainjob/version_new.tmpl View File

@@ -261,7 +261,7 @@
<button class="ui create_train_job green button">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>
<a class="ui button" href="{{.RepoLink}}/modelarts/train-job">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
<a class="ui button cancel" href="{{.RepoLink}}/modelarts/train-job">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>

<!-- 模态框 -->
@@ -274,7 +274,11 @@
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script src="{{StaticUrlPrefix}}/js/cloudbrainNew.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
let version_name = location.search.split('?version_name=')[1]
const params = new URLSearchParams(location.search)
let version_name = params.get('create_version')
if(params.get('path')){
$('.ui.cancel.button').attr('href',location.pathname.split('/create_version')[0])
}
$("#parents_version").val(version_name)
$("input[name=version_name]").attr('value',version_name)
;(function() {


+ 14
- 14
templates/reward/point/rule.tmpl View File

@@ -27,79 +27,79 @@
<th style="width:200px;">上限值</th>
<th>奖励细节澄清</th>
</tr>
<tr key="34">
<tr key="BindWechat">
<td class="t-center">完成微信扫码验证</td>
<td class="t-center point">-</td>
<td class="t-center"><span class="typ">累计</span>积分获取上限<span class="limit"> - </span></td>
<td>1、首次完成微信扫码验证,即获取积分。<br>2、同个账号,更换微信号码再验证不重复给积分。<br>3、同一个微信,绑定第一个账号时奖励积分,下次绑定其他账号时不再奖励。</td>
</tr>
<tr key="1">
<tr key="CreatePublicRepo">
<td class="t-center">创建或Fork公开项目</td>
<td class="t-center point">-</td>
<td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td>
<td>请注意项目质量,请勿复制粘贴或者重复公开项目,任何非常规的以公开项目去获取积分的行为将被认定为积分舞弊,将扣除所有积分。</td>
</tr>
<tr key="7">
<tr key="CreatePullRequest">
<td class="t-center">每日提出PR</td>
<td class="t-center point">-</td>
<td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td>
<td></td>
</tr>
<tr key="40">
<tr key="PushCommits">
<td class="t-center">每日commit</td>
<td class="t-center point">-</td>
<td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td>
<td>通过前台界面和后台命令行方式commit,都可获得奖励积分。</td>
</tr>
<tr key="6">
<tr key="CreateIssue">
<td class="t-center">每日提出任务</td>
<td class="t-center point">-</td>
<td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td>
<td></td>
</tr>
<tr key="10">
<tr key="CommentIssue">
<td class="t-center">发表评论</td>
<td class="t-center point">-</td>
<td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td>
<td>禁止空评论或评论后马上删除等非正常获取积分的方式,一经发现将扣除所有积分。</td>
</tr>
<tr key="24">
<tr key="UploadAttachment">
<td class="t-center">上传数据集文件</td>
<td class="t-center point">-</td>
<td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td>
<td>请注意数据集质量,请勿复制粘贴或者重复公开数据集,任何非常规的以公开数据集去获取积分的行为将被认定为积分舞弊,将扣除所有积分。</td>
</tr>
<tr key="36">
<tr key="DatasetRecommended">
<td class="t-center">数据集被平台推荐</td>
<td class="t-center point">-</td>
<td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td>
<td>仅统计属于个人的数据集,属于组织的数据集暂不统计。</td>
</tr>
<tr key="30">
<tr key="CreateNewModelTask">
<td class="t-center">导入新模型</td>
<td class="t-center point">-</td>
<td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td>
<td>请注意模型质量,请勿重复导入相同模型,任何非常规的以导入新模型去获取 积分的行为将被认定为积分舞弊,将扣除所有积分。</td>
</tr>
<tr key="35">
<tr key="CreateCloudbrainTask">
<td class="t-center">每日运行云脑任务</td>
<td class="t-center point">-</td>
<td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td>
<td> 每日运行调试、训练、推理、评测中任何一种任务,即可获得。</td>
</tr>
<tr key="37">
<tr key="CreateImage">
<td class="t-center">提交新公开镜像</td>
<td class="t-center point">-</td>
<td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td>
<td></td>
</tr>
<tr key="38">
<tr key="ImageRecommend">
<td class="t-center">镜像被平台推荐</td>
<td class="t-center point">-</td>
<td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td>
<td></td>
</tr>
<tr key="39">
<tr key="ChangeUserAvatar">
<td class="t-center">首次更换头像</td>
<td class="t-center point">-</td>
<td class="t-center"><span class="typ">累计</span>积分获取上限<span class="limit"> - </span></td>
@@ -133,7 +133,7 @@
if (taskRule.TaskCode == key) {
ruleTr.find('.point').text(taskRule.AwardAmount);
ruleTr.find('.typ').text(taskRule.RefreshRate == 'DAILY' ? '每日' : taskRule.RefreshRate == 'NOT_CYCLE' ? '累计' : taskRule.RefreshRate);
ruleTr.find('.limit').text(taskRule.LimitNum);
ruleTr.find('.limit').text(taskRule.AwardAmount * taskRule.LimitNum);
findOr = true;
break;
}


+ 4
- 0
templates/user/dashboard/feeds.tmpl View File

@@ -90,6 +90,8 @@
{{$.i18n.Tr "action.task_c2netnputrainjob" .GetRepoLink .Content .RefName | Str2html}}
{{else if eq .GetOpType 33}}
{{$.i18n.Tr "action.task_c2netgputrainjob" .GetRepoLink .Content .RefName | Str2html}}
{{else if eq .GetOpType 35}}
{{$.i18n.Tr "action.dataset_recommended" .GetRepoLink (index .GetIssueInfos 1 | RenderEmoji) | Str2html}}
{{end}}
</p>
{{if or (eq .GetOpType 5) (eq .GetOpType 18)}}
@@ -137,6 +139,8 @@
<span class="text grey"><i class="ri-picture-in-picture-exit-line icon big"></i></span>
{{else if eq .GetOpType 31}}
<span class="text grey"><i class="ri-character-recognition-line icon big"></i></span>
{{else if eq .GetOpType 35}}
<span class="text grey"><i class="thumbs up outline icon big"></i></span>
{{else}}
<span class="text grey">{{svg (printf "octicon-%s" (ActionIcon .GetOpType)) 32}}</span>
{{end}}


+ 80
- 10
web_src/js/features/cloudbrainShow.js View File

@@ -106,7 +106,7 @@ export default async function initCloudrainSow() {
let ID = $(`#accordion${version_name}`).data("jobid");
let repoPath = $(`#accordion${version_name}`).data("repopath");
$(`#log_file${version_name}`).siblings("pre").remove();
$(".ui.inverted.active.dimmer").css("display", "block");
$(`#log${version_name} .ui.inverted.active.dimmer`).css("display", "block");
$.get(
`/api/v1/repos/${repoPath}/${ID}/log?version_name=${version_name}&base_line=&lines=50&order=asc`,
(data) => {
@@ -121,7 +121,13 @@ export default async function initCloudrainSow() {
}, 1000);
scrollAnimation(logContentDom, logContentDom.scrollTop, 0);
}
);
).fail((err) => {
$(`#log${version_name} .ui.inverted.active.dimmer`).css(
"display",
"none"
);
throw err;
});
});
$(".log_bottom").click(function (e) {
let version_name = $(this).data("version");
@@ -166,6 +172,10 @@ export default async function initCloudrainSow() {
}
}
).fail(function (err) {
$(`#log${version_name} .ui.inverted.active.dimmer`).css(
"display",
"none"
);
console.log(err);
});
scrollAnimation(
@@ -174,7 +184,13 @@ export default async function initCloudrainSow() {
logContentDom.scrollHeight - logContentDom.clientHeight
);
}
);
).fail((err) => {
$(`#log${version_name} .ui.inverted.active.dimmer`).css(
"display",
"none"
);
throw err;
});
});

function loadLog(version_name) {
@@ -469,20 +485,24 @@ export default async function initCloudrainSow() {
}
let faildModelName = $('input[name="model_name"]').val();
let faildModelVersion = $('input[name="model_version"]').val();
let faildTrainUrl = $('input[name="pre_train_model_url"]').val();
let faildCkptName = $('input[name="ckpt_name"]').val();
let dataID;
// 新建错误的表单返回初始化
if (faildModelName && nameList.includes(faildModelName)) {
$("#select_model").dropdown("set text", faildModelName);
$("#select_model").dropdown("set value", faildModelName);
$("#select_model_version").dropdown("set text", faildModelVersion);
$("#select_model_version").dropdown("set value", faildTrainUrl);
$("#select_model_checkpoint").dropdown("set text", faildCkptName);
$("#select_model_checkpoint").dropdown("set value", faildCkptName);
nameMap[faildModelName].forEach((element) => {
if (element.Version === faildModelVersion) {
dataID = element.ID;
}
});
initModelVerison(faildModelName, nameMap, faildModelVersion);
initModelckpt(dataID);
}
}
);
}

$("#select_model").dropdown({
onChange: function (value, text, $selectedItem) {
$("#model_name_version").empty();
@@ -523,7 +543,9 @@ export default async function initCloudrainSow() {
const dataID =
$selectedItem && $selectedItem[0].getAttribute("data-id");
$("input#ai_model_version").val(text);
$("#select_model_checkpoint").dropdown("set text", "");
$("#select_model_checkpoint").addClass("loading");

$("#model_checkpoint").empty();
let html = "";
loadCheckpointList(dataID).then((res) => {
@@ -572,7 +594,55 @@ export default async function initCloudrainSow() {
},
});
});

function initModelVerison(value, nameMap, faildModelVersion) {
let faildTrainUrl = $('input[name="pre_train_model_url"]').val();
let html = "";
nameMap[value].forEach((element) => {
let { TrainTaskInfo } = element;
TrainTaskInfo = JSON.parse(TrainTaskInfo);
html += `<div class="item" data-label="${element.Label}" data-id="${element.ID}" data-value="${element.Path}">${element.Version}</div>`;
});
$("#model_name_version").append(html);
$("#select_model_version").dropdown("set text", faildModelVersion);
$("#select_model_version").dropdown("set value", faildTrainUrl);
}
function initModelckpt(dataID) {
let faildCkptName = $('input[name="ckpt_name"]').val();
$("#select_model_checkpoint").addClass("loading");
$("#model_checkpoint").empty();
let html = "";
loadCheckpointList(dataID).then((res) => {
res.forEach((element) => {
const ckptSuffix = element.FileName.split(".");
const loadCheckpointFile = [
"ckpt",
"pb",
"h5",
"json",
"pkl",
"pth",
"t7",
"pdparams",
"onnx",
"pbtxt",
"keras",
"mlmodel",
"cfg",
"pt",
];
if (
!element.IsDir &&
loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length - 1])
) {
html += `<div class="item" data-value=${element.FileName}>${element.FileName}</div>`;
}
});
$("#model_checkpoint").append(html);
$("#select_model_checkpoint").removeClass("loading");
$("#select_model_checkpoint").dropdown("set text", faildCkptName);
$("#select_model_checkpoint").dropdown("set value", faildCkptName);
});
}
function loadCheckpointList(value) {
return new Promise((resolve, reject) => {
$.get(


+ 22
- 3
web_src/js/standalone/cloudbrainNew.js View File

@@ -33,7 +33,7 @@
value += `<input type="text" class="shipping_first-name" value="${paramsObject.label}">`;
} else {
value +=
'<input type="text" class="shipping_first-name" required placeholder="' +
'<input type="text" class="shipping_first-name" required placeholder="' +
placeholder_name +
'">';
}
@@ -43,7 +43,7 @@
value += `<input type="text" class="shipping_last-name" value="${paramsObject.value}">`;
} else {
value +=
'<input type="text" class="shipping_last-name" required placeholder="' +
'<input type="text" class="shipping_last-name" required placeholder="' +
placeholder_value +
'">';
}
@@ -133,14 +133,30 @@
function send_run_para() {
var run_parameters = [];
var msg = {};
let paraFlag = true;
$(".dynamic.field .two.fields").each(function () {
var para_name = $(this).find("input.shipping_first-name").val();
var para_value = $(this).find("input.shipping_last-name").val();
if (!para_name) {
$(this).find("input.shipping_first-name").parent().addClass("error");
paraFlag = false;
return;
} else {
$(this).find("input.shipping_first-name").parent().removeClass("error");
}
if (!para_value) {
$(this).find("input.shipping_last-name").parent().addClass("error");
paraFlag = false;
return;
} else {
$(this).find("input.shipping_last-name").parent().removeClass("error");
}
run_parameters.push({ label: para_name, value: para_value });
});
msg["parameter"] = run_parameters;
msg = JSON.stringify(msg);
$("#store_run_para").val(msg);
return paraFlag;
}
function get_name() {
let name1 = $("#engine_name .text").text();
@@ -152,7 +168,10 @@
validate();
$(".ui.create_train_job.green.button").click(function (e) {
get_name();
send_run_para();
let paramNotValue = send_run_para();
if (!paramNotValue) {
return false;
}
validate();
});
})();

+ 2
- 2
web_src/vuepages/const/index.js View File

@@ -3,8 +3,8 @@ import { i18n } from '~/langs';
export const SOURCE_TYPE = [{ k: 'ACCOMPLISH_TASK', v: i18n.t('accomplishTask') }, { k: 'ADMIN_OPERATE', v: i18n.t('adminOperate') }, { k: 'RUN_CLOUDBRAIN_TASK', v: i18n.t('runCloudBrainTask') }];
export const CONSUME_STATUS = [{ k: 'OPERATING', v: i18n.t('operating') }, { k: 'SUCCEEDED', v: i18n.t('succeeded') }];
export const POINT_ACTIONS = [
{ k: 1, v: i18n.t('createPublicProject') }, { k: 6, v: i18n.t('dailyPutforwardTasks') }, { k: 7, v: i18n.t('dailyPR') }, { k: 10, v: i18n.t('comment') }, { k: 24, v: i18n.t('uploadDatasetFile') }, { k: 30, v: i18n.t('importNewModel') }, { k: 34, v: i18n.t('completeWechatCodeScanningVerification') },
{ k: 35, v: i18n.t('dailyRunCloudbrainTasks') }, { k: 36, v: i18n.t('datasetRecommendedByThePlatform') }, { k: 37, v: i18n.t('submitNewPublicImage') }, { k: 38, v: i18n.t('imageRecommendedByThePlatform') }, { k: 39, v: i18n.t('firstChangeofAvatar') }, { k: 40, v: i18n.t('dailyCommit') },
{ k: 'CreatePublicRepo', v: i18n.t('createPublicProject') }, { k: 'CreateIssue', v: i18n.t('dailyPutforwardTasks') }, { k: 'CreatePullRequest', v: i18n.t('dailyPR') }, { k: 'CommentIssue', v: i18n.t('comment') }, { k: 'UploadAttachment', v: i18n.t('uploadDatasetFile') }, { k: 'CreateNewModelTask', v: i18n.t('importNewModel') }, { k: 'BindWechat', v: i18n.t('completeWechatCodeScanningVerification') },
{ k: 'CreateCloudbrainTask', v: i18n.t('dailyRunCloudbrainTasks') }, { k: 'DatasetRecommended', v: i18n.t('datasetRecommendedByThePlatform') }, { k: 'CreateImage', v: i18n.t('submitNewPublicImage') }, { k: 'ImageRecommend', v: i18n.t('imageRecommendedByThePlatform') }, { k: 'ChangeUserAvatar', v: i18n.t('firstChangeofAvatar') }, { k: 'PushCommits', v: i18n.t('dailyCommit') },
];
export const JOB_TYPE = [{ k: 'DEBUG', v: i18n.t('debugTask') }, { k: 'TRAIN', v: i18n.t('trainTask') }, { k: 'INFERENCE', v: i18n.t('inferenceTask') }, { k: 'BENCHMARK', v: i18n.t('benchmarkTask') }];



+ 4
- 0
web_src/vuepages/langs/config/en-US.js View File

@@ -69,6 +69,9 @@ const en = {
setAsRecommendedImage: ' was set as recommended image',
updatedAvatar: 'updated avatar',
pushedBranch: 'pushed to {branch} at ',
deleteBranch: 'deleted branch {branch} from {repo}',
pushedTag: ' pushed tag {tag} to ',
deleteTag: ' deleted tag {tag} from {repo}',
dailyMaxTips: `can't get full points when reach the daily upper limit`,
memory: 'Memory',
sharedMemory: 'Shared Memory',
@@ -129,6 +132,7 @@ const en = {
shareMem: 'Share Memory',
unitPrice: 'Unit Price',
point_hr: 'Point/hr',
node: 'node',
free: 'Free',
onShelfConfirm: 'Are you sure to on shelf the resources specification?',
offShelfConfirm: 'Are you sure to off shelf the resources specification?',


+ 4
- 0
web_src/vuepages/langs/config/zh-CN.js View File

@@ -69,6 +69,9 @@ const zh = {
setAsRecommendedImage: '被设置为推荐镜像',
updatedAvatar: '更新了头像',
pushedBranch: '推送了{branch}分支代码到',
deleteBranch: '从{repo}删除分支{branch}',
pushedTag: '推送了标签{tag}到',
deleteTag: '从{repo}删除了标签{tag}',
dailyMaxTips: '达到每日上限积分,不能拿满分',
memory: '内存',
sharedMemory: '共享内存',
@@ -129,6 +132,7 @@ const zh = {
shareMem: '共享内存',
unitPrice: '单价',
point_hr: '积分/时',
node: '节点',
free: '免费',
onShelfConfirm: '请确认上架该规格?',
offShelfConfirm: '请确认下架该规格?',


+ 48
- 28
web_src/vuepages/pages/reward/point/utils.js View File

@@ -60,7 +60,9 @@ const renderSpecStr = (spec, showPoint) => {
var ngpu = `${spec.ComputeResource}: ${spec.AccCardsNum + '*' + getListValueWithKey(ACC_CARD_TYPE, spec.AccCardType)}`;
var gpuMemStr = spec.GPUMemGiB != 0 ? `${i18n.t('resourcesManagement.gpuMem')}: ${spec.GPUMemGiB}GB, ` : '';
var sharedMemStr = spec.ShareMemGiB != 0 ? `, ${i18n.t('resourcesManagement.shareMem')}: ${spec.ShareMemGiB}GB` : '';
var pointStr = showPoint ? `, ${spec.UnitPrice == 0 ? i18n.t('resourcesManagement.free') : spec.UnitPrice + i18n.t('resourcesManagement.point_hr')}` : '';
var workServerNum = spec.workServerNumber;
var workServerNumStr = showPoint && workServerNum != 1 && spec.UnitPrice != 0 ? '*' + workServerNum + i18n.t('resourcesManagement.node') : '';
var pointStr = showPoint ? `, ${spec.UnitPrice == 0 ? i18n.t('resourcesManagement.free') : spec.UnitPrice + i18n.t('resourcesManagement.point_hr') + workServerNumStr}` : '';
var specStr = `${ngpu}, CPU: ${spec.CpuCores}, ${gpuMemStr}${i18n.t('resourcesManagement.mem')}: ${spec.MemGiB}GB${sharedMemStr}${pointStr}`;
return specStr;
};
@@ -77,7 +79,7 @@ export const getRewardPointRecordInfo = (record) => {
duration: record?.Cloudbrain?.Duration || '--',
taskName: record?.Cloudbrain?.DisplayJobName || '--',
taskId: record?.Cloudbrain?.ID,
action: record?.Action?.OpType ? getPointAction(record.Action.OpType) : '--',
action: record?.Action?.TaskType ? getPointAction(record.Action.TaskType) : '--',
remark: record.Remark,
amount: record.Amount,
};
@@ -85,49 +87,72 @@ export const getRewardPointRecordInfo = (record) => {
if (record.SourceType === 'ADMIN_OPERATE') {
out.remark = record.Remark;
} else if (record.SourceType === 'ACCOMPLISH_TASK') {
switch (record?.Action?.OpType) {
case 1: // 创建公开项目 - 创建了项目OpenI/aiforge
switch (record?.Action?.TaskType) {
case 'CreatePublicRepo': // 创建公开项目 - 创建了项目OpenI/aiforge
out.remark = `${i18n.t('createdRepository')}<a href="${record.Action.RepoLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}</a>`;
break;
case 6: // 每日提出任务 - 创建了任务PCL-Platform.Intelligence/AISynergy#19
case 'CreateIssue': // 每日提出任务 - 创建了任务PCL-Platform.Intelligence/AISynergy#19
out.remark = `${i18n.t('openedIssue')}<a href="${record.Action.RepoLink}/issues/${record.Action.IssueInfos[0]}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}#${record.Action.IssueInfos[0]}</a>`;
break;
case 7: // 每日提出PR - 创建了合并请求OpenI/aiforge#1
case 'CreatePullRequest': // 每日提出PR - 创建了合并请求OpenI/aiforge#1
out.remark = `${i18n.t('createdPullRequest')}<a href="${record.Action.RepoLink}/pulls/${record.Action.IssueInfos[0]}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}#${record.Action.IssueInfos[0]}</a>`;
break;
case 10: // 发表评论 - 评论了任务PCL-Platform.Intelligence/AISynergy#19
case 'CommentIssue': // 发表评论 - 评论了任务PCL-Platform.Intelligence/AISynergy#19
out.remark = `${i18n.t('commentedOnIssue')}<a href="${record.Action.CommentLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}#${record.Action.IssueInfos[0]}</a>`;
break;
case 24: // 上传数据集文件 - 上传了数据集文件MMISTData.zip
case 'UploadAttachment': // 上传数据集文件 - 上传了数据集文件MMISTData.zip
out.remark = `${i18n.t('uploadDataset')}<a href="${record.Action.RepoLink}/datasets" rel="nofollow">${record.Action.RefName}</a>`;
break;
case 30: // 导入新模型 - 导入了新模型resnet50_qx7l
case 'CreateNewModelTask': // 导入新模型 - 导入了新模型resnet50_qx7l
out.remark = `${i18n.t('createdNewModel')}<a href="${record.Action.RepoLink}/modelmanage/show_model_info?name=${record.Action.RefName}" rel="nofollow">${record.Action.RefName}</a>`;
break;
case 34: // 完成微信扫码验证 - 首次绑定微信奖励
case 'BindWechat': // 完成微信扫码验证 - 首次绑定微信奖励
out.remark = `${i18n.t('firstBindingWechatRewards')}`;
break;
case 35: // 每日运行云脑任务 - 创建了(CPU/GPU/NPU)类型(调试/训练/推理/评测)任务tangl202204131431995
case 'CreateCloudbrainTask': // 每日运行云脑任务 - 创建了(CPU/GPU/NPU)类型(调试/训练/推理/评测)任务tangl202204131431995
out.remark = `${i18n.t('created')}${record.Action?.Cloudbrain?.ComputeResource}${i18n.t('type')}${getJobType(record.Action?.Cloudbrain?.JobType)} <a href="${getJobTypeLink(record, 'INCREASE')}" rel="nofollow">${record.Action.RefName}</a>`;
break;
case 36: // 数据集被平台推荐 - 数据集XXX被设置为推荐数据集
case 'DatasetRecommended': // 数据集被平台推荐 - 数据集XXX被设置为推荐数据集
out.remark = `${i18n.t('dataset')}<a href="${record.Action.RepoLink}/datasets" rel="nofollow">${record.Action.Content && record.Action.Content.split('|')[1]}</a>${i18n.t('setAsRecommendedDataset')}`;
break;
case 37: // 提交新公开镜像 - 提交了镜像jiangxiang_ceshi_tang03
case 'CreateImage': // 提交新公开镜像 - 提交了镜像jiangxiang_ceshi_tang03
out.remark = `${i18n.t('committedImage')}<span style="font-weight:bold;">${record.Action.Content && record.Action.Content.split('|')[1]}</span>`;
break;
case 38: // 镜像被平台推荐 - 镜像XXX被设置为推荐镜像
case 'ImageRecommend': // 镜像被平台推荐 - 镜像XXX被设置为推荐镜像
out.remark = `${i18n.t('image')}<span style="font-weight:bold;">${record.Action.Content && record.Action.Content.split('|')[1]}</span>${i18n.t('setAsRecommendedImage')}`;
break;
case 39: // 首次更换头像 - 更新了头像
case 'ChangeUserAvatar': // 首次更换头像 - 更新了头像
out.remark = `${i18n.t('updatedAvatar')}`;
break;
case 40: // 每日commit - 推送了xxxx分支的代码到OpenI/aiforge
const words = record.Action.RefName.split('/');
const branch = words[words.length - 1];
out.remark = `${i18n.t('pushedBranch', {
branch: `<a href="${record.Action.RepoLink}/src/branch/${branch}" rel="nofollow">${branch}</a>`
})}<a href="${record.Action.RepoLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}</a>`;
case 'PushCommits': // 每日commit - 推送了xxxx分支的代码到OpenI/aiforge
const opType = record.Action.OpType;
if (opType == 5) {
const words = record.Action.RefName.split('/');
const branch = words[words.length - 1];
out.remark = `${i18n.t('pushedBranch', {
branch: `<a href="${record.Action.RepoLink}/src/branch/${branch}" rel="nofollow">${branch}</a>`
})}<a href="${record.Action.RepoLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}</a>`;
} else if (opType == 9) {
const words = record.Action.RefName.split('/');
const tag = words[words.length - 1];
out.remark = `${i18n.t('pushedTag', {
tag: `<a href="${record.Action.RepoLink}/src/tag/${tag}" rel="nofollow">${tag}</a>`
})}<a href="${record.Action.RepoLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}</a>`;
} else if (opType == 16) {
const words = record.Action.RefName.split('/');
const tag = words[words.length - 1];
out.remark = `${i18n.t('deleteTag', {
repo: `<a href="${record.Action.RepoLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}</a>`,
tag: tag,
})}`;
} else if (opType == 17) {
const words = record.Action.RefName.split('/');
const branch = words[words.length - 1];
out.remark = `${i18n.t('deleteBranch', {
repo: `<a href="${record.Action.RepoLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}</a>`,
branch: branch,
})}`;
}
break;
default:
break;
@@ -145,15 +170,10 @@ export const getRewardPointRecordInfo = (record) => {
} else if (record.SourceType === 'ACCOMPLISH_TASK') {
//
} else if (record.SourceType === 'RUN_CLOUDBRAIN_TASK') {
out.taskName = `<a href="${getJobTypeLink(record, 'DECREASE')}" rel="nofollow">${record?.Cloudbrain?.DisplayJobName}</a>`;
// if (record?.Cloudbrain?.ComputeResource === 'CPU/GPU') {
// const resourceSpec = record?.Cloudbrain?.ResourceSpec?.ResourceSpec;
// out.remark = `【${getJobType(record?.Cloudbrain?.JobType)}】【${record?.Cloudbrain?.ComputeResource}】【GPU: ${resourceSpec?.gpu}, CPU: ${resourceSpec?.cpu}, ${i18n.t('memory')}: ${(resourceSpec?.memMiB / 1024).toFixed(2)}GB, ${i18n.t('sharedMemory')}: ${(resourceSpec?.shareMemMiB / 1024).toFixed(2)}GB】`;
// } else {
// out.remark = `【${getJobType(record?.Cloudbrain?.JobType)}】【${record?.Cloudbrain?.ComputeResource}】【${record?.Cloudbrain?.ResourceSpec.FlavorInfo.desc}】`;
// }
out.taskName = `<a href="${getJobTypeLink(record, 'DECREASE')}" rel="nofollow">${record?.Cloudbrain?.DisplayJobName}</a>`;
const resourceSpec = record?.Cloudbrain?.ResourceSpec;
if (resourceSpec) {
resourceSpec.workServerNumber = record?.Cloudbrain?.WorkServerNumber || 1;
out.remark = `【${getJobType(record?.Cloudbrain?.JobType)}】【${renderSpecStr(resourceSpec, true)}】`;
}
}


Loading…
Cancel
Save