diff --git a/.gitignore b/.gitignore index 9f34fea2aa..ceeeaa92cf 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,7 @@ coverage.all !/custom/conf/templates /custom/conf/app.ini !/custom/conf/app.ini.sample +/custom/public/kanban /data /indexers /log diff --git a/README.md b/README.md index 99f6a6e8c5..1d9ab8d066 100644 --- a/README.md +++ b/README.md @@ -54,4 +54,7 @@ ## 平台引用 如果本平台对您的科研工作提供了帮助,可在论文致谢中加入: 英文版:```Thanks for the support provided by OpenI Community (https://git.openi.org.cn).``` -中文版:```感谢启智社区提供的技术支持(https://git.openi.org.cn)。``` \ No newline at end of file +中文版:```感谢启智社区提供的技术支持(https://git.openi.org.cn)。``` + +如果您的成果中引用了本平台,也欢迎在下述开源项目中提交您的成果信息: +https://git.openi.org.cn/OpenIOSSG/references diff --git a/models/cloudbrain.go b/models/cloudbrain.go index 7de126f0bd..5091a87626 100755 --- a/models/cloudbrain.go +++ b/models/cloudbrain.go @@ -137,6 +137,8 @@ type Cloudbrain struct { Type int `xorm:"INDEX"` BenchmarkTypeID int BenchmarkChildTypeID int + CardType string + Cluster string VersionID int64 //版本id VersionName string `xorm:"INDEX"` //当前版本 @@ -206,7 +208,16 @@ func (task *Cloudbrain) CorrectCreateUnix() { func (task *Cloudbrain) IsTerminal() bool { status := task.Status - return status == string(ModelArtsTrainJobCompleted) || status == string(ModelArtsTrainJobFailed) || status == string(ModelArtsTrainJobKilled) || status == string(ModelArtsStopped) || status == string(JobStopped) || status == string(JobFailed) || status == string(JobSucceeded) + return status == string(ModelArtsTrainJobCompleted) || status == string(ModelArtsTrainJobFailed) || + status == string(ModelArtsTrainJobKilled) || status == string(ModelArtsStopped) || + status == string(JobStopped) || status == string(JobFailed) || + status == string(JobSucceeded) || status == GrampusStatusFailed || + status == GrampusStatusSucceeded || status == GrampusStatusStopped +} +func (task *Cloudbrain) IsRunning() bool { + status := task.Status + return status == string(ModelArtsTrainJobRunning) || status == string(ModelArtsRunning) || + status == string(JobRunning) || status == GrampusStatusRunning } func ConvertDurationToStr(duration int64) string { @@ -1669,6 +1680,37 @@ func GetCloudbrainsNeededStopByUserID(userID int64) ([]*Cloudbrain, error) { return cloudBrains, err } +func GetWaittingTop() ([]*CloudbrainInfo, error) { + sess := x.NewSession() + defer sess.Close() + var cond = builder.NewCond() + cond = cond.And( + builder.Eq{"cloudbrain.status": string(JobWaiting)}, + ) + sess.OrderBy("cloudbrain.created_unix ASC limit 1") + cloudbrains := make([]*CloudbrainInfo, 0, 1) + if err := sess.Table(&Cloudbrain{}).Where(cond). + Find(&cloudbrains); err != nil { + log.Info("find error.") + } + return cloudbrains, nil +} +func GetModelartsReDebugTaskByJobId(jobID string) ([]*Cloudbrain, error) { + sess := x.NewSession() + defer sess.Close() + var cond = builder.NewCond() + cond = cond.And( + builder.Eq{"cloudbrain.job_id": jobID}, + ) + sess.OrderBy("cloudbrain.created_unix ASC limit 1") + cloudbrains := make([]*Cloudbrain, 0, 10) + if err := sess.Table(&Cloudbrain{}).Unscoped().Where(cond). + Find(&cloudbrains); err != nil { + log.Info("find error.") + } + return cloudbrains, nil +} + func GetCloudbrainsNeededStopByRepoID(repoID int64) ([]*Cloudbrain, error) { cloudBrains := make([]*Cloudbrain, 0) err := x.Cols("job_id", "status", "type", "job_type", "version_id", "start_time").Where("repo_id=? AND status !=?", repoID, string(JobStopped)).Find(&cloudBrains) @@ -1918,7 +1960,8 @@ func CloudbrainAll(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { } if (opts.IsLatestVersion) != "" { - cond = cond.And(builder.Or(builder.And(builder.Eq{"cloudbrain.is_latest_version": opts.IsLatestVersion}, builder.Eq{"cloudbrain.job_type": "TRAIN"}), builder.Neq{"cloudbrain.job_type": "TRAIN"})) + cond = cond.And(builder.Or(builder.And(builder.Eq{"cloudbrain.is_latest_version": opts.IsLatestVersion}, + builder.Eq{"cloudbrain.job_type": "TRAIN"}), builder.Neq{"cloudbrain.job_type": "TRAIN"})) } if len(opts.CloudbrainIDs) > 0 { @@ -1956,7 +1999,8 @@ func CloudbrainAll(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { } else { lowerKeyWord := strings.ToLower(opts.Keyword) - cond = cond.And(builder.Or(builder.Like{"LOWER(cloudbrain.job_name)", lowerKeyWord}, builder.Like{"LOWER(cloudbrain.display_job_name)", lowerKeyWord}, builder.Like{"`user`.lower_name", lowerKeyWord})) + cond = cond.And(builder.Or(builder.Like{"LOWER(cloudbrain.job_name)", lowerKeyWord}, + builder.Like{"LOWER(cloudbrain.display_job_name)", lowerKeyWord}, builder.Like{"`user`.lower_name", lowerKeyWord})) count, err = sess.Table(&Cloudbrain{}).Unscoped().Where(cond). Join("left", "`user`", condition).Count(new(CloudbrainInfo)) @@ -2034,7 +2078,8 @@ func CloudbrainAllStatic(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, er } sess.OrderBy("cloudbrain.created_unix DESC") cloudbrains := make([]*CloudbrainInfo, 0, setting.UI.IssuePagingNum) - if err := sess.Cols("status", "type", "job_type", "train_job_duration", "duration", "compute_resource", "created_unix", "start_time", "end_time").Table(&Cloudbrain{}).Unscoped().Where(cond). + if err := sess.Cols("status", "type", "job_type", "train_job_duration", "duration", "compute_resource", + "created_unix", "start_time", "end_time").Table(&Cloudbrain{}).Unscoped().Where(cond). Find(&cloudbrains); err != nil { return nil, 0, fmt.Errorf("Find: %v", err) } @@ -2089,6 +2134,112 @@ func GetDatasetInfo(uuidStr string) (map[string]DatasetInfo, string, error) { return datasetInfos, datasetNames, nil } +var ( + SpecsMapInitFlag = false + CloudbrainDebugResourceSpecsMap map[int]*ResourceSpec + CloudbrainTrainResourceSpecsMap map[int]*ResourceSpec + CloudbrainInferenceResourceSpecsMap map[int]*ResourceSpec + CloudbrainBenchmarkResourceSpecsMap map[int]*ResourceSpec + CloudbrainSpecialResourceSpecsMap map[int]*ResourceSpec + GpuInfosMapInitFlag = false + CloudbrainDebugGpuInfosMap map[string]*GpuInfo + CloudbrainTrainGpuInfosMap map[string]*GpuInfo + CloudbrainInferenceGpuInfosMap map[string]*GpuInfo + CloudbrainBenchmarkGpuInfosMap map[string]*GpuInfo + CloudbrainSpecialGpuInfosMap map[string]*GpuInfo +) + +func InitCloudbrainOneResourceSpecMap() { + if CloudbrainDebugResourceSpecsMap == nil || len(CloudbrainDebugResourceSpecsMap) == 0 { + t := ResourceSpecs{} + json.Unmarshal([]byte(setting.ResourceSpecs), &t) + CloudbrainDebugResourceSpecsMap = make(map[int]*ResourceSpec, len(t.ResourceSpec)) + for _, spec := range t.ResourceSpec { + CloudbrainDebugResourceSpecsMap[spec.Id] = spec + } + } + if CloudbrainTrainResourceSpecsMap == nil || len(CloudbrainTrainResourceSpecsMap) == 0 { + t := ResourceSpecs{} + json.Unmarshal([]byte(setting.TrainResourceSpecs), &t) + CloudbrainTrainResourceSpecsMap = make(map[int]*ResourceSpec, len(t.ResourceSpec)) + for _, spec := range t.ResourceSpec { + CloudbrainTrainResourceSpecsMap[spec.Id] = spec + } + } + if CloudbrainInferenceResourceSpecsMap == nil || len(CloudbrainInferenceResourceSpecsMap) == 0 { + t := ResourceSpecs{} + json.Unmarshal([]byte(setting.InferenceResourceSpecs), &t) + CloudbrainInferenceResourceSpecsMap = make(map[int]*ResourceSpec, len(t.ResourceSpec)) + for _, spec := range t.ResourceSpec { + CloudbrainInferenceResourceSpecsMap[spec.Id] = spec + } + } + if CloudbrainBenchmarkResourceSpecsMap == nil || len(CloudbrainBenchmarkResourceSpecsMap) == 0 { + t := ResourceSpecs{} + json.Unmarshal([]byte(setting.BenchmarkResourceSpecs), &t) + CloudbrainBenchmarkResourceSpecsMap = make(map[int]*ResourceSpec, len(t.ResourceSpec)) + for _, spec := range t.ResourceSpec { + CloudbrainBenchmarkResourceSpecsMap[spec.Id] = spec + } + } + if CloudbrainSpecialResourceSpecsMap == nil || len(CloudbrainSpecialResourceSpecsMap) == 0 { + t := SpecialPools{} + json.Unmarshal([]byte(setting.SpecialPools), &t) + for _, pool := range t.Pools { + CloudbrainSpecialResourceSpecsMap = make(map[int]*ResourceSpec, len(pool.ResourceSpec)) + for _, spec := range pool.ResourceSpec { + CloudbrainSpecialResourceSpecsMap[spec.Id] = spec + } + } + } + SpecsMapInitFlag = true +} + +func InitCloudbrainOneGpuInfoMap() { + if CloudbrainDebugGpuInfosMap == nil || len(CloudbrainDebugGpuInfosMap) == 0 { + t := GpuInfos{} + json.Unmarshal([]byte(setting.GpuTypes), &t) + CloudbrainDebugGpuInfosMap = make(map[string]*GpuInfo, len(t.GpuInfo)) + for _, GpuInfo := range t.GpuInfo { + CloudbrainDebugGpuInfosMap[GpuInfo.Queue] = GpuInfo + } + } + if CloudbrainTrainGpuInfosMap == nil || len(CloudbrainTrainGpuInfosMap) == 0 { + t := GpuInfos{} + json.Unmarshal([]byte(setting.TrainGpuTypes), &t) + CloudbrainTrainGpuInfosMap = make(map[string]*GpuInfo, len(t.GpuInfo)) + for _, GpuInfo := range t.GpuInfo { + CloudbrainTrainGpuInfosMap[GpuInfo.Queue] = GpuInfo + } + } + if CloudbrainInferenceGpuInfosMap == nil || len(CloudbrainInferenceGpuInfosMap) == 0 { + t := GpuInfos{} + json.Unmarshal([]byte(setting.InferenceGpuTypes), &t) + CloudbrainInferenceGpuInfosMap = make(map[string]*GpuInfo, len(t.GpuInfo)) + for _, GpuInfo := range t.GpuInfo { + CloudbrainInferenceGpuInfosMap[GpuInfo.Queue] = GpuInfo + } + } + if CloudbrainBenchmarkGpuInfosMap == nil || len(CloudbrainBenchmarkGpuInfosMap) == 0 { + t := GpuInfos{} + json.Unmarshal([]byte(setting.BenchmarkGpuTypes), &t) + CloudbrainBenchmarkGpuInfosMap = make(map[string]*GpuInfo, len(t.GpuInfo)) + for _, GpuInfo := range t.GpuInfo { + CloudbrainBenchmarkGpuInfosMap[GpuInfo.Queue] = GpuInfo + } + } + if CloudbrainSpecialGpuInfosMap == nil || len(CloudbrainSpecialGpuInfosMap) == 0 { + t := SpecialPools{} + json.Unmarshal([]byte(setting.SpecialPools), &t) + for _, pool := range t.Pools { + CloudbrainSpecialGpuInfosMap = make(map[string]*GpuInfo, len(pool.Pool)) + for _, GpuInfo := range pool.Pool { + CloudbrainSpecialGpuInfosMap[GpuInfo.Queue] = GpuInfo + } + } + } + GpuInfosMapInitFlag = true +} func GetNewestJobsByAiCenter() ([]int64, error) { ids := make([]int64, 0) return ids, x. diff --git a/models/cloudbrain_static.go b/models/cloudbrain_static.go index 03cd7d2bc3..e3ac5e9632 100644 --- a/models/cloudbrain_static.go +++ b/models/cloudbrain_static.go @@ -29,6 +29,11 @@ type TaskDetail struct { RepoAlias string `json:"RepoAlias"` RepoID int64 `json:"RepoID"` IsDelete bool `json:"IsDelete"` + CardNum int `json:"CardNum"` + CardType string `json:"CardType"` + CardDuration string `json:"CardDuration"` + AiCenter string `json:"AiCenter"` + FlavorName string `json:"FlavorName"` } func GetDebugOnePeriodCount(beginTime time.Time, endTime time.Time) (int64, error) { @@ -206,21 +211,6 @@ func GetAllStatusCloudBrain() map[string]int { return cloudBrainStatusResult } -func GetWaittingTop() ([]*CloudbrainInfo, error) { - sess := x.NewSession() - defer sess.Close() - var cond = builder.NewCond() - cond = cond.And( - builder.Eq{"cloudbrain.status": string(JobWaiting)}, - ) - sess.OrderBy("cloudbrain.created_unix ASC limit 10") - cloudbrains := make([]*CloudbrainInfo, 0, 10) - if err := sess.Table(&Cloudbrain{}).Where(cond). - Find(&cloudbrains); err != nil { - log.Info("find error.") - } - return cloudbrains, nil -} func GetRunningTop() ([]*CloudbrainInfo, error) { sess := x.NewSession() defer sess.Close() diff --git a/models/dbsql/dataset_foreigntable_for_es.sql b/models/dbsql/dataset_foreigntable_for_es.sql index 02e5f0ddf6..4a0cae70e0 100644 --- a/models/dbsql/dataset_foreigntable_for_es.sql +++ b/models/dbsql/dataset_foreigntable_for_es.sql @@ -158,16 +158,20 @@ DROP TRIGGER IF EXISTS es_update_dataset on public.dataset; CREATE OR REPLACE FUNCTION public.update_dataset() RETURNS trigger AS $def$ BEGIN - UPDATE public.dataset_es - SET description=NEW.description, - title=NEW.title, - category=NEW.category, - task=NEW.task, - download_times=NEW.download_times, - updated_unix=NEW.updated_unix, - file_name=(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.id and is_private=false), - file_desc=(select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.id and is_private=false) - where id=NEW.id; + if (NEW.status=0) then + delete from public.dataset_es where id=NEW.id; + elsif (NEW.status=1) then + UPDATE public.dataset_es + SET description=NEW.description, + title=NEW.title, + category=NEW.category, + task=NEW.task, + download_times=NEW.download_times, + updated_unix=NEW.updated_unix, + file_name=(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.id and is_private=false), + file_desc=(select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.id and is_private=false) + where id=NEW.id; + end if; return new; END $def$ diff --git a/models/dbsql/repo_foreigntable_for_es.sql b/models/dbsql/repo_foreigntable_for_es.sql index e927eb7c29..82c8781af1 100644 --- a/models/dbsql/repo_foreigntable_for_es.sql +++ b/models/dbsql/repo_foreigntable_for_es.sql @@ -461,7 +461,7 @@ $def$ if not OLD.is_private and NEW.is_private then delete from public.issue_es where repo_id=NEW.id; - delete from public.dataset_es where repo_id=NEW.id; + -- delete from public.dataset_es where repo_id=NEW.id; delete from public.repository_es where id=NEW.id; end if; diff --git a/models/repo.go b/models/repo.go index 4770e5415b..feb6fd3ef6 100755 --- a/models/repo.go +++ b/models/repo.go @@ -1603,13 +1603,6 @@ func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err e if err != nil { return err } - //If repo has become private, we need set dataset and dataset_file to private - _, err = e.Where("repo_id = ? and status <> 2", repo.ID).Cols("status").Update(&Dataset{ - Status: 0, - }) - if err != nil { - return err - } dataset, err := GetDatasetByRepo(repo) if err != nil && !IsErrNotExist(err) { @@ -1624,6 +1617,14 @@ func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err e } } + //If repo has become private, we need set dataset and dataset_file to private + _, err = e.Where("repo_id = ? and status <> 2", repo.ID).Cols("status").Update(&Dataset{ + Status: 0, + }) + if err != nil { + return err + } + } else { //If repo has become public, we need set dataset to public _, err = e.Where("repo_id = ? and status <> 2", repo.ID).Cols("status").Update(&Dataset{ diff --git a/models/repo_activity_custom.go b/models/repo_activity_custom.go index 6e7921d754..b6fffca0ee 100644 --- a/models/repo_activity_custom.go +++ b/models/repo_activity_custom.go @@ -238,6 +238,9 @@ func GetAllUserPublicRepoKPIStats(startTime time.Time, endTime time.Time) (map[s CommitLines: 0, } } + if value.Email == "1250125907@qq.com" || value.Email == "peiyongyu-34@163.com" { + log.Info("repo path=" + repository.RepoPath()) + } authors[key].Commits += value.Commits authors[key].CommitLines += value.CommitLines diff --git a/models/user_analysis_for_activity.go b/models/user_analysis_for_activity.go index e69eecae0b..2066697d28 100644 --- a/models/user_analysis_for_activity.go +++ b/models/user_analysis_for_activity.go @@ -6,6 +6,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" + "xorm.io/builder" ) type UserBusinessAnalysisForActivity struct { @@ -195,7 +196,7 @@ func queryPullRequestPublic(start_unix int64, end_unix int64, publicAllRepo map[ sess := x.NewSession() defer sess.Close() resultMap := make(map[int64]int) - cond := "pull_request.merged_unix>=" + fmt.Sprint(start_unix) + " and pull_request.merged_unix<=" + fmt.Sprint(end_unix) + cond := "issue.created_unix>=" + fmt.Sprint(start_unix) + " and issue.created_unix<=" + fmt.Sprint(end_unix) count, err := sess.Table("issue").Join("inner", "pull_request", "issue.id=pull_request.issue_id").Where(cond).Count(new(Issue)) if err != nil { log.Info("query issue error. return.") @@ -435,3 +436,16 @@ func queryUserModelPublic(start_unix int64, end_unix int64, publicAllRepo map[in } return resultMap } + +func QueryUserLoginInfo(userIds []int64) []*UserLoginLog { + statictisSess := xStatistic.NewSession() + defer statictisSess.Close() + var cond = builder.NewCond() + cond = cond.And(builder.In("u_id", userIds)) + statictisSess.Select("*").Table(new(UserLoginLog)).Where(cond) + loginList := make([]*UserLoginLog, 0) + + statictisSess.Find(&loginList) + + return loginList +} diff --git a/models/user_business_analysis.go b/models/user_business_analysis.go index 47036e2e94..a36bd47363 100644 --- a/models/user_business_analysis.go +++ b/models/user_business_analysis.go @@ -110,9 +110,9 @@ type UserBusinessAnalysisAll struct { } type UserBusinessAnalysis struct { - ID int64 `xorm:"pk"` - - CountDate int64 `xorm:"pk"` + ID int64 `xorm:"pk"` + DataDate string `xorm:"pk"` + CountDate int64 `xorm:"NULL"` //action :ActionMergePullRequest // 11 CodeMergeCount int `xorm:"NOT NULL DEFAULT 0"` @@ -171,8 +171,6 @@ type UserBusinessAnalysis struct { //user Name string `xorm:"NOT NULL"` - DataDate string `xorm:"NULL"` - CloudBrainTaskNum int `xorm:"NOT NULL DEFAULT 0"` GpuDebugJob int `xorm:"NOT NULL DEFAULT 0"` NpuDebugJob int `xorm:"NOT NULL DEFAULT 0"` @@ -411,6 +409,42 @@ func QueryUserStaticDataAll(opts *UserBusinessAnalysisQueryOptions) ([]*UserBusi return userBusinessAnalysisReturnList, allCount } +func QueryDataForUserDefineFromDb(opts *UserBusinessAnalysisQueryOptions, key string) ([]*UserBusinessAnalysis, int64) { + statictisSess := xStatistic.NewSession() + defer statictisSess.Close() + cond := "data_date='" + key + "'" + allCount, err := statictisSess.Where(cond).Count(new(UserBusinessAnalysis)) + if err == nil { + if allCount > 0 { + userBusinessAnalysisList := make([]*UserBusinessAnalysis, 0) + if err := statictisSess.Table("user_business_analysis").Where(cond).OrderBy("id desc").Limit(opts.PageSize, (opts.Page-1)*opts.PageSize). + Find(&userBusinessAnalysisList); err != nil { + return nil, 0 + } + return userBusinessAnalysisList, allCount + } + } + return nil, 0 +} + +func WriteDataToDb(dataList []*UserBusinessAnalysis, key string) { + statictisSess := xStatistic.NewSession() + defer statictisSess.Close() + log.Info("write to db, size=" + fmt.Sprint(len(dataList))) + userBusinessAnalysisList := make([]*UserBusinessAnalysis, 0) + for _, data := range dataList { + data.DataDate = key + userBusinessAnalysisList = append(userBusinessAnalysisList, data) + if len(userBusinessAnalysisList) > BATCH_INSERT_SIZE { + statictisSess.Insert(userBusinessAnalysisList) + userBusinessAnalysisList = make([]*UserBusinessAnalysis, 0) + } + } + if len(userBusinessAnalysisList) > 0 { + statictisSess.Insert(userBusinessAnalysisList) + } +} + func QueryUserStaticDataForUserDefine(opts *UserBusinessAnalysisQueryOptions, wikiCountMap map[string]int) ([]*UserBusinessAnalysis, int64) { log.Info("start to count other user info data") sess := x.NewSession() @@ -954,6 +988,9 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time, statictisSess := xStatistic.NewSession() defer statictisSess.Close() + log.Info("truncate all data from table:user_business_analysis ") + statictisSess.Exec("TRUNCATE TABLE user_business_analysis") + cond := "type != 1" count, err := sess.Where(cond).Count(new(User)) if err != nil { @@ -1103,6 +1140,7 @@ func updateNewUserAcitivity(currentUserActivity map[int64]map[int64]int64, userA ",activate_regist_user=" + fmt.Sprint(useMetrics.ActivateRegistUser) + ",not_activate_regist_user=" + fmt.Sprint(useMetrics.CurrentDayRegistUser-useMetrics.ActivateRegistUser) + ",current_day_regist_user=" + fmt.Sprint(useMetrics.CurrentDayRegistUser) + + ",activate_index=" + fmt.Sprint(float64(useMetrics.ActivateRegistUser)/float64(useMetrics.CurrentDayRegistUser)) + ",data_date='" + time.Unix(key, 0).Format("2006-01-02") + "'" + " where count_date=" + fmt.Sprint(key) diff --git a/modules/auth/cloudbrain.go b/modules/auth/cloudbrain.go index 160328b5b5..39685990d1 100755 --- a/modules/auth/cloudbrain.go +++ b/modules/auth/cloudbrain.go @@ -23,6 +23,7 @@ type CreateCloudBrainForm struct { BootFile string `form:"boot_file"` Params string `form:"run_para_list"` BranchName string `form:"branch_name"` + DatasetName string `form:"dataset_name"` } type CommitImageCloudBrainForm struct { @@ -70,6 +71,7 @@ type CreateCloudBrainInferencForm struct { ModelVersion string `form:"model_version" binding:"Required"` CkptName string `form:"ckpt_name" binding:"Required"` LabelName string `form:"label_names" binding:"Required"` + DatasetName string `form:"dataset_name"` } func (f *CreateCloudBrainForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { diff --git a/modules/auth/grampus.go b/modules/auth/grampus.go index ebf0defde0..0338d2ae7c 100755 --- a/modules/auth/grampus.go +++ b/modules/auth/grampus.go @@ -19,6 +19,7 @@ type CreateGrampusTrainJobForm struct { EngineName string `form:"engine_name" binding:"Required"` WorkServerNumber int `form:"work_server_number" binding:"Required"` Image string `form:"image"` + DatasetName string `form:"dataset_name"` } func (f *CreateGrampusTrainJobForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { diff --git a/modules/auth/wechat/client.go b/modules/auth/wechat/client.go index 9ed4b543f8..bb6db09d09 100644 --- a/modules/auth/wechat/client.go +++ b/modules/auth/wechat/client.go @@ -19,6 +19,7 @@ const ( ACCESS_TOKEN_PATH = "/cgi-bin/token" QR_CODE_PATH = "/cgi-bin/qrcode/create" GET_MATERIAL_PATH = "/cgi-bin/material/batchget_material" + SEND_TEMPLATE_PATH = "/cgi-bin/message/template/send" ACTION_QR_STR_SCENE = "QR_STR_SCENE" ERR_CODE_ACCESSTOKEN_EXPIRE = 42001 @@ -41,12 +42,33 @@ type QRCodeRequest struct { Action_info ActionInfo `json:"action_info"` Expire_seconds int `json:"expire_seconds"` } + type MaterialRequest struct { Type string `json:"type"` Offset int `json:"offset"` Count int `json:"count"` } +type TemplateMsgRequest struct { + ToUser string `json:"touser"` + TemplateId string `json:"template_id"` + Url string `json:"url"` + ClientMsgId string `json:"client_msg_id"` + Data interface{} `json:"data"` +} +type TemplateValue struct { + Value string `json:"value"` + Color string `json:"color"` +} + +type CloudbrainTaskData struct { + First TemplateValue `json:"first"` + Keyword1 TemplateValue `json:"keyword1"` + Keyword2 TemplateValue `json:"keyword2"` + Keyword3 TemplateValue `json:"keyword3"` + Remark TemplateValue `json:"remark"` +} + type ActionInfo struct { Scene Scene `json:"scene"` } @@ -161,3 +183,27 @@ func getErrorCodeFromResponse(r *resty.Response) int { c, _ := strconv.Atoi(fmt.Sprint(code)) return c } + +func sendTemplateMsg(req TemplateMsgRequest) (error, bool) { + client := getWechatRestyClient() + + bodyJson, _ := json.Marshal(req) + r, err := client.R(). + SetHeader("Content-Type", "application/json"). + SetQueryParam("access_token", GetWechatAccessToken()). + SetBody(bodyJson). + Post(setting.WechatApiHost + SEND_TEMPLATE_PATH) + if err != nil { + log.Error("sendTemplateMsg,e=%v", err) + return nil, false + } + a := r.Body() + resultMap := make(map[string]interface{}, 0) + json.Unmarshal(a, &resultMap) + errcode := resultMap["errcode"] + log.Info("sendTemplateMsg,%v", r) + if errcode == fmt.Sprint(ERR_CODE_ACCESSTOKEN_EXPIRE) || errcode == fmt.Sprint(ERR_CODE_ACCESSTOKEN_INVALID) { + return nil, true + } + return nil, false +} diff --git a/modules/auth/wechat/template.go b/modules/auth/wechat/template.go new file mode 100644 index 0000000000..6c19651a66 --- /dev/null +++ b/modules/auth/wechat/template.go @@ -0,0 +1,145 @@ +package wechat + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "errors" + "fmt" + "time" +) + +type JobOperateType string + +const ( + JobOperateTypeStart JobOperateType = "start" + JobOperateTypeStop JobOperateType = "stop" +) + +func GetJobOperateTypeFromCloudbrainStatus(cloudbrain *models.Cloudbrain) JobOperateType { + if cloudbrain.IsTerminal() { + return JobOperateTypeStop + } + if cloudbrain.IsRunning() { + return JobOperateTypeStart + } + return "" +} + +func SendCloudbrainStartedMsg(operateType JobOperateType, cloudbrain models.Cloudbrain) error { + defer func() { + if err := recover(); err != nil { + combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2)) + log.Error("PANIC:", combinedErr) + } + }() + repo, err := models.GetRepositoryByID(cloudbrain.RepoID) + if err != nil { + log.Error("SendCloudbrainStartedMsg GetRepositoryByID error,%v", err) + } + + if setting.CloudbrainStartedTemplateId == "" { + return nil + } + + openId := models.GetUserWechatOpenId(cloudbrain.UserID) + if openId == "" { + return errors.New("Wechat openId not exist") + } + data := CloudbrainTaskData{ + First: TemplateValue{Value: getCloudbrainTemplateTitle(operateType)}, + Keyword1: TemplateValue{Value: cloudbrain.DisplayJobName}, + Keyword2: TemplateValue{Value: getJobTypeDisplayName(cloudbrain.JobType)}, + Keyword3: TemplateValue{Value: time.Unix(int64(cloudbrain.CreatedUnix), 0).Format("2006-01-02 15:04:05")}, + Remark: TemplateValue{Value: getCloudbrainTemplateRemark(operateType)}, + } + req := TemplateMsgRequest{ + ToUser: openId, + TemplateId: setting.CloudbrainStartedTemplateId, + Url: getCloudbrainTemplateUrl(cloudbrain, repo), + ClientMsgId: string(operateType) + "_" + fmt.Sprint(cloudbrain.ID), + Data: data, + } + err, retryFlag := sendTemplateMsg(req) + if retryFlag { + log.Info("retrySendCloudbrainTemplateMsg calling") + refreshAccessToken() + err, _ = sendTemplateMsg(req) + if err != nil { + log.Error("SendCloudbrainStartedMsg err. %v", err) + return err + } + return nil + } + if err != nil { + log.Error("SendCloudbrainStartedMsg err. %v", err) + return err + } + return nil +} + +func getCloudbrainTemplateUrl(cloudbrain models.Cloudbrain, repo *models.Repository) string { + url := setting.AppURL + repo.FullName() + + switch cloudbrain.JobType { + case string(models.JobTypeDebug): + if cloudbrain.ComputeResource == "CPU/GPU" { + url += "/cloudbrain/" + fmt.Sprint(cloudbrain.ID) + } else { + url += "/modelarts/notebook/" + fmt.Sprint(cloudbrain.ID) + } + case string(models.JobTypeBenchmark): + url += "/cloudbrain/benchmark/" + fmt.Sprint(cloudbrain.ID) + case string(models.JobTypeTrain): + if cloudbrain.Type == models.TypeCloudBrainOne { + url += "/cloudbrain/train-job/" + fmt.Sprint(cloudbrain.JobID) + } else if cloudbrain.Type == models.TypeCloudBrainTwo { + url += "/modelarts/train-job/" + fmt.Sprint(cloudbrain.JobID) + } else if cloudbrain.Type == models.TypeC2Net { + url += "/grampus/train-job/" + fmt.Sprint(cloudbrain.JobID) + } + case string(models.JobTypeInference): + url += "/modelarts/inference-job/" + fmt.Sprint(cloudbrain.JobID) + } + return url +} + +func getCloudbrainTemplateTitle(operateType JobOperateType) string { + var title string + switch operateType { + case JobOperateTypeStart: + title = "您好,您提交的算力资源申请已通过,任务已启动,请您关注运行情况。" + case JobOperateTypeStop: + title = "您好,您提交的任务已运行结束。" + } + + return title + +} + +func getCloudbrainTemplateRemark(operateType JobOperateType) string { + var remark string + switch operateType { + case JobOperateTypeStart: + remark = "感谢您的耐心等待。" + case JobOperateTypeStop: + remark = "点击可查看运行结果" + } + + return remark + +} + +func getJobTypeDisplayName(jobType string) string { + switch jobType { + case string(models.JobTypeDebug): + return "调试任务" + case string(models.JobTypeBenchmark): + return "评测任务" + case string(models.JobTypeTrain): + return "训练任务" + case string(models.JobTypeInference): + return "推理任务" + } + return "" +} diff --git a/modules/cloudbrain/cloudbrain.go b/modules/cloudbrain/cloudbrain.go index 6cbb97999f..1872375da6 100755 --- a/modules/cloudbrain/cloudbrain.go +++ b/modules/cloudbrain/cloudbrain.go @@ -326,7 +326,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { ReadOnly: true, }, }) - } else { + } else if len(req.DatasetInfos) > 1 { for _, dataset := range req.DatasetInfos { volumes = append(volumes, models.Volume{ HostPath: models.StHostPath{ @@ -466,11 +466,14 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e log.Error("no such resourceSpecId(%d)", task.ResourceSpecId, ctx.Data["MsgID"]) return errors.New("no such resourceSpec") } - - datasetInfos, _, err := models.GetDatasetInfo(task.Uuid) - if err != nil { - log.Error("GetDatasetInfo failed:%v", err, ctx.Data["MsgID"]) - return err + var datasetInfos map[string]models.DatasetInfo + if task.Uuid != "" { + var err error + datasetInfos, _, err = models.GetDatasetInfo(task.Uuid) + if err != nil { + log.Error("GetDatasetInfo failed:%v", err, ctx.Data["MsgID"]) + return err + } } volumes := []models.Volume{ @@ -510,24 +513,25 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e }, }, } - - if len(datasetInfos) == 1 { - volumes = append(volumes, models.Volume{ - HostPath: models.StHostPath{ - Path: datasetInfos[task.Uuid].DataLocalPath, - MountPath: DataSetMountPath, - ReadOnly: true, - }, - }) - } else { - for _, dataset := range datasetInfos { + if datasetInfos != nil { + if len(datasetInfos) == 1 { volumes = append(volumes, models.Volume{ HostPath: models.StHostPath{ - Path: dataset.DataLocalPath, - MountPath: DataSetMountPath + "/" + dataset.Name, + Path: datasetInfos[task.Uuid].DataLocalPath, + MountPath: DataSetMountPath, ReadOnly: true, }, }) + } else { + for _, dataset := range datasetInfos { + volumes = append(volumes, models.Volume{ + HostPath: models.StHostPath{ + Path: dataset.DataLocalPath, + MountPath: DataSetMountPath + "/" + dataset.Name, + ReadOnly: true, + }, + }) + } } } @@ -547,7 +551,7 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e GPUNumber: resourceSpec.GpuNum, MemoryMB: resourceSpec.MemMiB, ShmMB: resourceSpec.ShareMemMiB, - Command: GetCloudbrainDebugCommand(),//Command, + Command: GetCloudbrainDebugCommand(), //Command, NeedIBDevice: false, IsMainRole: false, UseNNI: false, diff --git a/modules/context/context.go b/modules/context/context.go index 2c935881c7..8c78084665 100755 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -6,7 +6,6 @@ package context import ( - "code.gitea.io/gitea/routers/notice" "html" "html/template" "io" @@ -16,6 +15,8 @@ import ( "strings" "time" + "code.gitea.io/gitea/routers/notice" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/base" diff --git a/modules/git/repo_stats_custom.go b/modules/git/repo_stats_custom.go index 1a7b657d51..52d91e77a5 100644 --- a/modules/git/repo_stats_custom.go +++ b/modules/git/repo_stats_custom.go @@ -62,7 +62,7 @@ func GetUserKPIStats(repoPath string, startTime time.Time, endTime time.Time) (m after := startTime.Format(time.RFC3339) until := endTime.Format(time.RFC3339) - args := []string{"log", "--numstat", "--no-merges", "--branches=*", "--pretty=format:---%n%h%n%an%n%ae%n", "--date=iso", fmt.Sprintf("--after='%s'", after), fmt.Sprintf("--until=='%s'", until)} + args := []string{"log", "--numstat", "--no-merges", "--branches=*", "--pretty=format:---%n%h%n%an%n%ae%n", "--date=iso", fmt.Sprintf("--after='%s'", after), fmt.Sprintf("--until='%s'", until)} stdout, err := NewCommand(args...).RunInDirBytes(repoPath) if err != nil { return nil, err diff --git a/modules/notification/base/notifier.go b/modules/notification/base/notifier.go index 8d6fdeb529..3bdc29d466 100644 --- a/modules/notification/base/notifier.go +++ b/modules/notification/base/notifier.go @@ -56,4 +56,6 @@ type Notifier interface { NotifySyncDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) NotifyOtherTask(doer *models.User, repo *models.Repository, id string, name string, optype models.ActionType) + + NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus string) } diff --git a/modules/notification/base/null.go b/modules/notification/base/null.go index 0d3489882d..6a24963d25 100644 --- a/modules/notification/base/null.go +++ b/modules/notification/base/null.go @@ -158,3 +158,7 @@ func (*NullNotifier) NotifySyncDeleteRef(doer *models.User, repo *models.Reposit func (*NullNotifier) NotifyOtherTask(doer *models.User, repo *models.Repository, id string, name string, optype models.ActionType) { } + +func (*NullNotifier) NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus string) { + +} diff --git a/modules/notification/notification.go b/modules/notification/notification.go index 0fd6fa4719..b6d925f07c 100644 --- a/modules/notification/notification.go +++ b/modules/notification/notification.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/modules/notification/mail" "code.gitea.io/gitea/modules/notification/ui" "code.gitea.io/gitea/modules/notification/webhook" + wechatNotifier "code.gitea.io/gitea/modules/notification/wechat" "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" ) @@ -35,6 +36,7 @@ func NewContext() { RegisterNotifier(indexer.NewNotifier()) RegisterNotifier(webhook.NewNotifier()) RegisterNotifier(action.NewNotifier()) + RegisterNotifier(wechatNotifier.NewNotifier()) } // NotifyUploadAttachment notifies attachment upload message to notifiers @@ -269,3 +271,10 @@ func NotifySyncDeleteRef(pusher *models.User, repo *models.Repository, refType, notifier.NotifySyncDeleteRef(pusher, repo, refType, refFullName) } } + +// NotifyChangeCloudbrainStatus +func NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus string) { + for _, notifier := range notifiers { + notifier.NotifyChangeCloudbrainStatus(cloudbrain, oldStatus) + } +} diff --git a/modules/notification/wechat/wechat.go b/modules/notification/wechat/wechat.go new file mode 100644 index 0000000000..f77bfe7419 --- /dev/null +++ b/modules/notification/wechat/wechat.go @@ -0,0 +1,44 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package wechat + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/auth/wechat" + "code.gitea.io/gitea/modules/notification/base" + "code.gitea.io/gitea/modules/setting" +) + +type wechatNotifier struct { + base.NullNotifier +} + +var ( + _ base.Notifier = &wechatNotifier{} +) + +// NewNotifier create a new wechatNotifier notifier +func NewNotifier() base.Notifier { + return &wechatNotifier{} +} + +func (*wechatNotifier) NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus string) { + operateType := wechat.GetJobOperateTypeFromCloudbrainStatus(cloudbrain) + if operateType == "" { + return + } + switch operateType { + case wechat.JobOperateTypeStart: + if len(setting.CloudbrainStartedNotifyList) == 0 { + return + } + for _, v := range setting.CloudbrainStartedNotifyList { + if v == cloudbrain.JobType { + go wechat.SendCloudbrainStartedMsg(operateType, *cloudbrain) + return + } + } + } +} diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 1bb54f2f57..8a8a4a0522 100755 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -583,6 +583,10 @@ var ( TreePathOfAutoMsgReply string TreePathOfSubscribe string + //wechat template msg config + CloudbrainStartedTemplateId string + CloudbrainStartedNotifyList []string + //nginx proxy PROXYURL string RadarMap = struct { @@ -1434,7 +1438,7 @@ func NewContext() { WechatApiHost = sec.Key("HOST").MustString("https://api.weixin.qq.com") WechatApiTimeoutSeconds = sec.Key("TIMEOUT_SECONDS").MustInt(3) WechatAppId = sec.Key("APP_ID").MustString("wxba77b915a305a57d") - WechatAppSecret = sec.Key("APP_SECRET").MustString("e48e13f315adc32749ddc7057585f198") + WechatAppSecret = sec.Key("APP_SECRET").MustString("") WechatQRCodeExpireSeconds = sec.Key("QR_CODE_EXPIRE_SECONDS").MustInt(120) WechatAuthSwitch = sec.Key("AUTH_SWITCH").MustBool(true) UserNameOfWechatReply = sec.Key("AUTO_REPLY_USER_NAME").MustString("OpenIOSSG") @@ -1442,6 +1446,8 @@ func NewContext() { RefNameOfWechatReply = sec.Key("AUTO_REPLY_REF_NAME").MustString("master") TreePathOfAutoMsgReply = sec.Key("AUTO_REPLY_TREE_PATH").MustString("wechat/auto_reply.json") TreePathOfSubscribe = sec.Key("SUBSCRIBE_TREE_PATH").MustString("wechat/subscribe_reply.json") + CloudbrainStartedTemplateId = sec.Key("CLOUDBRAIN_STARTED_TEMPLATE_ID").MustString("") + CloudbrainStartedNotifyList = strings.Split(sec.Key("CLOUDBRAIN_STARTED_NOTIFY_LIST").MustString("DEBUG"), ",") SetRadarMapConfig() diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index fa5c5c63f3..cb0ef205f7 100755 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1007,7 +1007,7 @@ cloudbrain.time.starttime=Start run time cloudbrain.time.endtime=End run time cloudbrain.datasetdownload=Dataset download url model_manager = Model -model_noright=No right +model_noright=You have no right to do the operation. model_rename=Duplicate model name, please modify model name. date=Date @@ -1098,6 +1098,9 @@ modelarts.createtime=CreateTime modelarts.version_nums = Version Nums modelarts.version = Version modelarts.computing_resources=compute Resources +modelarts.ai_center=Ai Center +modelarts.card_type=Card Type +modelarts.cluster=Cluster modelarts.notebook=Debug Task modelarts.train_job=Train Task modelarts.train_job.new_debug= New Debug Task @@ -1225,7 +1228,7 @@ model.manage.create_new_convert_task=Create Model Transformation Task modelconvert.manage.create_error1=A model transformation task with the same name already exists. modelconvert.manage.create_error2=Only one running model transformation task can be created. modelconvert.manage.model_not_exist=The model does not exist. -modelconvert.manage.no_operate_right=No operation permission. +modelconvert.manage.no_operate_right=You have no right to do the operation. grampus.train_job.ai_center = AI Center grampus.dataset_path_rule = The code is storaged in /cache/code;the dataset is storaged in /cache/dataset;and please put your model into /cache/output, then you can download it online。 diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 45ccb5f126..652371690c 100755 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -1006,7 +1006,7 @@ datasets.desc=数据集功能 cloudbrain_helper=使用GPU/NPU资源,开启Notebook、模型训练任务等 model_manager = 模型 -model_noright=无权限操作 +model_noright=您没有操作权限。 model_rename=模型名称重复,请修改模型名称 @@ -1108,6 +1108,9 @@ modelarts.deletetime=删除时间 modelarts.version_nums=版本数 modelarts.version=版本 modelarts.computing_resources=计算资源 +modelarts.ai_center=智算中心 +modelarts.card_type=卡类型 +modelarts.cluster=集群 modelarts.notebook=调试任务 modelarts.train_job=训练任务 modelarts.train_job.new_debug=新建调试任务 @@ -1237,7 +1240,7 @@ model.manage.create_new_convert_task=创建模型转换任务 modelconvert.manage.create_error1=相同的名称模型转换任务已经存在。 modelconvert.manage.create_error2=只能创建一个正在运行的模型转换任务。 modelconvert.manage.model_not_exist=选择的模型不存在。 -modelconvert.manage.no_operate_right=无操作权限。 +modelconvert.manage.no_operate_right=您没有操作权限。 grampus.train_job.ai_center=智算中心 grampus.dataset_path_rule = 训练脚本存储在/cache/code中,数据集存储在/cache/dataset中,训练输出请存储在/cache/output中以供后续下载。 @@ -3119,6 +3122,8 @@ select_dataset = 选择数据集 specification = 规格 select_specification = 选择资源规格 description = 描述 +card_duration = 运行卡时 +card_type = 卡类型 wrong_specification=您目前不能使用这个资源规格,请选择其他资源规格。 job_name_rule = 请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。 diff --git a/public/self/css/notebook/notebook.css b/public/self/css/notebook/notebook.css index c75c33865a..0e4979660d 100644 --- a/public/self/css/notebook/notebook.css +++ b/public/self/css/notebook/notebook.css @@ -1,6 +1,7 @@ .nb-notebook { line-height: 1.5; - margin-left: 7em; + margin-left: 6em; + } .nb-stdout, .nb-stderr { @@ -15,6 +16,7 @@ .nb-cell + .nb-cell { margin-top: 0.5em; + max-width: 100%; } .nb-output table { @@ -40,6 +42,11 @@ padding-left: 1em; } +.nb-notebook img { + max-width: 80%; + padding: 3px; +} + .nb-cell { position: relative; } @@ -60,7 +67,8 @@ } .nb-output img { - max-width: 100%; + max-width: 80%; + padding: 3px; } .nb-output:before, .nb-input:before { diff --git a/public/self/dataset_preview.js b/public/self/dataset_preview.js index e6b79dd7db..81620e1a0d 100644 --- a/public/self/dataset_preview.js +++ b/public/self/dataset_preview.js @@ -123,13 +123,13 @@ function loadimg(uuid,filename){ function loadimg(){ var length = labeltastresult[fileindex].pic_image_field.length; -  if(labeltastresult[fileindex].pic_image_field.substring(length - 5) == ".json"  -     || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".xml" -     || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".txt" -     || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".csv" -     || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".md" -     || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".py" -     || labeltastresult[fileindex].pic_image_field.substring(length - 3) == ".sh"){ +  if(labeltastresult[fileindex].pic_image_field.substring(length - 5).toLowerCase() == ".json"  +     || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".xml" +     || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".txt" +     || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".csv" +     || labeltastresult[fileindex].pic_image_field.substring(length - 3).toLowerCase() == ".md" +     || labeltastresult[fileindex].pic_image_field.substring(length - 3).toLowerCase() == ".py" +     || labeltastresult[fileindex].pic_image_field.substring(length - 3).toLowerCase() == ".sh"){ //文本 canvas.style.display="none"; @@ -138,11 +138,11 @@ function loadimg(){ $('#textcontent').height(canvas.height-40) $("#textcontent").text(textContent); }else{ - if(labeltastresult[fileindex].pic_image_field.substring(length - 5) == ".jpeg"  -    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".jpg" -    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".bmp" -    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".gif" -    || labeltastresult[fileindex].pic_image_field.substring(length - 4) == ".png"){ + if(labeltastresult[fileindex].pic_image_field.substring(length - 5).toLowerCase() == ".jpeg"  +    || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".jpg" +    || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".bmp" +    || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".gif" +    || labeltastresult[fileindex].pic_image_field.substring(length - 4).toLowerCase() == ".png"){ canvas.style.display="block"; document.getElementById("textcontent").style.display="none"; img.src = ip + "/getgiteaimage?uuid=" + dataset_id + "&filename=" + labeltastresult[fileindex].pic_image_field; diff --git a/routers/admin/cloudbrains.go b/routers/admin/cloudbrains.go index 8cfe107951..5876baf18d 100755 --- a/routers/admin/cloudbrains.go +++ b/routers/admin/cloudbrains.go @@ -10,6 +10,7 @@ import ( "github.com/360EntSecGroup-Skylar/excelize/v2" "code.gitea.io/gitea/modules/modelarts" + "code.gitea.io/gitea/routers/repo" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/base" @@ -89,6 +90,10 @@ func CloudBrains(ctx *context.Context) { ciTasks[i].CanDebug = true ciTasks[i].CanDel = true ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource + ciTasks[i].Cloudbrain.AiCenter = repo.GetCloudbrainAiCenter(task.Cloudbrain, ctx) + _, cardType, _ := repo.GetCloudbrainCardNumAndType(task.Cloudbrain) + ciTasks[i].Cloudbrain.CardType = cardType + ciTasks[i].Cloudbrain.Cluster = repo.GetCloudbrainCluster(task.Cloudbrain, ctx) } pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, getTotalPage(count, setting.UI.IssuePagingNum)) @@ -188,11 +193,19 @@ func DownloadCloudBrains(ctx *context.Context) { } func allValues(row int, rs *models.CloudbrainInfo, ctx *context.Context) map[string]string { - return map[string]string{getCellName("A", row): rs.DisplayJobName, getCellName("B", row): rs.JobType, getCellName("C", row): rs.Status, getCellName("D", row): time.Unix(int64(rs.Cloudbrain.CreatedUnix), 0).Format(CREATE_TIME_FORMAT), getCellName("E", row): getDurationTime(rs), - getCellName("F", row): rs.ComputeResource, getCellName("G", row): rs.Name, getCellName("H", row): getRepoPathName(rs), getCellName("I", row): rs.JobName, + return map[string]string{getCellName("A", row): rs.DisplayJobName, getCellName("B", row): repo.GetCloudbrainCluster(rs.Cloudbrain, ctx), + getCellName("C", row): rs.JobType, getCellName("D", row): rs.Status, getCellName("E", row): time.Unix(int64(rs.Cloudbrain.CreatedUnix), 0).Format(CREATE_TIME_FORMAT), + getCellName("F", row): getDurationTime(rs), getCellName("G", row): rs.ComputeResource, + getCellName("H", row): repo.GetCloudbrainAiCenter(rs.Cloudbrain, ctx), getCellName("I", row): getCloudbrainCardType(rs), + getCellName("J", row): rs.Name, getCellName("K", row): getRepoPathName(rs), getCellName("L", row): rs.JobName, } } +func getCloudbrainCardType(rs *models.CloudbrainInfo) string { + _, cardType, _ := repo.GetCloudbrainCardNumAndType(rs.Cloudbrain) + return cardType +} + func getRepoPathName(rs *models.CloudbrainInfo) string { if rs.Repo != nil { return rs.Repo.OwnerName + "/" + rs.Repo.Alias @@ -225,7 +238,11 @@ func getTotalPage(total int64, pageSize int) int { func allHeader(ctx *context.Context) map[string]string { - return map[string]string{"A1": ctx.Tr("repo.cloudbrain_task"), "B1": ctx.Tr("repo.cloudbrain_task_type"), "C1": ctx.Tr("repo.modelarts.status"), "D1": ctx.Tr("repo.modelarts.createtime"), "E1": ctx.Tr("repo.modelarts.train_job.dura_time"), "F1": ctx.Tr("repo.modelarts.computing_resources"), "G1": ctx.Tr("repo.cloudbrain_creator"), "H1": ctx.Tr("repo.repo_name"), "I1": ctx.Tr("repo.cloudbrain_task_name")} + return map[string]string{"A1": ctx.Tr("repo.cloudbrain_task"), "B1": ctx.Tr("repo.modelarts.cluster"), + "C1": ctx.Tr("repo.cloudbrain_task_type"), "D1": ctx.Tr("repo.modelarts.status"), "E1": ctx.Tr("repo.modelarts.createtime"), + "F1": ctx.Tr("repo.modelarts.train_job.dura_time"), "G1": ctx.Tr("repo.modelarts.computing_resources"), + "H1": ctx.Tr("repo.modelarts.ai_center"), "I1": ctx.Tr("repo.modelarts.card_type"), "J1": ctx.Tr("repo.cloudbrain_creator"), + "K1": ctx.Tr("repo.repo_name"), "L1": ctx.Tr("repo.cloudbrain_task_name")} } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 3d9452f939..aa51c6e1a3 100755 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -571,6 +571,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("/query_user_yesterday", operationReq, repo_ext.QueryUserStaticYesterday) m.Get("/query_user_all", operationReq, repo_ext.QueryUserStaticAll) m.Get("/query_user_activity", operationReq, repo_ext.QueryUserActivity) + m.Get("/query_user_login", operationReq, repo_ext.QueryUserLoginInfo) //cloudbrain board m.Group("/cloudbrainboard", func() { m.Get("/downloadAll", repo.DownloadCloudBrainBoard) diff --git a/routers/api/v1/repo/cloudbrain.go b/routers/api/v1/repo/cloudbrain.go index d291024f99..c3a803f709 100755 --- a/routers/api/v1/repo/cloudbrain.go +++ b/routers/api/v1/repo/cloudbrain.go @@ -6,6 +6,7 @@ package repo import ( + "code.gitea.io/gitea/modules/notification" "encoding/json" "net/http" "sort" @@ -74,7 +75,7 @@ func GetCloudbrainTask(ctx *context.APIContext) { log.Error("ConvertToJobResultPayload failed:", err) return } - + oldStatus := job.Status job.Status = result.JobStatus.State taskRoles := result.TaskRoles taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) @@ -86,6 +87,9 @@ func GetCloudbrainTask(ctx *context.APIContext) { if result.JobStatus.State != string(models.JobWaiting) { models.ParseAndSetDurationFromCloudBrainOne(result, job) + if oldStatus != job.Status { + notification.NotifyChangeCloudbrainStatus(job, oldStatus) + } err = models.UpdateJob(job) if err != nil { log.Error("UpdateJob failed:", err) @@ -99,6 +103,7 @@ func GetCloudbrainTask(ctx *context.APIContext) { "SubState": result.JobStatus.SubState, "CreatedTime": time.Unix(result.JobStatus.CreatedTime/1000, 0).Format("2006-01-02 15:04:05"), "CompletedTime": time.Unix(result.JobStatus.CompletedTime/1000, 0).Format("2006-01-02 15:04:05"), + "JobDuration": job.TrainJobDuration, }) } @@ -123,7 +128,7 @@ func GetCloudBrainInferenceJob(ctx *context.APIContext) { log.Error("ConvertToJobResultPayload failed:", err) return } - + oldStatus := job.Status job.Status = result.JobStatus.State if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { taskRoles := result.TaskRoles @@ -136,6 +141,9 @@ func GetCloudBrainInferenceJob(ctx *context.APIContext) { if result.JobStatus.State != string(models.JobWaiting) { models.ParseAndSetDurationFromCloudBrainOne(result, job) + if oldStatus != job.Status { + notification.NotifyChangeCloudbrainStatus(job, oldStatus) + } err = models.UpdateJob(job) if err != nil { log.Error("UpdateJob failed:", err) diff --git a/routers/api/v1/repo/cloudbrain_dashboard.go b/routers/api/v1/repo/cloudbrain_dashboard.go index eb86a82935..c632f3c8ba 100755 --- a/routers/api/v1/repo/cloudbrain_dashboard.go +++ b/routers/api/v1/repo/cloudbrain_dashboard.go @@ -10,6 +10,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/routers/repo" "github.com/360EntSecGroup-Skylar/excelize/v2" ) @@ -735,6 +736,7 @@ func GetCloudbrainsDetailData(ctx *context.Context) { var taskDetail models.TaskDetail taskDetail.ID = ciTasks[i].Cloudbrain.ID + taskDetail.JobID = ciTasks[i].Cloudbrain.JobID taskDetail.JobName = ciTasks[i].JobName taskDetail.DisplayJobName = ciTasks[i].DisplayJobName taskDetail.Status = ciTasks[i].Status @@ -751,46 +753,12 @@ func GetCloudbrainsDetailData(ctx *context.Context) { taskDetail.RepoName = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Name taskDetail.RepoAlias = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Alias } - if ciTasks[i].Cloudbrain.Status == string(models.JobWaiting) { - if ciTasks[i].Cloudbrain.DeletedAt != nilTime { - WaitTimeInt := ciTasks[i].Cloudbrain.UpdatedUnix.AsTime().Unix() - ciTasks[i].Cloudbrain.CreatedUnix.AsTime().Unix() - taskDetail.WaitTime = models.ConvertDurationToStr(WaitTimeInt) - if WaitTimeInt < 0 { - taskDetail.WaitTime = "00:00:00" - } - } else { - if ciTasks[i].Cloudbrain.StartTime.AsTime().Unix() == 0 { - WaitTimeInt := time.Now().Unix() - ciTasks[i].Cloudbrain.CreatedUnix.AsTime().Unix() - taskDetail.WaitTime = models.ConvertDurationToStr(WaitTimeInt) - if WaitTimeInt < 0 { - taskDetail.WaitTime = "00:00:00" - } - } else { - WaitTimeInt := ciTasks[i].Cloudbrain.StartTime.AsTime().Unix() - ciTasks[i].Cloudbrain.CreatedUnix.AsTime().Unix() - taskDetail.WaitTime = models.ConvertDurationToStr(WaitTimeInt) - if WaitTimeInt < 0 { - taskDetail.WaitTime = "00:00:00" - } - } - } - } else if ciTasks[i].Cloudbrain.Status == string(models.JobStopped) && ciTasks[i].Cloudbrain.StartTime.AsTime().Unix() == 0 { - WaitTimeInt := ciTasks[i].Cloudbrain.EndTime.AsTime().Unix() - ciTasks[i].Cloudbrain.CreatedUnix.AsTime().Unix() - taskDetail.WaitTime = models.ConvertDurationToStr(WaitTimeInt) - if WaitTimeInt < 0 { - taskDetail.WaitTime = "00:00:00" - - } - } else { - WaitTimeInt := ciTasks[i].Cloudbrain.StartTime.AsTime().Unix() - ciTasks[i].Cloudbrain.CreatedUnix.AsTime().Unix() - taskDetail.WaitTime = models.ConvertDurationToStr(WaitTimeInt) - if WaitTimeInt < 0 { - taskDetail.WaitTime = "00:00:00" - } - } + taskDetail.CardNum, taskDetail.CardType, _ = repo.GetCloudbrainCardNumAndType(ciTasks[i].Cloudbrain) + taskDetail.CardDuration = repo.GetCloudbrainCardDuration(ciTasks[i].Cloudbrain) + taskDetail.AiCenter = repo.GetCloudbrainAiCenter(ciTasks[i].Cloudbrain, ctx) + taskDetail.FlavorName, _ = repo.GetCloudbrainFlavorName(ciTasks[i].Cloudbrain) - if ciTasks[i].Cloudbrain.Type == models.TypeCloudBrainTwo || (ciTasks[i].Cloudbrain.Type == models.TypeCloudBrainOne && ciTasks[i].Cloudbrain.JobType == "TRAIN") { - taskDetail.JobID = ciTasks[i].Cloudbrain.JobID - } + taskDetail.WaitTime = repo.GetCloudbrainWaitTime(ciTasks[i].Cloudbrain) if ciTasks[i].Cloudbrain.DeletedAt != nilTime { taskDetail.IsDelete = true @@ -813,6 +781,17 @@ func GetCloudbrainsDetailData(ctx *context.Context) { }) } +func getCloudbrainAiCenter(task models.Cloudbrain, ctx *context.Context) string { + if task.Type == models.TypeCloudBrainOne { + return ctx.Tr("repo.cloudbrain1") + } else if task.Type == models.TypeCloudBrainTwo { + return ctx.Tr("repo.cloudbrain2") + } else if task.Type == models.TypeC2Net { + return task.AiCenter + } + return "" +} + func GetCloudbrainsCreateHoursData(ctx *context.Context) { recordCloudbrain, err := models.GetRecordBeginTime() if err != nil { @@ -1247,18 +1226,23 @@ func allCloudbrainHeader(ctx *context.Context) map[string]string { return map[string]string{"A1": ctx.Tr("repo.cloudbrain_task"), "B1": ctx.Tr("repo.cloudbrain_type"), "C1": ctx.Tr("repo.modelarts.status"), "D1": ctx.Tr("repo.cloudbrain_task_type"), "E1": ctx.Tr("repo.modelarts.createtime"), "F1": ctx.Tr("repo.modelarts.train_job.wait_time"), "G1": ctx.Tr("repo.modelarts.train_job.dura_time"), - "H1": ctx.Tr("repo.modelarts.train_job.start_time"), - "I1": ctx.Tr("repo.modelarts.train_job.end_time"), "J1": ctx.Tr("repo.modelarts.computing_resources"), - "K1": ctx.Tr("repo.cloudbrain_creator"), "L1": ctx.Tr("repo.repo_name"), "M1": ctx.Tr("repo.cloudbrain_task_name"), "N1": ctx.Tr("repo.modelarts.deletetime")} + "H1": ctx.Tr("cloudbrain.card_duration"), + "I1": ctx.Tr("repo.modelarts.train_job.start_time"), "J1": ctx.Tr("repo.modelarts.train_job.end_time"), + "K1": ctx.Tr("repo.modelarts.computing_resources"), "L1": ctx.Tr("cloudbrain.card_type"), + "M1": ctx.Tr("repo.grampus.train_job.ai_center"), "N1": ctx.Tr("cloudbrain.resource_specification"), + "O1": ctx.Tr("repo.cloudbrain_creator"), "P1": ctx.Tr("repo.repo_name"), "Q1": ctx.Tr("repo.cloudbrain_task_name"), + "R1": ctx.Tr("repo.modelarts.deletetime")} } func allCloudbrainValues(row int, rs *models.CloudbrainInfo, ctx *context.Context) map[string]string { return map[string]string{getCellName("A", row): rs.DisplayJobName, getCellName("B", row): getCloudbrainType(rs, ctx), getCellName("C", row): rs.Status, getCellName("D", row): rs.JobType, - getCellName("E", row): time.Unix(int64(rs.Cloudbrain.CreatedUnix), 0).Format(CREATE_TIME_FORMAT), getCellName("F", row): getBrainWaitTime(rs), - getCellName("G", row): rs.TrainJobDuration, getCellName("H", row): getBrainStartTime(rs), - getCellName("I", row): getBrainEndTime(rs), - getCellName("J", row): rs.ComputeResource, getCellName("K", row): rs.Name, getCellName("L", row): getBrainRepo(rs), - getCellName("M", row): rs.JobName, getCellName("N", row): getBrainDeleteTime(rs), + getCellName("E", row): time.Unix(int64(rs.Cloudbrain.CreatedUnix), 0).Format(CREATE_TIME_FORMAT), getCellName("F", row): repo.GetCloudbrainWaitTime(rs.Cloudbrain), + getCellName("G", row): rs.TrainJobDuration, getCellName("H", row): repo.GetCloudbrainCardDuration(rs.Cloudbrain), + getCellName("I", row): getBrainStartTime(rs), + getCellName("J", row): getBrainEndTime(rs), getCellName("K", row): rs.ComputeResource, getCellName("L", row): getCloudbrainCardType(rs), + getCellName("M", row): repo.GetCloudbrainAiCenter(rs.Cloudbrain, ctx), getCellName("N", row): getCloudbrainFlavorName(rs), + getCellName("O", row): rs.Name, getCellName("P", row): getBrainRepo(rs), + getCellName("Q", row): rs.JobName, getCellName("R", row): getBrainDeleteTime(rs), } } func getBrainRepo(rs *models.CloudbrainInfo) string { @@ -1285,19 +1269,6 @@ func getBrainEndTime(rs *models.CloudbrainInfo) string { } } -func getBrainWaitTime(rs *models.CloudbrainInfo) string { - var waitTime int64 - if rs.Cloudbrain.Status == string(models.JobWaiting) { - waitTime = time.Now().Unix() - rs.Cloudbrain.CreatedUnix.AsTime().Unix() - } else { - waitTime = int64(rs.Cloudbrain.StartTime - rs.Cloudbrain.CreatedUnix) - } - if waitTime <= 0 { - return "00:00:00" - } else { - return models.ConvertDurationToStr(waitTime) - } -} func getCloudbrainType(rs *models.CloudbrainInfo, ctx *context.Context) string { if rs.Cloudbrain.Type == models.TypeCloudBrainOne { return ctx.Tr("repo.cloudbrain1") @@ -1309,6 +1280,14 @@ func getCloudbrainType(rs *models.CloudbrainInfo, ctx *context.Context) string { return ctx.Tr("repo.cloudbrain_untype") } } +func getCloudbrainCardType(rs *models.CloudbrainInfo) string { + _, cardType, _ := repo.GetCloudbrainCardNumAndType(rs.Cloudbrain) + return cardType +} +func getCloudbrainFlavorName(rs *models.CloudbrainInfo) string { + flavorName, _ := repo.GetCloudbrainFlavorName(rs.Cloudbrain) + return flavorName +} func getBrainDeleteTime(rs *models.CloudbrainInfo) string { nilTime := time.Time{} diff --git a/routers/api/v1/repo/modelarts.go b/routers/api/v1/repo/modelarts.go index 187c16c50f..7d30614b51 100755 --- a/routers/api/v1/repo/modelarts.go +++ b/routers/api/v1/repo/modelarts.go @@ -6,6 +6,7 @@ package repo import ( + "code.gitea.io/gitea/modules/notification" "encoding/json" "net/http" "path" @@ -42,8 +43,11 @@ func GetModelArtsNotebook(ctx *context.APIContext) { ctx.NotFound(err) return } - + oldStatus := job.Status job.Status = result.Status + if oldStatus != result.Status { + notification.NotifyChangeCloudbrainStatus(job, oldStatus) + } err = models.UpdateJob(job) if err != nil { log.Error("UpdateJob failed:", err) @@ -75,21 +79,26 @@ func GetModelArtsNotebook2(ctx *context.APIContext) { if job.StartTime == 0 && result.Lease.UpdateTime > 0 { job.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000) } + oldStatus := job.Status job.Status = result.Status if job.EndTime == 0 && models.IsModelArtsDebugJobTerminal(job.Status) { job.EndTime = timeutil.TimeStampNow() } job.CorrectCreateUnix() job.ComputeAndSetDuration() + if oldStatus != result.Status { + notification.NotifyChangeCloudbrainStatus(job, oldStatus) + } err = models.UpdateJob(job) if err != nil { log.Error("UpdateJob failed:", err) } ctx.JSON(http.StatusOK, map[string]interface{}{ - "ID": ID, - "JobName": job.JobName, - "JobStatus": result.Status, + "ID": ID, + "JobName": job.JobName, + "JobStatus": result.Status, + "JobDuration": job.TrainJobDuration, }) } @@ -111,10 +120,13 @@ func GetModelArtsTrainJob(ctx *context.APIContext) { ctx.NotFound(err) return } - + oldStatus := job.Status job.Status = modelarts.TransTrainJobStatus(result.IntStatus) job.Duration = result.Duration job.TrainJobDuration = result.TrainJobDuration + if oldStatus != job.Status { + notification.NotifyChangeCloudbrainStatus(job, oldStatus) + } err = models.UpdateJob(job) if err != nil { log.Error("UpdateJob failed:", err) @@ -155,7 +167,7 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) { log.Error("ConvertToJobResultPayload failed:", err) return } - + oldStatus := job.Status job.Status = result.JobStatus.State if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { taskRoles := result.TaskRoles @@ -168,6 +180,9 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) { if result.JobStatus.State != string(models.JobWaiting) { models.ParseAndSetDurationFromCloudBrainOne(result, job) + if oldStatus != job.Status { + notification.NotifyChangeCloudbrainStatus(job, oldStatus) + } err = models.UpdateJob(job) if err != nil { log.Error("UpdateJob failed:", err) diff --git a/routers/repo/ai_model_manage.go b/routers/repo/ai_model_manage.go index 0aef1a70c2..d01539a754 100644 --- a/routers/repo/ai_model_manage.go +++ b/routers/repo/ai_model_manage.go @@ -152,6 +152,10 @@ func saveModelByParameters(jobId string, versionName string, name string, versio } func SaveNewNameModel(ctx *context.Context) { + if !ctx.Repo.CanWrite(models.UnitTypeModelManage) { + ctx.Error(403, ctx.Tr("repo.model_noright")) + return + } name := ctx.Query("Name") if name == "" { ctx.Error(500, fmt.Sprintf("name or version is null.")) @@ -169,6 +173,10 @@ func SaveNewNameModel(ctx *context.Context) { } func SaveModel(ctx *context.Context) { + if !ctx.Repo.CanWrite(models.UnitTypeModelManage) { + ctx.Error(403, ctx.Tr("repo.model_noright")) + return + } log.Info("save model start.") JobId := ctx.Query("JobId") VersionName := ctx.Query("VersionName") @@ -177,16 +185,8 @@ func SaveModel(ctx *context.Context) { label := ctx.Query("Label") description := ctx.Query("Description") engine := ctx.QueryInt("Engine") - trainTaskCreate := ctx.QueryBool("trainTaskCreate") modelSelectedFile := ctx.Query("modelSelectedFile") log.Info("engine=" + fmt.Sprint(engine) + " modelSelectedFile=" + modelSelectedFile) - if !trainTaskCreate { - if !ctx.Repo.CanWrite(models.UnitTypeModelManage) { - //ctx.NotFound(ctx.Req.URL.RequestURI(), nil) - ctx.JSON(403, ctx.Tr("repo.model_noright")) - return - } - } if JobId == "" || VersionName == "" { ctx.Error(500, fmt.Sprintf("JobId or VersionName is null.")) diff --git a/routers/repo/cloudbrain.go b/routers/repo/cloudbrain.go index 1a9dec6eaa..32c5ea9f63 100755 --- a/routers/repo/cloudbrain.go +++ b/routers/repo/cloudbrain.go @@ -15,6 +15,8 @@ import ( "time" "unicode/utf8" + "code.gitea.io/gitea/modules/notification" + "code.gitea.io/gitea/modules/grampus" "code.gitea.io/gitea/modules/timeutil" @@ -222,6 +224,7 @@ func CloudBrainNew(ctx *context.Context) { ctx.ServerError("get new cloudbrain info failed", err) return } + ctx.Data["PageIsGPUDebug"] = true ctx.HTML(200, tplCloudBrainNew) } @@ -287,13 +290,17 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { return } } - - datasetInfos, datasetNames, err := models.GetDatasetInfo(uuids) - if err != nil { - log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) - ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form) - return + var datasetInfos map[string]models.DatasetInfo + var datasetNames string + //var + if uuids != "" { + datasetInfos, datasetNames, err = models.GetDatasetInfo(uuids) + if err != nil { + log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"]) + cloudBrainNewDataPrepare(ctx) + ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form) + return + } } command := cloudbrain.GetCloudbrainDebugCommand() @@ -302,6 +309,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { commandTrain, err := getTrainJobCommand(form) if err != nil { log.Error("getTrainJobCommand failed: %v", err) + cloudBrainNewDataPrepare(ctx) ctx.RenderWithErr(err.Error(), tpl, &form) return } @@ -370,7 +378,6 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { } } - func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBrainInferencForm) { ctx.Data["PageIsCloudBrain"] = true displayJobName := form.DisplayJobName @@ -391,6 +398,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra command, err := getInferenceJobCommand(form) if err != nil { log.Error("getTrainJobCommand failed: %v", err) + cloudBrainNewDataPrepare(ctx) ctx.RenderWithErr(err.Error(), tpl, &form) return } @@ -413,6 +421,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra } if !jobNamePattern.MatchString(displayJobName) { + cloudBrainNewDataPrepare(ctx) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tpl, &form) return } @@ -491,6 +500,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/inference-job") } + /** 检查用户传输的参数是否符合专属资源池 */ @@ -633,6 +643,7 @@ func CloudBrainTrainJobShow(ctx *context.Context) { func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.JobType) { ctx.Data["PageIsCloudBrain"] = true debugListType := ctx.Query("debugListType") + cloudbrain.InitSpecialPool() var task *models.Cloudbrain var err error @@ -644,22 +655,22 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo if err != nil { log.Info("error:" + err.Error()) - ctx.Data["error"] = err.Error() + ctx.NotFound(ctx.Req.URL.RequestURI(), nil) return } result, err := cloudbrain.GetJob(task.JobID) if err != nil { log.Info("error:" + err.Error()) - ctx.Data["error"] = err.Error() + ctx.NotFound(ctx.Req.URL.RequestURI(), nil) return } - + hasSpec := false if task.JobType == string(models.JobTypeTrain) { if cloudbrain.TrainResourceSpecs == nil { json.Unmarshal([]byte(setting.TrainResourceSpecs), &cloudbrain.TrainResourceSpecs) } - hasSpec := false + for _, tmp := range cloudbrain.TrainResourceSpecs.ResourceSpec { if tmp.Id == task.ResourceSpecId { hasSpec = true @@ -667,24 +678,7 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo ctx.Data["CpuNum"] = tmp.CpuNum ctx.Data["MemMiB"] = tmp.MemMiB ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB - } - } - - if !hasSpec && cloudbrain.SpecialPools != nil { - for _, specialPool := range cloudbrain.SpecialPools.Pools { - - if specialPool.ResourceSpec != nil { - - for _, spec := range specialPool.ResourceSpec { - if task.ResourceSpecId == spec.Id { - ctx.Data["GpuNum"] = spec.GpuNum - ctx.Data["CpuNum"] = spec.CpuNum - ctx.Data["MemMiB"] = spec.MemMiB - ctx.Data["ShareMemMiB"] = spec.ShareMemMiB - break - } - } - } + break } } @@ -694,10 +688,12 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo } for _, tmp := range cloudbrain.InferenceResourceSpecs.ResourceSpec { if tmp.Id == task.ResourceSpecId { + hasSpec = true ctx.Data["GpuNum"] = tmp.GpuNum ctx.Data["CpuNum"] = tmp.CpuNum ctx.Data["MemMiB"] = tmp.MemMiB ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB + break } } } else { @@ -706,10 +702,32 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo } for _, tmp := range cloudbrain.ResourceSpecs.ResourceSpec { if tmp.Id == task.ResourceSpecId { + hasSpec = true ctx.Data["GpuNum"] = tmp.GpuNum ctx.Data["CpuNum"] = tmp.CpuNum ctx.Data["MemMiB"] = tmp.MemMiB ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB + break + + } + } + } + + if !hasSpec && cloudbrain.SpecialPools != nil { + + for _, specialPool := range cloudbrain.SpecialPools.Pools { + + if specialPool.ResourceSpec != nil { + + for _, spec := range specialPool.ResourceSpec { + if task.ResourceSpecId == spec.Id { + ctx.Data["GpuNum"] = spec.GpuNum + ctx.Data["CpuNum"] = spec.CpuNum + ctx.Data["MemMiB"] = spec.MemMiB + ctx.Data["ShareMemMiB"] = spec.ShareMemMiB + break + } + } } } } @@ -728,14 +746,6 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo ctx.Data["resource_type"] = resourceType.Value } } - for _, specialPool := range cloudbrain.SpecialPools.Pools { - - for _, resourceType := range specialPool.Pool { - if resourceType.Queue == jobRes.Config.GpuType { - ctx.Data["resource_type"] = resourceType.Value - } - } - } } else if task.JobType == string(models.JobTypeInference) { if inferenceGpuInfos == nil { @@ -767,16 +777,30 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo } } } + + if cloudbrain.SpecialPools != nil { + for _, specialPool := range cloudbrain.SpecialPools.Pools { + for _, resourceType := range specialPool.Pool { + if resourceType.Queue == jobRes.Config.GpuType { + ctx.Data["resource_type"] = resourceType.Value + } + } + } + } taskRoles := jobRes.TaskRoles taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) ctx.Data["taskRes"] = taskRes ctx.Data["ExitDiagnostics"] = taskRes.TaskStatuses[0].ExitDiagnostics + oldStatus := task.Status task.Status = taskRes.TaskStatuses[0].State task.ContainerID = taskRes.TaskStatuses[0].ContainerID task.ContainerIp = taskRes.TaskStatuses[0].ContainerIP models.ParseAndSetDurationFromCloudBrainOne(jobRes, task) if task.DeletedAt.IsZero() { //normal record + if oldStatus != task.Status { + notification.NotifyChangeCloudbrainStatus(task, oldStatus) + } err = models.UpdateJob(task) if err != nil { ctx.Data["error"] = err.Error() @@ -892,6 +916,20 @@ func CloudBrainCommitImageShow(ctx *context.Context) { ctx.HTML(200, tplCloudBrainImageSubmit) } +func GetImage(ctx *context.Context) { + + var ID = ctx.Params(":id") + id, _ := strconv.ParseInt(ID, 10, 64) + + image, err := models.GetImageByID(id) + if err != nil { + log.Error("GetImageByID failed:%v", err.Error()) + ctx.JSON(http.StatusNotFound, nil) + } + ctx.JSON(http.StatusOK, image) + +} + func CloudBrainImageEdit(ctx *context.Context) { ctx.Data["PageIsImageEdit"] = true ctx.Data["PageFrom"] = ctx.Params(":from") @@ -1116,12 +1154,15 @@ func CloudBrainStop(ctx *context.Context) { errorMsg = "cloudbrain.Stopped_failed" break } - + oldStatus := task.Status task.Status = string(models.JobStopped) if task.EndTime == 0 { task.EndTime = timeutil.TimeStampNow() } task.ComputeAndSetDuration() + if oldStatus != task.Status { + notification.NotifyChangeCloudbrainStatus(task, oldStatus) + } err = models.UpdateJob(task) if err != nil { log.Error("UpdateJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"]) @@ -1215,11 +1256,15 @@ func logErrorAndUpdateJobStatus(err error, taskInfo *models.Cloudbrain) { if err != nil { log.Warn("Failed to stop cloudBrain job:"+taskInfo.JobID, err) } else { + oldStatus := taskInfo.Status taskInfo.Status = string(models.JobStopped) if taskInfo.EndTime == 0 { taskInfo.EndTime = timeutil.TimeStampNow() } taskInfo.ComputeAndSetDuration() + if oldStatus != taskInfo.Status { + notification.NotifyChangeCloudbrainStatus(taskInfo, oldStatus) + } err = models.UpdateJob(taskInfo) if err != nil { log.Warn("UpdateJob failed", err) @@ -1699,9 +1744,13 @@ func SyncCloudbrainStatus() { jobRes, _ := models.ConvertToJobResultPayload(result.Payload) taskRoles := jobRes.TaskRoles taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) + oldStatus := task.Status task.Status = taskRes.TaskStatuses[0].State if task.Status != string(models.JobWaiting) { models.ParseAndSetDurationFromCloudBrainOne(jobRes, task) + if oldStatus != task.Status { + notification.NotifyChangeCloudbrainStatus(task, oldStatus) + } err = models.UpdateJob(task) if err != nil { log.Error("UpdateJob(%s) failed:%v", task.JobName, err) @@ -1728,6 +1777,9 @@ func SyncCloudbrainStatus() { task.EndTime = timeutil.TimeStampNow() } task.ComputeAndSetDuration() + if oldStatus != task.Status { + notification.NotifyChangeCloudbrainStatus(task, oldStatus) + } err = models.UpdateJob(task) if err != nil { log.Error("UpdateJob(%s) failed:%v", task.DisplayJobName, err) @@ -1746,6 +1798,7 @@ func SyncCloudbrainStatus() { } if result != nil { + oldStatus := task.Status task.Status = result.Status if task.StartTime == 0 && result.Lease.UpdateTime > 0 { task.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000) @@ -1755,6 +1808,9 @@ func SyncCloudbrainStatus() { } task.CorrectCreateUnix() task.ComputeAndSetDuration() + if oldStatus != task.Status { + notification.NotifyChangeCloudbrainStatus(task, oldStatus) + } err = models.UpdateJob(task) if err != nil { log.Error("UpdateJob(%s) failed:%v", task.JobName, err) @@ -1769,6 +1825,7 @@ func SyncCloudbrainStatus() { } if result != nil { + oldStatus := task.Status task.Status = modelarts.TransTrainJobStatus(result.IntStatus) task.Duration = result.Duration / 1000 task.TrainJobDuration = result.TrainJobDuration @@ -1781,6 +1838,9 @@ func SyncCloudbrainStatus() { task.EndTime = task.StartTime.Add(task.Duration) } task.CorrectCreateUnix() + if oldStatus != task.Status { + notification.NotifyChangeCloudbrainStatus(task, oldStatus) + } err = models.UpdateJob(task) if err != nil { log.Error("UpdateJob(%s) failed:%v", task.JobName, err) @@ -1801,6 +1861,7 @@ func SyncCloudbrainStatus() { if len(result.JobInfo.Tasks[0].CenterID) == 1 && len(result.JobInfo.Tasks[0].CenterName) == 1 { task.AiCenter = result.JobInfo.Tasks[0].CenterID[0] + "+" + result.JobInfo.Tasks[0].CenterName[0] } + oldStatus := task.Status task.Status = grampus.TransTrainJobStatus(result.JobInfo.Status) task.Duration = result.JobInfo.RunSec task.TrainJobDuration = models.ConvertDurationToStr(task.Duration) @@ -1812,6 +1873,9 @@ func SyncCloudbrainStatus() { task.EndTime = task.StartTime.Add(task.Duration) } task.CorrectCreateUnix() + if oldStatus != task.Status { + notification.NotifyChangeCloudbrainStatus(task, oldStatus) + } err = models.UpdateJob(task) if err != nil { log.Error("UpdateJob(%s) failed:%v", task.JobName, err) @@ -2662,3 +2726,170 @@ func GetBenchmarkTypes(ctx *context.Context) *models.BenchmarkTypes { } return benchmarkTypesMap[lang] } + +func GetCloudbrainAiCenter(task models.Cloudbrain, ctx *context.Context) string { + if task.Type == models.TypeCloudBrainOne { + return ctx.Tr("repo.cloudbrain1") + } else if task.Type == models.TypeCloudBrainTwo { + return ctx.Tr("repo.cloudbrain2") + } else if task.Type == models.TypeC2Net { + return getCutStringAiCenterByAiCenter(task.AiCenter) + } + return "" +} +func getCutStringAiCenterByAiCenter(aiCenter string) string { + if aiCenter == "" { + return "" + } + index := strings.LastIndex(aiCenter, "+") + return aiCenter[index+1:] + +} +func GetCloudbrainCluster(task models.Cloudbrain, ctx *context.Context) string { + if task.Type == models.TypeCloudBrainOne || task.Type == models.TypeCloudBrainTwo { + return ctx.Tr("cloudbrain.resource_cluster_openi") + } else if task.Type == models.TypeC2Net { + return ctx.Tr("cloudbrain.resource_cluster_c2net") + } + return "" +} +func GetCloudbrainCardDuration(task models.Cloudbrain) string { + cardNum, _, _ := GetCloudbrainCardNumAndType(task) + cardDuration := models.ConvertDurationToStr(int64(cardNum) * task.Duration) + return cardDuration +} +func GetCloudbrainWaitTime(task models.Cloudbrain) string { + var waitTime string + if task.Status == string(models.JobWaiting) { + waitTimeInt := time.Now().Unix() - task.CreatedUnix.AsTime().Unix() + waitTime = models.ConvertDurationToStr(waitTimeInt) + if waitTimeInt < 0 { + waitTime = "00:00:00" + } + } else if task.Status == string(models.JobStopped) && task.StartTime.AsTime().Unix() == 0 { + waitTimeInt := task.EndTime.AsTime().Unix() - task.CreatedUnix.AsTime().Unix() + waitTime = models.ConvertDurationToStr(waitTimeInt) + if waitTimeInt < 0 { + waitTime = "00:00:00" + + } + } else { + waitTimeInt := task.StartTime.AsTime().Unix() - task.CreatedUnix.AsTime().Unix() + waitTime = models.ConvertDurationToStr(waitTimeInt) + if waitTimeInt < 0 { + waitTime = "00:00:00" + } + } + return waitTime +} + +func GetCloudbrainCardNumAndType(task models.Cloudbrain) (int, string, error) { + if !models.SpecsMapInitFlag { + models.InitCloudbrainOneResourceSpecMap() + } + if !models.GpuInfosMapInitFlag { + models.InitCloudbrainOneGpuInfoMap() + } + flavorName, err := GetCloudbrainFlavorName(task) + if err != nil { + return 0, "", nil + } + return getCardNumAndTypeByFlavorname(flavorName) +} + +func getCardNumAndTypeByFlavorname(FlavorName string) (int, string, error) { + if FlavorName == "" { + return 0, "", nil + } else { + var beginIndex = strings.Index(FlavorName, ":") + var lastIndex = strings.LastIndex(FlavorName, ":") + var endIndex = strings.Index(FlavorName, "*") + if endIndex >= (beginIndex+1) && lastIndex >= (endIndex+1) { + cardNum, err := strconv.Atoi(strings.TrimSpace(FlavorName[beginIndex+1 : endIndex])) + if err != nil { + log.Error("strconv.Atoi failed: %v", err) + return 0, "", err + } + cardType := strings.TrimSpace(FlavorName[endIndex+1 : lastIndex]) + return cardNum, cardType, err + } + return 0, "", nil + } +} + +func GetCloudbrainFlavorName(task models.Cloudbrain) (string, error) { + if task.Type == models.TypeCloudBrainOne { + resourceSpec, gpuInfo, err := getCloudBrainOneResourceSpec(task) + if err != nil { + log.Info("getCloudBrainOneResourceSpec err:", err) + return "", err + } else { + if resourceSpec == nil || gpuInfo == nil { + err := errors.New("resourceSpec or gpuInfo is nil") + return "", err + } else { + CloudbrainOneFlavorName := "GPU:" + strconv.Itoa(resourceSpec.GpuNum) + "*Nvidia-" + gpuInfo.Value + + " | CPU:" + strconv.Itoa(resourceSpec.CpuNum) + "核" + strconv.Itoa(resourceSpec.MemMiB) + "MB" + return CloudbrainOneFlavorName, nil + } + } + } else if (task.Type == models.TypeCloudBrainTwo || task.Type == models.TypeC2Net) && task.FlavorName != "" { + replaceFlavorName := strings.ReplaceAll(task.FlavorName, ":", ":") + return replaceFlavorName, nil + } else if task.Type == models.TypeCloudBrainTwo && task.FlavorName == "" && task.FlavorCode != "" { + cloudbrainTwoFlavorName := getFlavorNameByFlavorCode(task.FlavorCode) + return cloudbrainTwoFlavorName, nil + } else if task.Type == models.TypeCloudBrainTwo && task.JobType == string(models.JobTypeDebug) && task.FlavorName == "" && task.FlavorCode == "" { + tasks, err := models.GetModelartsReDebugTaskByJobId(task.JobID) + if err != nil { + return "", err + } + if len(tasks) >= 1 { + return getFlavorNameByFlavorCode(tasks[0].FlavorCode), nil + } + return "", nil + } + return "", nil +} + +func getCloudBrainOneResourceSpec(task models.Cloudbrain) (*models.ResourceSpec, *models.GpuInfo, error) { + gpuQueueDefault := "openidebug" + if task.GpuQueue != "" { + gpuQueueDefault = task.GpuQueue + } + if task.ResourceSpecId >= 0 { + if task.JobType == string(models.JobTypeTrain) { + if models.CloudbrainTrainResourceSpecsMap[task.ResourceSpecId] != nil { + return models.CloudbrainTrainResourceSpecsMap[task.ResourceSpecId], models.CloudbrainTrainGpuInfosMap[gpuQueueDefault], nil + } else { + return models.CloudbrainSpecialResourceSpecsMap[task.ResourceSpecId], models.CloudbrainSpecialGpuInfosMap[gpuQueueDefault], nil + } + } else if task.JobType == string(models.JobTypeDebug) { + if models.CloudbrainDebugResourceSpecsMap[task.ResourceSpecId] != nil { + return models.CloudbrainDebugResourceSpecsMap[task.ResourceSpecId], models.CloudbrainDebugGpuInfosMap[gpuQueueDefault], nil + } else { + return models.CloudbrainSpecialResourceSpecsMap[task.ResourceSpecId], models.CloudbrainSpecialGpuInfosMap[gpuQueueDefault], nil + } + } else if task.JobType == string(models.JobTypeInference) { + return models.CloudbrainInferenceResourceSpecsMap[task.ResourceSpecId], models.CloudbrainInferenceGpuInfosMap[gpuQueueDefault], nil + } else if task.JobType == string(models.JobTypeBenchmark) || task.JobType == string(models.JobTypeSnn4imagenet) || task.JobType == string(models.JobTypeBrainScore) { + return models.CloudbrainBenchmarkResourceSpecsMap[task.ResourceSpecId], models.CloudbrainBenchmarkGpuInfosMap[gpuQueueDefault], nil + } + } else { + err := errors.New("ResourceSpecId is null") + return nil, nil, err + } + return nil, nil, nil +} +func getFlavorNameByFlavorCode(flavorCode string) string { + index := strings.LastIndex(flavorCode, ".") + cardNum, err := strconv.Atoi(strings.TrimSpace(flavorCode[index+1 : len(flavorCode)])) + if err != nil { + log.Error("strconv.Atoi failed: %v", err) + return "" + } + cloudbrainTwoFlavorName := "Ascend:" + strings.TrimSpace(flavorCode[index+1:len(flavorCode)]) + + "*Ascend-910(" + strconv.Itoa(cardNum*32) + "GB)|ARM:" + strconv.Itoa(cardNum*24) + + "核" + strconv.Itoa(cardNum*256) + "GB" + return cloudbrainTwoFlavorName +} diff --git a/routers/repo/grampus.go b/routers/repo/grampus.go index 978b7462de..76f2bd98c5 100755 --- a/routers/repo/grampus.go +++ b/routers/repo/grampus.go @@ -1,15 +1,8 @@ package repo import ( - "code.gitea.io/gitea/modules/auth" - "code.gitea.io/gitea/modules/git" - "code.gitea.io/gitea/modules/grampus" - "code.gitea.io/gitea/modules/modelarts" - "code.gitea.io/gitea/modules/timeutil" - "code.gitea.io/gitea/modules/util" "encoding/json" "errors" - "github.com/unknwon/com" "io/ioutil" "net/http" "os" @@ -18,6 +11,15 @@ import ( "strings" "time" + "code.gitea.io/gitea/modules/auth" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/grampus" + "code.gitea.io/gitea/modules/modelarts" + "code.gitea.io/gitea/modules/notification" + "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" + "github.com/unknwon/com" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/cloudbrain" @@ -64,7 +66,7 @@ func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) err ctx.Data["PageIsCloudBrain"] = true t := time.Now() - var displayJobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] + var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] ctx.Data["display_job_name"] = displayJobName //get valid images @@ -469,7 +471,7 @@ func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain //todo: upload code (send to file_server todo this work?) if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.OutputPath); err != nil { log.Error("Failed to obsMkdir_output: %s (%v)", repo.FullName(), err) - grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) + grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) ctx.RenderWithErr("Failed to obsMkdir_output", tplGrampusTrainJobNPUNew, &form) return } @@ -550,12 +552,15 @@ func GrampusStopJob(ctx *context.Context) { errorMsg = res.ErrorMsg break } - + oldStatus := task.Status task.Status = string(models.GrampusStatusStopped) if task.EndTime == 0 { task.EndTime = timeutil.TimeStampNow() } task.ComputeAndSetDuration() + if oldStatus != task.Status { + notification.NotifyChangeCloudbrainStatus(task, oldStatus) + } err = models.UpdateJob(task) if err != nil { log.Error("UpdateJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"]) @@ -626,7 +631,7 @@ func GrampusTrainJobShow(ctx *context.Context) { task, err := models.GetCloudbrainByJobIDWithDeleted(ctx.Params(":jobid")) if err != nil { log.Error("GetCloudbrainByJobID failed:" + err.Error()) - ctx.ServerError("system error", err) + ctx.NotFound(ctx.Req.URL.RequestURI(), nil) return } @@ -634,14 +639,15 @@ func GrampusTrainJobShow(ctx *context.Context) { result, err := grampus.GetJob(task.JobID) if err != nil { log.Error("GetJob failed:" + err.Error()) - //ctx.ServerError("GetJob failed", err) - //return + ctx.NotFound(ctx.Req.URL.RequestURI(), nil) + return } if result != nil { if len(result.JobInfo.Tasks[0].CenterID) == 1 && len(result.JobInfo.Tasks[0].CenterName) == 1 { task.AiCenter = result.JobInfo.Tasks[0].CenterID[0] + "+" + result.JobInfo.Tasks[0].CenterName[0] } + oldStatus := task.Status task.Status = grampus.TransTrainJobStatus(result.JobInfo.Status) if task.Status != result.JobInfo.Status || result.JobInfo.Status == models.GrampusStatusRunning { task.Duration = result.JobInfo.RunSec @@ -654,6 +660,9 @@ func GrampusTrainJobShow(ctx *context.Context) { task.EndTime = task.StartTime.Add(task.Duration) } task.CorrectCreateUnix() + if oldStatus != task.Status { + notification.NotifyChangeCloudbrainStatus(task, oldStatus) + } err = models.UpdateJob(task) if err != nil { log.Error("UpdateJob failed:" + err.Error()) diff --git a/routers/repo/modelarts.go b/routers/repo/modelarts.go index 4aff5c9e36..43f4a6e73b 100755 --- a/routers/repo/modelarts.go +++ b/routers/repo/modelarts.go @@ -265,33 +265,38 @@ func NotebookShow(ctx *context.Context) { var ID = ctx.Params(":id") task, err := models.GetCloudbrainByIDWithDeleted(ID) if err != nil { - ctx.Data["error"] = err.Error() - ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil) + log.Error("GET job error", err.Error()) + ctx.NotFound(ctx.Req.URL.RequestURI(), nil) return } result, err := modelarts.GetNotebook2(task.JobID) if err != nil { - ctx.Data["error"] = err.Error() - ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil) + log.Error("GET job error", err.Error()) + ctx.NotFound(ctx.Req.URL.RequestURI(), nil) return } if result != nil { if task.DeletedAt.IsZero() { //normal record if task.Status != result.Status { + oldStatus := task.Status task.Status = result.Status models.ParseAndSetDurationFromModelArtsNotebook(result, task) + notification.NotifyChangeCloudbrainStatus(task, oldStatus) err = models.UpdateJob(task) if err != nil { - ctx.Data["error"] = err.Error() - ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil) + log.Error("GET job error", err.Error()) + ctx.NotFound(ctx.Req.URL.RequestURI(), nil) return } } } else { //deleted record } + if task.FlavorCode == "" { + task.FlavorCode = result.Flavor + } } datasetDownload := make([]models.DatasetDownload, 0) @@ -526,6 +531,8 @@ func NotebookManage(ctx *context.Context) { Description: task.Description, CreatedUnix: createTime, UpdatedUnix: createTime, + FlavorCode: task.FlavorCode, + FlavorName: task.FlavorName, } err = models.RestartCloudbrain(task, newTask) @@ -538,11 +545,15 @@ func NotebookManage(ctx *context.Context) { ID = strconv.FormatInt(newTask.ID, 10) notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, ID, task.DisplayJobName, models.ActionCreateDebugNPUTask) } else { + oldStatus := task.Status task.Status = res.Status if task.EndTime == 0 && models.IsModelArtsDebugJobTerminal(task.Status) { task.EndTime = timeutil.TimeStampNow() } task.ComputeAndSetDuration() + if oldStatus != task.Status { + notification.NotifyChangeCloudbrainStatus(task, oldStatus) + } err = models.UpdateJob(task) if err != nil { log.Error("UpdateJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) @@ -567,7 +578,7 @@ func NotebookDel(ctx *context.Context) { var listType = ctx.Query("debugListType") task := ctx.Cloudbrain - if task.Status != string(models.ModelArtsCreateFailed) && task.Status != string(models.ModelArtsStartFailed) && task.Status != string(models.ModelArtsStopped) { + if task.Status != string(models.ModelArtsCreateFailed) && task.Status != string(models.ModelArtsStartFailed) && task.Status != string(models.ModelArtsStopped) && task.Status != string(models.ModelArtsDeleted) { log.Error("the job(%s) has not been stopped", task.JobName) ctx.RenderWithErr("the job has not been stopped", tplDebugJobIndex, nil) return @@ -680,7 +691,7 @@ func trainJobNewDataPrepare(ctx *context.Context) error { //} t := time.Now() - var displayJobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] + var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] ctx.Data["display_job_name"] = displayJobName attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) @@ -785,7 +796,7 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts //} t := time.Now() - var displayJobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] + var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] ctx.Data["display_job_name"] = displayJobName attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) @@ -838,6 +849,12 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts ctx.Data["config_list"] = configList.ParaConfigs ctx.Data["bootFile"] = form.BootFile ctx.Data["uuid"] = form.Attachment + _, datasetNames, err := models.GetDatasetInfo(form.Attachment) + if err != nil { + log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"]) + return nil + } + ctx.Data["dataset_name"] = datasetNames ctx.Data["branch_name"] = form.BranchName ctx.Data["datasetType"] = models.TypeCloudBrainTwo @@ -962,7 +979,7 @@ func versionErrorDataPrepare(ctx *context.Context, form auth.CreateModelArtsTrai } t := time.Now() - var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] + var jobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] ctx.Data["job_name"] = task.JobName attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) @@ -1727,7 +1744,11 @@ func TrainJobShow(ctx *context.Context) { if err != nil { log.Error("GetVersionListTasks(%s) failed:%v", jobID, err.Error()) - ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil) + ctx.NotFound(ctx.Req.URL.RequestURI(), nil) + return + } + if len(VersionListTasks) == 0 { + ctx.NotFound(ctx.Req.URL.RequestURI(), nil) return } //设置权限 @@ -2305,7 +2326,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { ctx.Data["newInference"] = true t := time.Now() - var displayJobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] + var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] ctx.Data["display_job_name"] = displayJobName attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) @@ -2429,6 +2450,12 @@ func inferenceJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModel ctx.Data["config_list"] = configList.ParaConfigs ctx.Data["bootFile"] = form.BootFile ctx.Data["uuid"] = form.Attachment + _, datasetNames, err := models.GetDatasetInfo(form.Attachment) + if err != nil { + log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"]) + return nil + } + ctx.Data["dataset_name"] = datasetNames ctx.Data["branch_name"] = form.BranchName ctx.Data["model_name"] = form.ModelName ctx.Data["model_version"] = form.ModelVersion @@ -2450,7 +2477,7 @@ func InferenceJobShow(ctx *context.Context) { if err != nil { log.Error("GetInferenceTask(%s) failed:%v", jobID, err.Error()) - ctx.RenderWithErr(err.Error(), tplModelArtsInferenceJobShow, nil) + ctx.NotFound(ctx.Req.URL.RequestURI(), nil) return } //设置权限 diff --git a/routers/repo/user_data_analysis.go b/routers/repo/user_data_analysis.go index ac1265d045..508addf755 100755 --- a/routers/repo/user_data_analysis.go +++ b/routers/repo/user_data_analysis.go @@ -5,6 +5,8 @@ import ( "net/http" "net/url" "os" + "strconv" + "strings" "time" "code.gitea.io/gitea/models" @@ -404,7 +406,7 @@ func queryMetrics(ctx *context.Context, tableName string, startTime time.Time, e if tableName == "public.user_business_analysis_yesterday" { mapInterface["datarecordbegintime"] = setting.RadarMap.GrowthBeginTime if len(result) > 0 { - dateTime := time.Unix(result[0].CountDate, 0) + dateTime := time.Unix(result[0].CountDate, 0).AddDate(0, 0, 1) mapInterface["lastUpdatedTime"] = dateTime.Format("2006-01-02 15:04:05") } else { mapInterface["lastUpdatedTime"] = "" @@ -450,7 +452,7 @@ func DownloadUserDefineFile(ctx *context.Context) { func QueryUserMetricsCurrentMonth(ctx *context.Context) { currentTimeNow := time.Now() - pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) + pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location()) pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), 1, 0, 0, 0, 0, currentTimeNow.Location()) pageStartTime = getStartTime(pageStartTime) queryMetrics(ctx, "public.user_business_analysis_current_month", pageStartTime, pageEndTime) @@ -476,7 +478,7 @@ func QueryUserMetricsCurrentWeek(ctx *context.Context) { } pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset) pageStartTime = getStartTime(pageStartTime) - pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) + pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location()) queryMetrics(ctx, "public.user_business_analysis_current_week", pageStartTime, pageEndTime) } func QueryUserStaticCurrentWeek(ctx *context.Context) { @@ -490,7 +492,7 @@ func QueryUserMetricsCurrentYear(ctx *context.Context) { currentTimeNow := time.Now() pageStartTime := time.Date(currentTimeNow.Year(), 1, 1, 0, 0, 0, 0, currentTimeNow.Location()) pageStartTime = getStartTime(pageStartTime) - pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) + pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location()) queryMetrics(ctx, "public.user_business_analysis_current_year", pageStartTime, pageEndTime) } func QueryUserStaticCurrentYear(ctx *context.Context) { @@ -500,7 +502,7 @@ func QueryUserMetricsLast30Day(ctx *context.Context) { currentTimeNow := time.Now() pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, -30) pageStartTime = getStartTime(pageStartTime) - pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) + pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location()) queryMetrics(ctx, "public.user_business_analysis_last30_day", pageStartTime, pageEndTime) } func QueryUserStaticLast30Day(ctx *context.Context) { @@ -518,7 +520,7 @@ func QueryUserStaticLastMonth(ctx *context.Context) { queryUserDataPage(ctx, "public.user_business_analysis_last_month", new(models.UserBusinessAnalysisLastMonth)) } func QueryUserMetricsYesterday(ctx *context.Context) { - currentTimeNow := time.Now() + currentTimeNow := time.Now().AddDate(0, 0, -1) pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local) pageStartTime = getStartTime(pageStartTime) pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) @@ -531,7 +533,7 @@ func QueryUserMetricsAll(ctx *context.Context) { currentTimeNow := time.Now() pageStartTime := time.Date(2022, 4, 5, 0, 0, 0, 0, currentTimeNow.Location()) pageStartTime = getStartTime(pageStartTime) - pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) + pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, currentTimeNow.Location()) queryMetrics(ctx, "public.user_business_analysis_all", pageStartTime, pageEndTime) } func QueryUserStaticAll(ctx *context.Context) { @@ -611,7 +613,15 @@ func QueryUserStaticDataPage(ctx *context.Context) { ctx.JSON(http.StatusOK, ctx.Tr("user.static.downloadinfo")+"/api/v1/download_user_define_file?filename="+filename) } else { mapInterface := make(map[string]interface{}) - re, count := models.QueryUserStaticDataPage(pageOpts) + key := startTime.Format("2006-01-02") + endTime.Format("2006-01-02") + log.Info("db key =" + key) + re, count := models.QueryDataForUserDefineFromDb(pageOpts, key) + if count == 0 { + wikiMap, _ := queryWikiCountMap(startTime, endTime) + re, count = models.QueryUserStaticDataForUserDefine(pageOpts, wikiMap) + models.WriteDataToDb(re, key) + } + re, count = models.QueryDataForUserDefineFromDb(pageOpts, key) mapInterface["data"] = re mapInterface["count"] = count ctx.JSON(http.StatusOK, mapInterface) @@ -839,3 +849,61 @@ func writeUserActivityToExcel(startTime time.Time, endTime time.Time, filePath s log.Info("write to file succeed, filepath=" + filePath) } } + +// URL: /api/v1/query_user_login?userId=1,2,3,4 +func QueryUserLoginInfo(ctx *context.Context) { + userId := ctx.Query("userId") + userIds := strings.Split(userId, ",") + userIdInt := make([]int64, 0) + for _, id := range userIds { + idInt, err := strconv.ParseInt(id, 10, 64) + if err == nil { + userIdInt = append(userIdInt, idInt) + } + } + result := models.QueryUserLoginInfo(userIdInt) + + xlsx := excelize.NewFile() + sheetName := ctx.Tr("用户登录信息") + index := xlsx.NewSheet(sheetName) + xlsx.DeleteSheet("Sheet1") + + excelHeader := make([]string, 0) + excelHeader = append(excelHeader, "用户ID") + excelHeader = append(excelHeader, "登录IP") + excelHeader = append(excelHeader, "登录时间") + + excelHeaderMap := make(map[string]string, 0) + var j byte + j = 0 + for _, value := range excelHeader { + excelColumn := getColumn(j) + fmt.Sprint(1) + log.Info("excelColumn=" + excelColumn) + excelHeaderMap[excelColumn] = value + j++ + } + for k, v := range excelHeaderMap { + //设置单元格的值 + xlsx.SetCellValue(sheetName, k, v) + } + for i, userLogin := range result { + row := i + 2 + rows := fmt.Sprint(row) + var tmp byte + tmp = 0 + xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userLogin.UId) + tmp = tmp + 1 + xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userLogin.IpAddr) + tmp = tmp + 1 + formatTime := userLogin.CreatedUnix.Format("2006-01-02 15:04:05") + xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, formatTime) + } + //设置默认打开的表单 + xlsx.SetActiveSheet(index) + filename := sheetName + "_" + time.Now().Format("2006-01-02 15:04:05") + ".xlsx" + ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(filename)) + ctx.Resp.Header().Set("Content-Type", "application/octet-stream") + if _, err := xlsx.WriteTo(ctx.Resp); err != nil { + log.Info("writer exel error." + err.Error()) + } +} diff --git a/routers/repo/view.go b/routers/repo/view.go index 02004fa06c..3a18e4ddf0 100755 --- a/routers/repo/view.go +++ b/routers/repo/view.go @@ -484,6 +484,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st ) } else if isNoteBook { ctx.Data["FileContent"] = string(buf) + ctx.Data["FileParentURL"] = path.Dir(rawLink+"/"+ctx.Repo.TreePath) + "/" } else { // Building code view blocks with line number on server side. var fileContent string diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 35a26f5852..03b53c5cd8 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -1016,6 +1016,7 @@ func RegisterRoutes(m *macaron.Macaron) { }, context.RepoAssignment(), context.RepoMustNotBeArchived(), reqRepoAdmin) m.Group("/image/:id", func() { + m.Get("", repo.GetImage) m.Get("/:from", cloudbrain.AdminOrImageCreaterRight, repo.CloudBrainImageEdit) m.Post("", cloudbrain.AdminOrImageCreaterRight, bindIgnErr(auth.EditImageCloudBrainForm{}), repo.CloudBrainImageEditPost) m.Delete("", cloudbrain.AdminOrImageCreaterRight, repo.CloudBrainImageDelete) @@ -1135,7 +1136,7 @@ func RegisterRoutes(m *macaron.Macaron) { }) }, context.RepoRef()) m.Group("/modelmanage", func() { - m.Post("/create_model", reqRepoModelManageWriter, repo.SaveModel) + m.Post("/create_model", repo.SaveModel) m.Post("/create_model_convert", reqRepoModelManageWriter, repo.SaveModelConvert) m.Post("/create_new_model", repo.SaveNewNameModel) m.Delete("/delete_model", repo.DeleteModel) diff --git a/routers/search.go b/routers/search.go index 05074df55c..6283504245 100644 --- a/routers/search.go +++ b/routers/search.go @@ -313,9 +313,8 @@ func searchRepo(ctx *context.Context, TableName string, Key string, Page int, Pa res, err := client.Search(TableName).Query(boolQ).SortBy(getSort(SortBy, ascending, "num_stars", false)...).From(from).Size(Size).Highlight(queryHighlight("alias", "description", "topics")).Do(ctx.Req.Context()) if err == nil { - searchJson, _ := json.Marshal(res) - log.Info("searchJson=" + string(searchJson)) esresult := makeRepoResult(res, Key, OnlyReturnNum, language) + setForkRepoOrder(esresult) resultObj.Total = resultObj.PrivateTotal + esresult.Total isNeedSort := false if len(resultObj.Result) > 0 { @@ -348,6 +347,30 @@ func searchRepo(ctx *context.Context, TableName string, Key string, Page int, Pa } } +func setForkRepoOrder(esresult *SearchRes) { + forkidMap := make(map[string]int, 0) + for index, re := range esresult.Result { + if re["fork_id"] != nil { + fork_id := re["fork_id"].(string) + if _, ok := forkidMap[fork_id]; !ok { + forkidMap[fork_id] = index + } + } + } + for key, value := range forkidMap { + for index, re := range esresult.Result { + if re["id"].(string) == key { + if value < index { //swap + tmp := esresult.Result[index] + esresult.Result[index] = esresult.Result[value] + esresult.Result[value] = tmp + break + } + } + } + } +} + func sortRepo(Result []map[string]interface{}, SortBy string, ascending bool) { orderBy := "" switch SortBy { @@ -479,6 +502,7 @@ func makeRepoResult(sRes *elastic.SearchResult, Key string, OnlyReturnNum bool, record["num_stars"] = recordSource["num_stars"] record["num_forks"] = recordSource["num_forks"] record["lower_alias"] = recordSource["lower_alias"] + record["fork_id"] = recordSource["fork_id"] if recordSource["topics"] != nil { topicsStr := recordSource["topics"].(string) log.Info("topicsStr=" + topicsStr) diff --git a/routers/user/home.go b/routers/user/home.go index ab64e707f3..25b1c518ed 100755 --- a/routers/user/home.go +++ b/routers/user/home.go @@ -23,6 +23,7 @@ import ( "code.gitea.io/gitea/modules/modelarts" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/routers/repo" issue_service "code.gitea.io/gitea/services/issue" pull_service "code.gitea.io/gitea/services/pull" @@ -834,6 +835,11 @@ func Cloudbrains(ctx *context.Context) { ciTasks[i].CanDebug = true ciTasks[i].CanDel = true ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource + ciTasks[i].Cloudbrain.AiCenter = repo.GetCloudbrainAiCenter(task.Cloudbrain, ctx) + _, cardType, _ := repo.GetCloudbrainCardNumAndType(task.Cloudbrain) + ciTasks[i].Cloudbrain.CardType = cardType + ciTasks[i].Cloudbrain.Cluster = repo.GetCloudbrainCluster(task.Cloudbrain, ctx) + } pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, getTotalPage(count, setting.UI.IssuePagingNum)) diff --git a/routers/user/profile.go b/routers/user/profile.go index 30808f2353..42cdfd1a85 100755 --- a/routers/user/profile.go +++ b/routers/user/profile.go @@ -116,8 +116,8 @@ func Profile(ctx *context.Context) { } var opts = models.FindOrgMembersOpts{ - OrgID: org.ID, - PublicOnly: true, + OrgID: org.ID, + PublicOnly: true, } if ctx.User != nil { @@ -261,7 +261,7 @@ func Profile(ctx *context.Context) { IsOwner: isOwner, ListOptions: models.ListOptions{ Page: page, - PageSize: setting.UI.ExplorePagingNum, + PageSize: setting.UI.User.RepoPagingNum, }, CloudBrainType: -1, } diff --git a/templates/admin/cloudbrain/list.tmpl b/templates/admin/cloudbrain/list.tmpl index e66f40e84a..cd5913c407 100755 --- a/templates/admin/cloudbrain/list.tmpl +++ b/templates/admin/cloudbrain/list.tmpl @@ -18,7 +18,7 @@ data-all-compute="{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}" data-all-status="{{.i18n.Tr "admin.cloudbrain.all_status"}}"> {{template "admin/navbar" .}} -
+
{{template "base/alert" .}}
@@ -34,34 +34,46 @@
-
- {{$.i18n.Tr "repo.cloudbrain_task"}} +
+ {{$.i18n.Tr "repo.cloudbrain_task"}}
-
- {{$.i18n.Tr "repo.cloudbrain_task_type"}} + +
+ {{$.i18n.Tr "repo.modelarts.cluster"}}
-
+
+ {{$.i18n.Tr "repo.cloudbrain_task_type"}} +
+
{{$.i18n.Tr "repo.modelarts.status"}}
-
+
{{$.i18n.Tr "repo.modelarts.createtime"}}
-
+
{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}
-
+
{{$.i18n.Tr "repo.modelarts.computing_resources"}}
-
+ +
+ {{$.i18n.Tr "repo.modelarts.ai_center"}} +
+ +
+ {{$.i18n.Tr "repo.modelarts.card_type"}} +
+
{{$.i18n.Tr "repo.cloudbrain_creator"}}
-
+
{{$.i18n.Tr "repository"}}
-
+
{{.i18n.Tr "admin.cloudbrain.cloudbrain_name"}}
-
+
{{$.i18n.Tr "repo.cloudbrain_operate"}}
@@ -78,24 +90,24 @@ {{$JobID = .JobID}} {{end}} -
+ - -
- {{.JobType}} + +
+ {{if .Cluster}}{{.Cluster}}{{else}}--{{end}}
+ style="width: 6% !important;"> @@ -131,23 +144,39 @@ style="margin-left: 0.4em;font-size: 12px;">{{.Status}}
+ +
+ {{.JobType}} +
+ -
+
{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}
-
+
{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}
-
+
{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}
+ +
+ {{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}} +
+ +
+ + {{if .CardType}}{{.CardType}}{{else}}--{{end}} + +
-
+
{{if .User.Name}} @@ -157,16 +186,24 @@ {{end}}
-
+
- {{.JobName}} + style="overflow: hidden;text-overflow:ellipsis;width:10% !important;"> + + {{.JobName}} +
-
+
{{if eq .JobType "DEBUG"}}
@@ -235,36 +272,37 @@
-
+
{{if eq .JobType "DEBUG"}} - + {{.DisplayJobName}} {{else if eq .JobType "INFERENCE"}} - + {{.DisplayJobName}} {{else if eq .JobType "TRAIN"}} - + {{.DisplayJobName}} {{else if eq .JobType "BENCHMARK"}} - + {{.DisplayJobName}} {{end}}
- -
- {{.JobType}} + +
+ {{if .Cluster}}{{.Cluster}}{{else}}--{{end}}
+ style="width: 6% !important;"> {{.Status}}
+ +
+ {{.JobType}} +
+ -
+
{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}
-
+
{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}
-
+
{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}
+ +
+ {{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}} +
+ +
+ + {{if .CardType}}{{.CardType}}{{else}}--{{end}} + +
-
+
{{if .User.Name}} @@ -298,15 +352,24 @@ {{end}}
-
+
--
- {{.JobName}} + style="overflow: hidden;text-overflow:ellipsis;width:10% !important;"> + + {{.JobName}} + +
-
+
{{if eq .JobType "DEBUG"}}
diff --git a/templates/admin/cloudbrain/search_dashboard.tmpl b/templates/admin/cloudbrain/search_dashboard.tmpl index 61f02f182f..e4d74836de 100644 --- a/templates/admin/cloudbrain/search_dashboard.tmpl +++ b/templates/admin/cloudbrain/search_dashboard.tmpl @@ -15,7 +15,7 @@
-
+
diff --git a/templates/admin/dataset/list.tmpl b/templates/admin/dataset/list.tmpl index 9e4e72b683..9712f2e7b5 100644 --- a/templates/admin/dataset/list.tmpl +++ b/templates/admin/dataset/list.tmpl @@ -35,7 +35,7 @@ {{range .Datasets}} {{.ID}} - {{.Title}}{{if .Recommend}}{{end}} + {{.Title}}{{if .Recommend}}{{end}} {{.CreatedUnix.FormatShort}} {{if .Recommend}}{{$.i18n.Tr "admin.datasets.unrecommend"}}{{else}}{{$.i18n.Tr "admin.datasets.recommend"}}{{end}} @@ -48,4 +48,4 @@ {{template "base/paginate" .}}
-{{template "base/footer" .}} +{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl index 937abd5887..4ab9da2319 100755 --- a/templates/base/head.tmpl +++ b/templates/base/head.tmpl @@ -109,6 +109,11 @@ ], {{end}} }; + {{if .IsSigned}} + window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}'); + {{else}} + window.sessionStorage.removeItem('_csrf'); + {{end}} diff --git a/templates/base/head_course.tmpl b/templates/base/head_course.tmpl index 3fff0b8d2b..fe21a0e05b 100644 --- a/templates/base/head_course.tmpl +++ b/templates/base/head_course.tmpl @@ -109,6 +109,11 @@ ], {{end}} }; + {{if .IsSigned}} + window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}'); + {{else}} + window.sessionStorage.removeItem('_csrf'); + {{end}} diff --git a/templates/base/head_fluid.tmpl b/templates/base/head_fluid.tmpl index 5340c7cb89..1c16e71402 100644 --- a/templates/base/head_fluid.tmpl +++ b/templates/base/head_fluid.tmpl @@ -109,6 +109,11 @@ ], {{end}} }; + {{if .IsSigned}} + window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}'); + {{else}} + window.sessionStorage.removeItem('_csrf'); + {{end}} diff --git a/templates/base/head_home.tmpl b/templates/base/head_home.tmpl index 2def358f83..a77d7b00a9 100644 --- a/templates/base/head_home.tmpl +++ b/templates/base/head_home.tmpl @@ -109,6 +109,11 @@ ], {{end}} }; + {{if .IsSigned}} + window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}'); + {{else}} + window.sessionStorage.removeItem('_csrf'); + {{end}} diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index 51761a7e5e..a5a898ad03 100755 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -42,7 +42,8 @@ {{.i18n.Tr "explore.organizations"}} {{.i18n.Tr "explore.images"}} {{if .IsOperator}} - {{.i18n.Tr "explore.data_analysis"}} + {{/* {{.i18n.Tr "explore.data_analysis"}} */}} + {{.i18n.Tr "explore.data_analysis"}} {{end}} {{.i18n.Tr "custom.head.openi.repo"}}
@@ -73,7 +74,8 @@ {{.i18n.Tr "explore.organizations"}} {{.i18n.Tr "explore.images"}} {{if .IsOperator}} - {{.i18n.Tr "explore.data_analysis"}} + {{/* {{.i18n.Tr "explore.data_analysis"}} */}} + {{.i18n.Tr "explore.data_analysis"}} {{end}} {{.i18n.Tr "custom.head.openi.repo"}}
diff --git a/templates/base/head_navbar_fluid.tmpl b/templates/base/head_navbar_fluid.tmpl index 6baeced54c..84781db116 100644 --- a/templates/base/head_navbar_fluid.tmpl +++ b/templates/base/head_navbar_fluid.tmpl @@ -41,7 +41,8 @@ {{.i18n.Tr "explore.organizations"}} {{.i18n.Tr "explore.images"}} {{if .IsOperator}} - {{.i18n.Tr "explore.data_analysis"}} + {{/* {{.i18n.Tr "explore.data_analysis"}} */}} + {{.i18n.Tr "explore.data_analysis"}} {{end}} {{.i18n.Tr "custom.head.openi.repo"}}
@@ -71,7 +72,8 @@ {{.i18n.Tr "explore.organizations"}} {{.i18n.Tr "explore.images"}} {{if .IsOperator}} - {{.i18n.Tr "explore.data_analysis"}} + {{/* {{.i18n.Tr "explore.data_analysis"}} */}} + {{.i18n.Tr "explore.data_analysis"}} {{end}} {{.i18n.Tr "custom.head.openi.repo"}}
diff --git a/templates/base/head_navbar_home.tmpl b/templates/base/head_navbar_home.tmpl index c9ea13b8a3..64e04b4c3f 100644 --- a/templates/base/head_navbar_home.tmpl +++ b/templates/base/head_navbar_home.tmpl @@ -33,7 +33,8 @@ {{.i18n.Tr "explore.organizations"}} {{.i18n.Tr "explore.images"}} {{if .IsOperator}} - {{.i18n.Tr "explore.data_analysis"}} + {{/* {{.i18n.Tr "explore.data_analysis"}} */}} + {{.i18n.Tr "explore.data_analysis"}} {{end}} {{.i18n.Tr "custom.head.openi.repo"}}
@@ -64,7 +65,8 @@ {{.i18n.Tr "explore.organizations"}} {{.i18n.Tr "explore.images"}} {{if .IsOperator}} - {{.i18n.Tr "explore.data_analysis"}} + {{/* {{.i18n.Tr "explore.data_analysis"}} */}} + {{.i18n.Tr "explore.data_analysis"}} {{end}} {{.i18n.Tr "custom.head.openi.repo"}}
diff --git a/templates/base/head_navbar_pro.tmpl b/templates/base/head_navbar_pro.tmpl index e744508f09..e9f662bbe6 100644 --- a/templates/base/head_navbar_pro.tmpl +++ b/templates/base/head_navbar_pro.tmpl @@ -43,7 +43,8 @@ {{.i18n.Tr "explore.organizations"}} {{.i18n.Tr "explore.images"}} {{if .IsOperator}} - {{.i18n.Tr "explore.data_analysis"}} + {{/* {{.i18n.Tr "explore.data_analysis"}} */}} + {{.i18n.Tr "explore.data_analysis"}} {{end}} {{.i18n.Tr "custom.head.openi.repo"}}
@@ -74,7 +75,8 @@ {{.i18n.Tr "explore.organizations"}} {{.i18n.Tr "explore.images"}} {{if .IsOperator}} - {{.i18n.Tr "explore.data_analysis"}} + {{/* {{.i18n.Tr "explore.data_analysis"}} */}} + {{.i18n.Tr "explore.data_analysis"}} {{end}} {{.i18n.Tr "custom.head.openi.repo"}}
diff --git a/templates/base/head_pro.tmpl b/templates/base/head_pro.tmpl index 75292b6fc0..c643ea873e 100644 --- a/templates/base/head_pro.tmpl +++ b/templates/base/head_pro.tmpl @@ -109,6 +109,11 @@ ], {{end}} }; + {{if .IsSigned}} + window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}'); + {{else}} + window.sessionStorage.removeItem('_csrf'); + {{end}} diff --git a/templates/custom/select_dataset_train.tmpl b/templates/custom/select_dataset_train.tmpl index 27730cf16d..d7dbb055a5 100755 --- a/templates/custom/select_dataset_train.tmpl +++ b/templates/custom/select_dataset_train.tmpl @@ -9,6 +9,7 @@ {{end}} --> + {{if .benchmarkMode}}{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}{{else}}{{.i18n.Tr "dataset.select_dataset"}}{{end}} diff --git a/templates/explore/dataset_list.tmpl b/templates/explore/dataset_list.tmpl index 1d22b62ec1..a0f1711950 100755 --- a/templates/explore/dataset_list.tmpl +++ b/templates/explore/dataset_list.tmpl @@ -24,9 +24,9 @@
{{range .Datasets}}
-
- - {{.Repo.OwnerName}} / {{.Repo.Alias}} +
+ + {{.Title}}
{{if .Task}} @@ -40,7 +40,7 @@
{{if .Description}} -

{{.Description}}

+

{{.Description}}

{{else if .Repo.DescriptionHTML}}

{{.Repo.DescriptionHTML}}

{{end}} @@ -53,4 +53,7 @@
{{end}}
-
\ No newline at end of file +
+ \ No newline at end of file diff --git a/templates/org/create.tmpl b/templates/org/create.tmpl index 872140efaa..21b6ebdb46 100644 --- a/templates/org/create.tmpl +++ b/templates/org/create.tmpl @@ -48,7 +48,7 @@ - {{.i18n.Tr "cancel"}} + {{.i18n.Tr "cancel"}}
diff --git a/templates/repo/cloudbrain/benchmark/new.tmpl b/templates/repo/cloudbrain/benchmark/new.tmpl index fb1296d271..e1b5c890eb 100755 --- a/templates/repo/cloudbrain/benchmark/new.tmpl +++ b/templates/repo/cloudbrain/benchmark/new.tmpl @@ -69,8 +69,8 @@ - {{.i18n.Tr "cloudbrain.job_name_rule"}} + tabindex="3" autofocus required maxlength="36"> + {{.i18n.Tr "repo.cloudbrain_jobname_err"}}
- {{.i18n.Tr "cloudbrain.job_name_rule"}} + tabindex="3" autofocus required maxlength="36"> + {{.i18n.Tr "repo.cloudbrain_jobname_err"}}