Reviewed-on: https://git.openi.org.cn/OpenI/aiforge/pulls/2648tags/v1.22.7.2
| @@ -55,6 +55,7 @@ coverage.all | |||||
| !/custom/conf/templates | !/custom/conf/templates | ||||
| /custom/conf/app.ini | /custom/conf/app.ini | ||||
| !/custom/conf/app.ini.sample | !/custom/conf/app.ini.sample | ||||
| /custom/public/kanban | |||||
| /data | /data | ||||
| /indexers | /indexers | ||||
| /log | /log | ||||
| @@ -54,4 +54,7 @@ | |||||
| ## 平台引用 | ## 平台引用 | ||||
| 如果本平台对您的科研工作提供了帮助,可在论文致谢中加入: | 如果本平台对您的科研工作提供了帮助,可在论文致谢中加入: | ||||
| 英文版:```Thanks for the support provided by OpenI Community (https://git.openi.org.cn).``` | 英文版:```Thanks for the support provided by OpenI Community (https://git.openi.org.cn).``` | ||||
| 中文版:```感谢启智社区提供的技术支持(https://git.openi.org.cn)。``` | |||||
| 中文版:```感谢启智社区提供的技术支持(https://git.openi.org.cn)。``` | |||||
| 如果您的成果中引用了本平台,也欢迎在下述开源项目中提交您的成果信息: | |||||
| https://git.openi.org.cn/OpenIOSSG/references | |||||
| @@ -137,6 +137,8 @@ type Cloudbrain struct { | |||||
| Type int `xorm:"INDEX"` | Type int `xorm:"INDEX"` | ||||
| BenchmarkTypeID int | BenchmarkTypeID int | ||||
| BenchmarkChildTypeID int | BenchmarkChildTypeID int | ||||
| CardType string | |||||
| Cluster string | |||||
| VersionID int64 //版本id | VersionID int64 //版本id | ||||
| VersionName string `xorm:"INDEX"` //当前版本 | VersionName string `xorm:"INDEX"` //当前版本 | ||||
| @@ -206,7 +208,16 @@ func (task *Cloudbrain) CorrectCreateUnix() { | |||||
| func (task *Cloudbrain) IsTerminal() bool { | func (task *Cloudbrain) IsTerminal() bool { | ||||
| status := task.Status | 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 { | func ConvertDurationToStr(duration int64) string { | ||||
| @@ -1669,6 +1680,37 @@ func GetCloudbrainsNeededStopByUserID(userID int64) ([]*Cloudbrain, error) { | |||||
| return cloudBrains, err | 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) { | func GetCloudbrainsNeededStopByRepoID(repoID int64) ([]*Cloudbrain, error) { | ||||
| cloudBrains := make([]*Cloudbrain, 0) | 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) | 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) != "" { | 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 { | if len(opts.CloudbrainIDs) > 0 { | ||||
| @@ -1956,7 +1999,8 @@ func CloudbrainAll(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) { | |||||
| } else { | } else { | ||||
| lowerKeyWord := strings.ToLower(opts.Keyword) | 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). | count, err = sess.Table(&Cloudbrain{}).Unscoped().Where(cond). | ||||
| Join("left", "`user`", condition).Count(new(CloudbrainInfo)) | Join("left", "`user`", condition).Count(new(CloudbrainInfo)) | ||||
| @@ -2034,7 +2078,8 @@ func CloudbrainAllStatic(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, er | |||||
| } | } | ||||
| sess.OrderBy("cloudbrain.created_unix DESC") | sess.OrderBy("cloudbrain.created_unix DESC") | ||||
| cloudbrains := make([]*CloudbrainInfo, 0, setting.UI.IssuePagingNum) | 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 { | Find(&cloudbrains); err != nil { | ||||
| return nil, 0, fmt.Errorf("Find: %v", err) | 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 | 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) { | func GetNewestJobsByAiCenter() ([]int64, error) { | ||||
| ids := make([]int64, 0) | ids := make([]int64, 0) | ||||
| return ids, x. | return ids, x. | ||||
| @@ -29,6 +29,11 @@ type TaskDetail struct { | |||||
| RepoAlias string `json:"RepoAlias"` | RepoAlias string `json:"RepoAlias"` | ||||
| RepoID int64 `json:"RepoID"` | RepoID int64 `json:"RepoID"` | ||||
| IsDelete bool `json:"IsDelete"` | 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) { | func GetDebugOnePeriodCount(beginTime time.Time, endTime time.Time) (int64, error) { | ||||
| @@ -206,21 +211,6 @@ func GetAllStatusCloudBrain() map[string]int { | |||||
| return cloudBrainStatusResult | 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) { | func GetRunningTop() ([]*CloudbrainInfo, error) { | ||||
| sess := x.NewSession() | sess := x.NewSession() | ||||
| defer sess.Close() | defer sess.Close() | ||||
| @@ -158,16 +158,20 @@ DROP TRIGGER IF EXISTS es_update_dataset on public.dataset; | |||||
| CREATE OR REPLACE FUNCTION public.update_dataset() RETURNS trigger AS | CREATE OR REPLACE FUNCTION public.update_dataset() RETURNS trigger AS | ||||
| $def$ | $def$ | ||||
| BEGIN | 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; | return new; | ||||
| END | END | ||||
| $def$ | $def$ | ||||
| @@ -461,7 +461,7 @@ $def$ | |||||
| if not OLD.is_private and NEW.is_private then | if not OLD.is_private and NEW.is_private then | ||||
| delete from public.issue_es where repo_id=NEW.id; | 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; | delete from public.repository_es where id=NEW.id; | ||||
| end if; | end if; | ||||
| @@ -1603,13 +1603,6 @@ func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err e | |||||
| if err != nil { | if err != nil { | ||||
| return err | 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) | dataset, err := GetDatasetByRepo(repo) | ||||
| if err != nil && !IsErrNotExist(err) { | 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 { | } else { | ||||
| //If repo has become public, we need set dataset to public | //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{ | _, err = e.Where("repo_id = ? and status <> 2", repo.ID).Cols("status").Update(&Dataset{ | ||||
| @@ -238,6 +238,9 @@ func GetAllUserPublicRepoKPIStats(startTime time.Time, endTime time.Time) (map[s | |||||
| CommitLines: 0, | 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].Commits += value.Commits | ||||
| authors[key].CommitLines += value.CommitLines | authors[key].CommitLines += value.CommitLines | ||||
| @@ -6,6 +6,7 @@ import ( | |||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/timeutil" | "code.gitea.io/gitea/modules/timeutil" | ||||
| "xorm.io/builder" | |||||
| ) | ) | ||||
| type UserBusinessAnalysisForActivity struct { | type UserBusinessAnalysisForActivity struct { | ||||
| @@ -195,7 +196,7 @@ func queryPullRequestPublic(start_unix int64, end_unix int64, publicAllRepo map[ | |||||
| sess := x.NewSession() | sess := x.NewSession() | ||||
| defer sess.Close() | defer sess.Close() | ||||
| resultMap := make(map[int64]int) | 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)) | count, err := sess.Table("issue").Join("inner", "pull_request", "issue.id=pull_request.issue_id").Where(cond).Count(new(Issue)) | ||||
| if err != nil { | if err != nil { | ||||
| log.Info("query issue error. return.") | log.Info("query issue error. return.") | ||||
| @@ -435,3 +436,16 @@ func queryUserModelPublic(start_unix int64, end_unix int64, publicAllRepo map[in | |||||
| } | } | ||||
| return resultMap | 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 | |||||
| } | |||||
| @@ -110,9 +110,9 @@ type UserBusinessAnalysisAll struct { | |||||
| } | } | ||||
| type UserBusinessAnalysis 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 | //action :ActionMergePullRequest // 11 | ||||
| CodeMergeCount int `xorm:"NOT NULL DEFAULT 0"` | CodeMergeCount int `xorm:"NOT NULL DEFAULT 0"` | ||||
| @@ -171,8 +171,6 @@ type UserBusinessAnalysis struct { | |||||
| //user | //user | ||||
| Name string `xorm:"NOT NULL"` | Name string `xorm:"NOT NULL"` | ||||
| DataDate string `xorm:"NULL"` | |||||
| CloudBrainTaskNum int `xorm:"NOT NULL DEFAULT 0"` | CloudBrainTaskNum int `xorm:"NOT NULL DEFAULT 0"` | ||||
| GpuDebugJob int `xorm:"NOT NULL DEFAULT 0"` | GpuDebugJob int `xorm:"NOT NULL DEFAULT 0"` | ||||
| NpuDebugJob 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 | 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) { | func QueryUserStaticDataForUserDefine(opts *UserBusinessAnalysisQueryOptions, wikiCountMap map[string]int) ([]*UserBusinessAnalysis, int64) { | ||||
| log.Info("start to count other user info data") | log.Info("start to count other user info data") | ||||
| sess := x.NewSession() | sess := x.NewSession() | ||||
| @@ -954,6 +988,9 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time, | |||||
| statictisSess := xStatistic.NewSession() | statictisSess := xStatistic.NewSession() | ||||
| defer statictisSess.Close() | defer statictisSess.Close() | ||||
| log.Info("truncate all data from table:user_business_analysis ") | |||||
| statictisSess.Exec("TRUNCATE TABLE user_business_analysis") | |||||
| cond := "type != 1" | cond := "type != 1" | ||||
| count, err := sess.Where(cond).Count(new(User)) | count, err := sess.Where(cond).Count(new(User)) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -1103,6 +1140,7 @@ func updateNewUserAcitivity(currentUserActivity map[int64]map[int64]int64, userA | |||||
| ",activate_regist_user=" + fmt.Sprint(useMetrics.ActivateRegistUser) + | ",activate_regist_user=" + fmt.Sprint(useMetrics.ActivateRegistUser) + | ||||
| ",not_activate_regist_user=" + fmt.Sprint(useMetrics.CurrentDayRegistUser-useMetrics.ActivateRegistUser) + | ",not_activate_regist_user=" + fmt.Sprint(useMetrics.CurrentDayRegistUser-useMetrics.ActivateRegistUser) + | ||||
| ",current_day_regist_user=" + fmt.Sprint(useMetrics.CurrentDayRegistUser) + | ",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") + "'" + | ",data_date='" + time.Unix(key, 0).Format("2006-01-02") + "'" + | ||||
| " where count_date=" + fmt.Sprint(key) | " where count_date=" + fmt.Sprint(key) | ||||
| @@ -23,6 +23,7 @@ type CreateCloudBrainForm struct { | |||||
| BootFile string `form:"boot_file"` | BootFile string `form:"boot_file"` | ||||
| Params string `form:"run_para_list"` | Params string `form:"run_para_list"` | ||||
| BranchName string `form:"branch_name"` | BranchName string `form:"branch_name"` | ||||
| DatasetName string `form:"dataset_name"` | |||||
| } | } | ||||
| type CommitImageCloudBrainForm struct { | type CommitImageCloudBrainForm struct { | ||||
| @@ -70,6 +71,7 @@ type CreateCloudBrainInferencForm struct { | |||||
| ModelVersion string `form:"model_version" binding:"Required"` | ModelVersion string `form:"model_version" binding:"Required"` | ||||
| CkptName string `form:"ckpt_name" binding:"Required"` | CkptName string `form:"ckpt_name" binding:"Required"` | ||||
| LabelName string `form:"label_names" 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 { | func (f *CreateCloudBrainForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
| @@ -19,6 +19,7 @@ type CreateGrampusTrainJobForm struct { | |||||
| EngineName string `form:"engine_name" binding:"Required"` | EngineName string `form:"engine_name" binding:"Required"` | ||||
| WorkServerNumber int `form:"work_server_number" binding:"Required"` | WorkServerNumber int `form:"work_server_number" binding:"Required"` | ||||
| Image string `form:"image"` | Image string `form:"image"` | ||||
| DatasetName string `form:"dataset_name"` | |||||
| } | } | ||||
| func (f *CreateGrampusTrainJobForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *CreateGrampusTrainJobForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
| @@ -19,6 +19,7 @@ const ( | |||||
| ACCESS_TOKEN_PATH = "/cgi-bin/token" | ACCESS_TOKEN_PATH = "/cgi-bin/token" | ||||
| QR_CODE_PATH = "/cgi-bin/qrcode/create" | QR_CODE_PATH = "/cgi-bin/qrcode/create" | ||||
| GET_MATERIAL_PATH = "/cgi-bin/material/batchget_material" | GET_MATERIAL_PATH = "/cgi-bin/material/batchget_material" | ||||
| SEND_TEMPLATE_PATH = "/cgi-bin/message/template/send" | |||||
| ACTION_QR_STR_SCENE = "QR_STR_SCENE" | ACTION_QR_STR_SCENE = "QR_STR_SCENE" | ||||
| ERR_CODE_ACCESSTOKEN_EXPIRE = 42001 | ERR_CODE_ACCESSTOKEN_EXPIRE = 42001 | ||||
| @@ -41,12 +42,33 @@ type QRCodeRequest struct { | |||||
| Action_info ActionInfo `json:"action_info"` | Action_info ActionInfo `json:"action_info"` | ||||
| Expire_seconds int `json:"expire_seconds"` | Expire_seconds int `json:"expire_seconds"` | ||||
| } | } | ||||
| type MaterialRequest struct { | type MaterialRequest struct { | ||||
| Type string `json:"type"` | Type string `json:"type"` | ||||
| Offset int `json:"offset"` | Offset int `json:"offset"` | ||||
| Count int `json:"count"` | 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 { | type ActionInfo struct { | ||||
| Scene Scene `json:"scene"` | Scene Scene `json:"scene"` | ||||
| } | } | ||||
| @@ -161,3 +183,27 @@ func getErrorCodeFromResponse(r *resty.Response) int { | |||||
| c, _ := strconv.Atoi(fmt.Sprint(code)) | c, _ := strconv.Atoi(fmt.Sprint(code)) | ||||
| return c | 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 | |||||
| } | |||||
| @@ -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 "" | |||||
| } | |||||
| @@ -326,7 +326,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||||
| ReadOnly: true, | ReadOnly: true, | ||||
| }, | }, | ||||
| }) | }) | ||||
| } else { | |||||
| } else if len(req.DatasetInfos) > 1 { | |||||
| for _, dataset := range req.DatasetInfos { | for _, dataset := range req.DatasetInfos { | ||||
| volumes = append(volumes, models.Volume{ | volumes = append(volumes, models.Volume{ | ||||
| HostPath: models.StHostPath{ | 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"]) | log.Error("no such resourceSpecId(%d)", task.ResourceSpecId, ctx.Data["MsgID"]) | ||||
| return errors.New("no such resourceSpec") | 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{ | 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{ | volumes = append(volumes, models.Volume{ | ||||
| HostPath: models.StHostPath{ | HostPath: models.StHostPath{ | ||||
| Path: dataset.DataLocalPath, | |||||
| MountPath: DataSetMountPath + "/" + dataset.Name, | |||||
| Path: datasetInfos[task.Uuid].DataLocalPath, | |||||
| MountPath: DataSetMountPath, | |||||
| ReadOnly: true, | 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, | GPUNumber: resourceSpec.GpuNum, | ||||
| MemoryMB: resourceSpec.MemMiB, | MemoryMB: resourceSpec.MemMiB, | ||||
| ShmMB: resourceSpec.ShareMemMiB, | ShmMB: resourceSpec.ShareMemMiB, | ||||
| Command: GetCloudbrainDebugCommand(),//Command, | |||||
| Command: GetCloudbrainDebugCommand(), //Command, | |||||
| NeedIBDevice: false, | NeedIBDevice: false, | ||||
| IsMainRole: false, | IsMainRole: false, | ||||
| UseNNI: false, | UseNNI: false, | ||||
| @@ -6,7 +6,6 @@ | |||||
| package context | package context | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/routers/notice" | |||||
| "html" | "html" | ||||
| "html/template" | "html/template" | ||||
| "io" | "io" | ||||
| @@ -16,6 +15,8 @@ import ( | |||||
| "strings" | "strings" | ||||
| "time" | "time" | ||||
| "code.gitea.io/gitea/routers/notice" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/auth" | "code.gitea.io/gitea/modules/auth" | ||||
| "code.gitea.io/gitea/modules/base" | "code.gitea.io/gitea/modules/base" | ||||
| @@ -62,7 +62,7 @@ func GetUserKPIStats(repoPath string, startTime time.Time, endTime time.Time) (m | |||||
| after := startTime.Format(time.RFC3339) | after := startTime.Format(time.RFC3339) | ||||
| until := endTime.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) | stdout, err := NewCommand(args...).RunInDirBytes(repoPath) | ||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| @@ -56,4 +56,6 @@ type Notifier interface { | |||||
| NotifySyncDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) | NotifySyncDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) | ||||
| NotifyOtherTask(doer *models.User, repo *models.Repository, id string, name string, optype models.ActionType) | NotifyOtherTask(doer *models.User, repo *models.Repository, id string, name string, optype models.ActionType) | ||||
| NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus string) | |||||
| } | } | ||||
| @@ -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) NotifyOtherTask(doer *models.User, repo *models.Repository, id string, name string, optype models.ActionType) { | ||||
| } | } | ||||
| func (*NullNotifier) NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus string) { | |||||
| } | |||||
| @@ -12,6 +12,7 @@ import ( | |||||
| "code.gitea.io/gitea/modules/notification/mail" | "code.gitea.io/gitea/modules/notification/mail" | ||||
| "code.gitea.io/gitea/modules/notification/ui" | "code.gitea.io/gitea/modules/notification/ui" | ||||
| "code.gitea.io/gitea/modules/notification/webhook" | "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/repository" | ||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| ) | ) | ||||
| @@ -35,6 +36,7 @@ func NewContext() { | |||||
| RegisterNotifier(indexer.NewNotifier()) | RegisterNotifier(indexer.NewNotifier()) | ||||
| RegisterNotifier(webhook.NewNotifier()) | RegisterNotifier(webhook.NewNotifier()) | ||||
| RegisterNotifier(action.NewNotifier()) | RegisterNotifier(action.NewNotifier()) | ||||
| RegisterNotifier(wechatNotifier.NewNotifier()) | |||||
| } | } | ||||
| // NotifyUploadAttachment notifies attachment upload message to notifiers | // 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) | notifier.NotifySyncDeleteRef(pusher, repo, refType, refFullName) | ||||
| } | } | ||||
| } | } | ||||
| // NotifyChangeCloudbrainStatus | |||||
| func NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus string) { | |||||
| for _, notifier := range notifiers { | |||||
| notifier.NotifyChangeCloudbrainStatus(cloudbrain, oldStatus) | |||||
| } | |||||
| } | |||||
| @@ -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 | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -583,6 +583,10 @@ var ( | |||||
| TreePathOfAutoMsgReply string | TreePathOfAutoMsgReply string | ||||
| TreePathOfSubscribe string | TreePathOfSubscribe string | ||||
| //wechat template msg config | |||||
| CloudbrainStartedTemplateId string | |||||
| CloudbrainStartedNotifyList []string | |||||
| //nginx proxy | //nginx proxy | ||||
| PROXYURL string | PROXYURL string | ||||
| RadarMap = struct { | RadarMap = struct { | ||||
| @@ -1434,7 +1438,7 @@ func NewContext() { | |||||
| WechatApiHost = sec.Key("HOST").MustString("https://api.weixin.qq.com") | WechatApiHost = sec.Key("HOST").MustString("https://api.weixin.qq.com") | ||||
| WechatApiTimeoutSeconds = sec.Key("TIMEOUT_SECONDS").MustInt(3) | WechatApiTimeoutSeconds = sec.Key("TIMEOUT_SECONDS").MustInt(3) | ||||
| WechatAppId = sec.Key("APP_ID").MustString("wxba77b915a305a57d") | 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) | WechatQRCodeExpireSeconds = sec.Key("QR_CODE_EXPIRE_SECONDS").MustInt(120) | ||||
| WechatAuthSwitch = sec.Key("AUTH_SWITCH").MustBool(true) | WechatAuthSwitch = sec.Key("AUTH_SWITCH").MustBool(true) | ||||
| UserNameOfWechatReply = sec.Key("AUTO_REPLY_USER_NAME").MustString("OpenIOSSG") | UserNameOfWechatReply = sec.Key("AUTO_REPLY_USER_NAME").MustString("OpenIOSSG") | ||||
| @@ -1442,6 +1446,8 @@ func NewContext() { | |||||
| RefNameOfWechatReply = sec.Key("AUTO_REPLY_REF_NAME").MustString("master") | RefNameOfWechatReply = sec.Key("AUTO_REPLY_REF_NAME").MustString("master") | ||||
| TreePathOfAutoMsgReply = sec.Key("AUTO_REPLY_TREE_PATH").MustString("wechat/auto_reply.json") | TreePathOfAutoMsgReply = sec.Key("AUTO_REPLY_TREE_PATH").MustString("wechat/auto_reply.json") | ||||
| TreePathOfSubscribe = sec.Key("SUBSCRIBE_TREE_PATH").MustString("wechat/subscribe_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() | SetRadarMapConfig() | ||||
| @@ -1007,7 +1007,7 @@ cloudbrain.time.starttime=Start run time | |||||
| cloudbrain.time.endtime=End run time | cloudbrain.time.endtime=End run time | ||||
| cloudbrain.datasetdownload=Dataset download url | cloudbrain.datasetdownload=Dataset download url | ||||
| model_manager = Model | 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. | model_rename=Duplicate model name, please modify model name. | ||||
| date=Date | date=Date | ||||
| @@ -1098,6 +1098,9 @@ modelarts.createtime=CreateTime | |||||
| modelarts.version_nums = Version Nums | modelarts.version_nums = Version Nums | ||||
| modelarts.version = Version | modelarts.version = Version | ||||
| modelarts.computing_resources=compute Resources | modelarts.computing_resources=compute Resources | ||||
| modelarts.ai_center=Ai Center | |||||
| modelarts.card_type=Card Type | |||||
| modelarts.cluster=Cluster | |||||
| modelarts.notebook=Debug Task | modelarts.notebook=Debug Task | ||||
| modelarts.train_job=Train Task | modelarts.train_job=Train Task | ||||
| modelarts.train_job.new_debug= New Debug 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_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.create_error2=Only one running model transformation task can be created. | ||||
| modelconvert.manage.model_not_exist=The model does not exist. | 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.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。 | 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。 | ||||
| @@ -1006,7 +1006,7 @@ datasets.desc=数据集功能 | |||||
| cloudbrain_helper=使用GPU/NPU资源,开启Notebook、模型训练任务等 | cloudbrain_helper=使用GPU/NPU资源,开启Notebook、模型训练任务等 | ||||
| model_manager = 模型 | model_manager = 模型 | ||||
| model_noright=无权限操作 | |||||
| model_noright=您没有操作权限。 | |||||
| model_rename=模型名称重复,请修改模型名称 | model_rename=模型名称重复,请修改模型名称 | ||||
| @@ -1108,6 +1108,9 @@ modelarts.deletetime=删除时间 | |||||
| modelarts.version_nums=版本数 | modelarts.version_nums=版本数 | ||||
| modelarts.version=版本 | modelarts.version=版本 | ||||
| modelarts.computing_resources=计算资源 | modelarts.computing_resources=计算资源 | ||||
| modelarts.ai_center=智算中心 | |||||
| modelarts.card_type=卡类型 | |||||
| modelarts.cluster=集群 | |||||
| modelarts.notebook=调试任务 | modelarts.notebook=调试任务 | ||||
| modelarts.train_job=训练任务 | modelarts.train_job=训练任务 | ||||
| modelarts.train_job.new_debug=新建调试任务 | modelarts.train_job.new_debug=新建调试任务 | ||||
| @@ -1237,7 +1240,7 @@ model.manage.create_new_convert_task=创建模型转换任务 | |||||
| modelconvert.manage.create_error1=相同的名称模型转换任务已经存在。 | modelconvert.manage.create_error1=相同的名称模型转换任务已经存在。 | ||||
| modelconvert.manage.create_error2=只能创建一个正在运行的模型转换任务。 | modelconvert.manage.create_error2=只能创建一个正在运行的模型转换任务。 | ||||
| modelconvert.manage.model_not_exist=选择的模型不存在。 | modelconvert.manage.model_not_exist=选择的模型不存在。 | ||||
| modelconvert.manage.no_operate_right=无操作权限。 | |||||
| modelconvert.manage.no_operate_right=您没有操作权限。 | |||||
| grampus.train_job.ai_center=智算中心 | grampus.train_job.ai_center=智算中心 | ||||
| grampus.dataset_path_rule = 训练脚本存储在/cache/code中,数据集存储在/cache/dataset中,训练输出请存储在/cache/output中以供后续下载。 | grampus.dataset_path_rule = 训练脚本存储在/cache/code中,数据集存储在/cache/dataset中,训练输出请存储在/cache/output中以供后续下载。 | ||||
| @@ -3119,6 +3122,8 @@ select_dataset = 选择数据集 | |||||
| specification = 规格 | specification = 规格 | ||||
| select_specification = 选择资源规格 | select_specification = 选择资源规格 | ||||
| description = 描述 | description = 描述 | ||||
| card_duration = 运行卡时 | |||||
| card_type = 卡类型 | |||||
| wrong_specification=您目前不能使用这个资源规格,请选择其他资源规格。 | wrong_specification=您目前不能使用这个资源规格,请选择其他资源规格。 | ||||
| job_name_rule = 请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。 | job_name_rule = 请输入字母、数字、_和-,最长64个字符,且不能以中划线(-)结尾。 | ||||
| @@ -1,6 +1,7 @@ | |||||
| .nb-notebook { | .nb-notebook { | ||||
| line-height: 1.5; | line-height: 1.5; | ||||
| margin-left: 7em; | |||||
| margin-left: 6em; | |||||
| } | } | ||||
| .nb-stdout, .nb-stderr { | .nb-stdout, .nb-stderr { | ||||
| @@ -15,6 +16,7 @@ | |||||
| .nb-cell + .nb-cell { | .nb-cell + .nb-cell { | ||||
| margin-top: 0.5em; | margin-top: 0.5em; | ||||
| max-width: 100%; | |||||
| } | } | ||||
| .nb-output table { | .nb-output table { | ||||
| @@ -40,6 +42,11 @@ | |||||
| padding-left: 1em; | padding-left: 1em; | ||||
| } | } | ||||
| .nb-notebook img { | |||||
| max-width: 80%; | |||||
| padding: 3px; | |||||
| } | |||||
| .nb-cell { | .nb-cell { | ||||
| position: relative; | position: relative; | ||||
| } | } | ||||
| @@ -60,7 +67,8 @@ | |||||
| } | } | ||||
| .nb-output img { | .nb-output img { | ||||
| max-width: 100%; | |||||
| max-width: 80%; | |||||
| padding: 3px; | |||||
| } | } | ||||
| .nb-output:before, .nb-input:before { | .nb-output:before, .nb-input:before { | ||||
| @@ -123,13 +123,13 @@ function loadimg(uuid,filename){ | |||||
| function loadimg(){ | function loadimg(){ | ||||
| var length = labeltastresult[fileindex].pic_image_field.length; | 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"; | canvas.style.display="none"; | ||||
| @@ -138,11 +138,11 @@ function loadimg(){ | |||||
| $('#textcontent').height(canvas.height-40) | $('#textcontent').height(canvas.height-40) | ||||
| $("#textcontent").text(textContent); | $("#textcontent").text(textContent); | ||||
| }else{ | }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"; | canvas.style.display="block"; | ||||
| document.getElementById("textcontent").style.display="none"; | document.getElementById("textcontent").style.display="none"; | ||||
| img.src = ip + "/getgiteaimage?uuid=" + dataset_id + "&filename=" + labeltastresult[fileindex].pic_image_field; | img.src = ip + "/getgiteaimage?uuid=" + dataset_id + "&filename=" + labeltastresult[fileindex].pic_image_field; | ||||
| @@ -10,6 +10,7 @@ import ( | |||||
| "github.com/360EntSecGroup-Skylar/excelize/v2" | "github.com/360EntSecGroup-Skylar/excelize/v2" | ||||
| "code.gitea.io/gitea/modules/modelarts" | "code.gitea.io/gitea/modules/modelarts" | ||||
| "code.gitea.io/gitea/routers/repo" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/base" | "code.gitea.io/gitea/modules/base" | ||||
| @@ -89,6 +90,10 @@ func CloudBrains(ctx *context.Context) { | |||||
| ciTasks[i].CanDebug = true | ciTasks[i].CanDebug = true | ||||
| ciTasks[i].CanDel = true | ciTasks[i].CanDel = true | ||||
| ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource | 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)) | 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 { | 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 { | func getRepoPathName(rs *models.CloudbrainInfo) string { | ||||
| if rs.Repo != nil { | if rs.Repo != nil { | ||||
| return rs.Repo.OwnerName + "/" + rs.Repo.Alias | 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 { | 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")} | |||||
| } | } | ||||
| @@ -571,6 +571,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Get("/query_user_yesterday", operationReq, repo_ext.QueryUserStaticYesterday) | m.Get("/query_user_yesterday", operationReq, repo_ext.QueryUserStaticYesterday) | ||||
| m.Get("/query_user_all", operationReq, repo_ext.QueryUserStaticAll) | m.Get("/query_user_all", operationReq, repo_ext.QueryUserStaticAll) | ||||
| m.Get("/query_user_activity", operationReq, repo_ext.QueryUserActivity) | m.Get("/query_user_activity", operationReq, repo_ext.QueryUserActivity) | ||||
| m.Get("/query_user_login", operationReq, repo_ext.QueryUserLoginInfo) | |||||
| //cloudbrain board | //cloudbrain board | ||||
| m.Group("/cloudbrainboard", func() { | m.Group("/cloudbrainboard", func() { | ||||
| m.Get("/downloadAll", repo.DownloadCloudBrainBoard) | m.Get("/downloadAll", repo.DownloadCloudBrainBoard) | ||||
| @@ -6,6 +6,7 @@ | |||||
| package repo | package repo | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/modules/notification" | |||||
| "encoding/json" | "encoding/json" | ||||
| "net/http" | "net/http" | ||||
| "sort" | "sort" | ||||
| @@ -74,7 +75,7 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||||
| log.Error("ConvertToJobResultPayload failed:", err) | log.Error("ConvertToJobResultPayload failed:", err) | ||||
| return | return | ||||
| } | } | ||||
| oldStatus := job.Status | |||||
| job.Status = result.JobStatus.State | job.Status = result.JobStatus.State | ||||
| taskRoles := result.TaskRoles | taskRoles := result.TaskRoles | ||||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | 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) { | if result.JobStatus.State != string(models.JobWaiting) { | ||||
| models.ParseAndSetDurationFromCloudBrainOne(result, job) | models.ParseAndSetDurationFromCloudBrainOne(result, job) | ||||
| if oldStatus != job.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(job, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(job) | err = models.UpdateJob(job) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob failed:", err) | log.Error("UpdateJob failed:", err) | ||||
| @@ -99,6 +103,7 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||||
| "SubState": result.JobStatus.SubState, | "SubState": result.JobStatus.SubState, | ||||
| "CreatedTime": time.Unix(result.JobStatus.CreatedTime/1000, 0).Format("2006-01-02 15:04:05"), | "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"), | "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) | log.Error("ConvertToJobResultPayload failed:", err) | ||||
| return | return | ||||
| } | } | ||||
| oldStatus := job.Status | |||||
| job.Status = result.JobStatus.State | job.Status = result.JobStatus.State | ||||
| if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { | if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { | ||||
| taskRoles := result.TaskRoles | taskRoles := result.TaskRoles | ||||
| @@ -136,6 +141,9 @@ func GetCloudBrainInferenceJob(ctx *context.APIContext) { | |||||
| if result.JobStatus.State != string(models.JobWaiting) { | if result.JobStatus.State != string(models.JobWaiting) { | ||||
| models.ParseAndSetDurationFromCloudBrainOne(result, job) | models.ParseAndSetDurationFromCloudBrainOne(result, job) | ||||
| if oldStatus != job.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(job, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(job) | err = models.UpdateJob(job) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob failed:", err) | log.Error("UpdateJob failed:", err) | ||||
| @@ -10,6 +10,7 @@ import ( | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/routers/repo" | |||||
| "github.com/360EntSecGroup-Skylar/excelize/v2" | "github.com/360EntSecGroup-Skylar/excelize/v2" | ||||
| ) | ) | ||||
| @@ -735,6 +736,7 @@ func GetCloudbrainsDetailData(ctx *context.Context) { | |||||
| var taskDetail models.TaskDetail | var taskDetail models.TaskDetail | ||||
| taskDetail.ID = ciTasks[i].Cloudbrain.ID | taskDetail.ID = ciTasks[i].Cloudbrain.ID | ||||
| taskDetail.JobID = ciTasks[i].Cloudbrain.JobID | |||||
| taskDetail.JobName = ciTasks[i].JobName | taskDetail.JobName = ciTasks[i].JobName | ||||
| taskDetail.DisplayJobName = ciTasks[i].DisplayJobName | taskDetail.DisplayJobName = ciTasks[i].DisplayJobName | ||||
| taskDetail.Status = ciTasks[i].Status | 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.RepoName = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Name | ||||
| taskDetail.RepoAlias = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Alias | 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 { | if ciTasks[i].Cloudbrain.DeletedAt != nilTime { | ||||
| taskDetail.IsDelete = true | 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) { | func GetCloudbrainsCreateHoursData(ctx *context.Context) { | ||||
| recordCloudbrain, err := models.GetRecordBeginTime() | recordCloudbrain, err := models.GetRecordBeginTime() | ||||
| if err != nil { | 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"), | 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"), | "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 { | 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, | 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 { | 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 { | func getCloudbrainType(rs *models.CloudbrainInfo, ctx *context.Context) string { | ||||
| if rs.Cloudbrain.Type == models.TypeCloudBrainOne { | if rs.Cloudbrain.Type == models.TypeCloudBrainOne { | ||||
| return ctx.Tr("repo.cloudbrain1") | return ctx.Tr("repo.cloudbrain1") | ||||
| @@ -1309,6 +1280,14 @@ func getCloudbrainType(rs *models.CloudbrainInfo, ctx *context.Context) string { | |||||
| return ctx.Tr("repo.cloudbrain_untype") | 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 { | func getBrainDeleteTime(rs *models.CloudbrainInfo) string { | ||||
| nilTime := time.Time{} | nilTime := time.Time{} | ||||
| @@ -6,6 +6,7 @@ | |||||
| package repo | package repo | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/modules/notification" | |||||
| "encoding/json" | "encoding/json" | ||||
| "net/http" | "net/http" | ||||
| "path" | "path" | ||||
| @@ -42,8 +43,11 @@ func GetModelArtsNotebook(ctx *context.APIContext) { | |||||
| ctx.NotFound(err) | ctx.NotFound(err) | ||||
| return | return | ||||
| } | } | ||||
| oldStatus := job.Status | |||||
| job.Status = result.Status | job.Status = result.Status | ||||
| if oldStatus != result.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(job, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(job) | err = models.UpdateJob(job) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob failed:", err) | log.Error("UpdateJob failed:", err) | ||||
| @@ -75,21 +79,26 @@ func GetModelArtsNotebook2(ctx *context.APIContext) { | |||||
| if job.StartTime == 0 && result.Lease.UpdateTime > 0 { | if job.StartTime == 0 && result.Lease.UpdateTime > 0 { | ||||
| job.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000) | job.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000) | ||||
| } | } | ||||
| oldStatus := job.Status | |||||
| job.Status = result.Status | job.Status = result.Status | ||||
| if job.EndTime == 0 && models.IsModelArtsDebugJobTerminal(job.Status) { | if job.EndTime == 0 && models.IsModelArtsDebugJobTerminal(job.Status) { | ||||
| job.EndTime = timeutil.TimeStampNow() | job.EndTime = timeutil.TimeStampNow() | ||||
| } | } | ||||
| job.CorrectCreateUnix() | job.CorrectCreateUnix() | ||||
| job.ComputeAndSetDuration() | job.ComputeAndSetDuration() | ||||
| if oldStatus != result.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(job, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(job) | err = models.UpdateJob(job) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob failed:", err) | log.Error("UpdateJob failed:", err) | ||||
| } | } | ||||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | 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) | ctx.NotFound(err) | ||||
| return | return | ||||
| } | } | ||||
| oldStatus := job.Status | |||||
| job.Status = modelarts.TransTrainJobStatus(result.IntStatus) | job.Status = modelarts.TransTrainJobStatus(result.IntStatus) | ||||
| job.Duration = result.Duration | job.Duration = result.Duration | ||||
| job.TrainJobDuration = result.TrainJobDuration | job.TrainJobDuration = result.TrainJobDuration | ||||
| if oldStatus != job.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(job, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(job) | err = models.UpdateJob(job) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob failed:", err) | log.Error("UpdateJob failed:", err) | ||||
| @@ -155,7 +167,7 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) { | |||||
| log.Error("ConvertToJobResultPayload failed:", err) | log.Error("ConvertToJobResultPayload failed:", err) | ||||
| return | return | ||||
| } | } | ||||
| oldStatus := job.Status | |||||
| job.Status = result.JobStatus.State | job.Status = result.JobStatus.State | ||||
| if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { | if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { | ||||
| taskRoles := result.TaskRoles | taskRoles := result.TaskRoles | ||||
| @@ -168,6 +180,9 @@ func GetModelArtsTrainJobVersion(ctx *context.APIContext) { | |||||
| if result.JobStatus.State != string(models.JobWaiting) { | if result.JobStatus.State != string(models.JobWaiting) { | ||||
| models.ParseAndSetDurationFromCloudBrainOne(result, job) | models.ParseAndSetDurationFromCloudBrainOne(result, job) | ||||
| if oldStatus != job.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(job, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(job) | err = models.UpdateJob(job) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob failed:", err) | log.Error("UpdateJob failed:", err) | ||||
| @@ -152,6 +152,10 @@ func saveModelByParameters(jobId string, versionName string, name string, versio | |||||
| } | } | ||||
| func SaveNewNameModel(ctx *context.Context) { | func SaveNewNameModel(ctx *context.Context) { | ||||
| if !ctx.Repo.CanWrite(models.UnitTypeModelManage) { | |||||
| ctx.Error(403, ctx.Tr("repo.model_noright")) | |||||
| return | |||||
| } | |||||
| name := ctx.Query("Name") | name := ctx.Query("Name") | ||||
| if name == "" { | if name == "" { | ||||
| ctx.Error(500, fmt.Sprintf("name or version is null.")) | ctx.Error(500, fmt.Sprintf("name or version is null.")) | ||||
| @@ -169,6 +173,10 @@ func SaveNewNameModel(ctx *context.Context) { | |||||
| } | } | ||||
| func SaveModel(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.") | log.Info("save model start.") | ||||
| JobId := ctx.Query("JobId") | JobId := ctx.Query("JobId") | ||||
| VersionName := ctx.Query("VersionName") | VersionName := ctx.Query("VersionName") | ||||
| @@ -177,16 +185,8 @@ func SaveModel(ctx *context.Context) { | |||||
| label := ctx.Query("Label") | label := ctx.Query("Label") | ||||
| description := ctx.Query("Description") | description := ctx.Query("Description") | ||||
| engine := ctx.QueryInt("Engine") | engine := ctx.QueryInt("Engine") | ||||
| trainTaskCreate := ctx.QueryBool("trainTaskCreate") | |||||
| modelSelectedFile := ctx.Query("modelSelectedFile") | modelSelectedFile := ctx.Query("modelSelectedFile") | ||||
| log.Info("engine=" + fmt.Sprint(engine) + " modelSelectedFile=" + 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 == "" { | if JobId == "" || VersionName == "" { | ||||
| ctx.Error(500, fmt.Sprintf("JobId or VersionName is null.")) | ctx.Error(500, fmt.Sprintf("JobId or VersionName is null.")) | ||||
| @@ -15,6 +15,8 @@ import ( | |||||
| "time" | "time" | ||||
| "unicode/utf8" | "unicode/utf8" | ||||
| "code.gitea.io/gitea/modules/notification" | |||||
| "code.gitea.io/gitea/modules/grampus" | "code.gitea.io/gitea/modules/grampus" | ||||
| "code.gitea.io/gitea/modules/timeutil" | "code.gitea.io/gitea/modules/timeutil" | ||||
| @@ -222,6 +224,7 @@ func CloudBrainNew(ctx *context.Context) { | |||||
| ctx.ServerError("get new cloudbrain info failed", err) | ctx.ServerError("get new cloudbrain info failed", err) | ||||
| return | return | ||||
| } | } | ||||
| ctx.Data["PageIsGPUDebug"] = true | |||||
| ctx.HTML(200, tplCloudBrainNew) | ctx.HTML(200, tplCloudBrainNew) | ||||
| } | } | ||||
| @@ -287,13 +290,17 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
| return | 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() | command := cloudbrain.GetCloudbrainDebugCommand() | ||||
| @@ -302,6 +309,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
| commandTrain, err := getTrainJobCommand(form) | commandTrain, err := getTrainJobCommand(form) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("getTrainJobCommand failed: %v", err) | log.Error("getTrainJobCommand failed: %v", err) | ||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr(err.Error(), tpl, &form) | ctx.RenderWithErr(err.Error(), tpl, &form) | ||||
| return | return | ||||
| } | } | ||||
| @@ -370,7 +378,6 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
| } | } | ||||
| } | } | ||||
| func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBrainInferencForm) { | func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBrainInferencForm) { | ||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| displayJobName := form.DisplayJobName | displayJobName := form.DisplayJobName | ||||
| @@ -391,6 +398,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra | |||||
| command, err := getInferenceJobCommand(form) | command, err := getInferenceJobCommand(form) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("getTrainJobCommand failed: %v", err) | log.Error("getTrainJobCommand failed: %v", err) | ||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr(err.Error(), tpl, &form) | ctx.RenderWithErr(err.Error(), tpl, &form) | ||||
| return | return | ||||
| } | } | ||||
| @@ -413,6 +421,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra | |||||
| } | } | ||||
| if !jobNamePattern.MatchString(displayJobName) { | if !jobNamePattern.MatchString(displayJobName) { | ||||
| cloudBrainNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tpl, &form) | ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tpl, &form) | ||||
| return | return | ||||
| } | } | ||||
| @@ -491,6 +500,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/inference-job") | 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) { | func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.JobType) { | ||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| debugListType := ctx.Query("debugListType") | debugListType := ctx.Query("debugListType") | ||||
| cloudbrain.InitSpecialPool() | |||||
| var task *models.Cloudbrain | var task *models.Cloudbrain | ||||
| var err error | var err error | ||||
| @@ -644,22 +655,22 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||||
| if err != nil { | if err != nil { | ||||
| log.Info("error:" + err.Error()) | log.Info("error:" + err.Error()) | ||||
| ctx.Data["error"] = err.Error() | |||||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||||
| return | return | ||||
| } | } | ||||
| result, err := cloudbrain.GetJob(task.JobID) | result, err := cloudbrain.GetJob(task.JobID) | ||||
| if err != nil { | if err != nil { | ||||
| log.Info("error:" + err.Error()) | log.Info("error:" + err.Error()) | ||||
| ctx.Data["error"] = err.Error() | |||||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||||
| return | return | ||||
| } | } | ||||
| hasSpec := false | |||||
| if task.JobType == string(models.JobTypeTrain) { | if task.JobType == string(models.JobTypeTrain) { | ||||
| if cloudbrain.TrainResourceSpecs == nil { | if cloudbrain.TrainResourceSpecs == nil { | ||||
| json.Unmarshal([]byte(setting.TrainResourceSpecs), &cloudbrain.TrainResourceSpecs) | json.Unmarshal([]byte(setting.TrainResourceSpecs), &cloudbrain.TrainResourceSpecs) | ||||
| } | } | ||||
| hasSpec := false | |||||
| for _, tmp := range cloudbrain.TrainResourceSpecs.ResourceSpec { | for _, tmp := range cloudbrain.TrainResourceSpecs.ResourceSpec { | ||||
| if tmp.Id == task.ResourceSpecId { | if tmp.Id == task.ResourceSpecId { | ||||
| hasSpec = true | hasSpec = true | ||||
| @@ -667,24 +678,7 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||||
| ctx.Data["CpuNum"] = tmp.CpuNum | ctx.Data["CpuNum"] = tmp.CpuNum | ||||
| ctx.Data["MemMiB"] = tmp.MemMiB | ctx.Data["MemMiB"] = tmp.MemMiB | ||||
| ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB | 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 { | for _, tmp := range cloudbrain.InferenceResourceSpecs.ResourceSpec { | ||||
| if tmp.Id == task.ResourceSpecId { | if tmp.Id == task.ResourceSpecId { | ||||
| hasSpec = true | |||||
| ctx.Data["GpuNum"] = tmp.GpuNum | ctx.Data["GpuNum"] = tmp.GpuNum | ||||
| ctx.Data["CpuNum"] = tmp.CpuNum | ctx.Data["CpuNum"] = tmp.CpuNum | ||||
| ctx.Data["MemMiB"] = tmp.MemMiB | ctx.Data["MemMiB"] = tmp.MemMiB | ||||
| ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB | ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB | ||||
| break | |||||
| } | } | ||||
| } | } | ||||
| } else { | } else { | ||||
| @@ -706,10 +702,32 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||||
| } | } | ||||
| for _, tmp := range cloudbrain.ResourceSpecs.ResourceSpec { | for _, tmp := range cloudbrain.ResourceSpecs.ResourceSpec { | ||||
| if tmp.Id == task.ResourceSpecId { | if tmp.Id == task.ResourceSpecId { | ||||
| hasSpec = true | |||||
| ctx.Data["GpuNum"] = tmp.GpuNum | ctx.Data["GpuNum"] = tmp.GpuNum | ||||
| ctx.Data["CpuNum"] = tmp.CpuNum | ctx.Data["CpuNum"] = tmp.CpuNum | ||||
| ctx.Data["MemMiB"] = tmp.MemMiB | ctx.Data["MemMiB"] = tmp.MemMiB | ||||
| ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB | 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 | 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) { | } else if task.JobType == string(models.JobTypeInference) { | ||||
| if inferenceGpuInfos == nil { | 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 | taskRoles := jobRes.TaskRoles | ||||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | ||||
| ctx.Data["taskRes"] = taskRes | ctx.Data["taskRes"] = taskRes | ||||
| ctx.Data["ExitDiagnostics"] = taskRes.TaskStatuses[0].ExitDiagnostics | ctx.Data["ExitDiagnostics"] = taskRes.TaskStatuses[0].ExitDiagnostics | ||||
| oldStatus := task.Status | |||||
| task.Status = taskRes.TaskStatuses[0].State | task.Status = taskRes.TaskStatuses[0].State | ||||
| task.ContainerID = taskRes.TaskStatuses[0].ContainerID | task.ContainerID = taskRes.TaskStatuses[0].ContainerID | ||||
| task.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | task.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | ||||
| models.ParseAndSetDurationFromCloudBrainOne(jobRes, task) | models.ParseAndSetDurationFromCloudBrainOne(jobRes, task) | ||||
| if task.DeletedAt.IsZero() { //normal record | if task.DeletedAt.IsZero() { //normal record | ||||
| if oldStatus != task.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(task, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Data["error"] = err.Error() | ctx.Data["error"] = err.Error() | ||||
| @@ -892,6 +916,20 @@ func CloudBrainCommitImageShow(ctx *context.Context) { | |||||
| ctx.HTML(200, tplCloudBrainImageSubmit) | 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) { | func CloudBrainImageEdit(ctx *context.Context) { | ||||
| ctx.Data["PageIsImageEdit"] = true | ctx.Data["PageIsImageEdit"] = true | ||||
| ctx.Data["PageFrom"] = ctx.Params(":from") | ctx.Data["PageFrom"] = ctx.Params(":from") | ||||
| @@ -1116,12 +1154,15 @@ func CloudBrainStop(ctx *context.Context) { | |||||
| errorMsg = "cloudbrain.Stopped_failed" | errorMsg = "cloudbrain.Stopped_failed" | ||||
| break | break | ||||
| } | } | ||||
| oldStatus := task.Status | |||||
| task.Status = string(models.JobStopped) | task.Status = string(models.JobStopped) | ||||
| if task.EndTime == 0 { | if task.EndTime == 0 { | ||||
| task.EndTime = timeutil.TimeStampNow() | task.EndTime = timeutil.TimeStampNow() | ||||
| } | } | ||||
| task.ComputeAndSetDuration() | task.ComputeAndSetDuration() | ||||
| if oldStatus != task.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(task, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"]) | 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 { | if err != nil { | ||||
| log.Warn("Failed to stop cloudBrain job:"+taskInfo.JobID, err) | log.Warn("Failed to stop cloudBrain job:"+taskInfo.JobID, err) | ||||
| } else { | } else { | ||||
| oldStatus := taskInfo.Status | |||||
| taskInfo.Status = string(models.JobStopped) | taskInfo.Status = string(models.JobStopped) | ||||
| if taskInfo.EndTime == 0 { | if taskInfo.EndTime == 0 { | ||||
| taskInfo.EndTime = timeutil.TimeStampNow() | taskInfo.EndTime = timeutil.TimeStampNow() | ||||
| } | } | ||||
| taskInfo.ComputeAndSetDuration() | taskInfo.ComputeAndSetDuration() | ||||
| if oldStatus != taskInfo.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(taskInfo, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(taskInfo) | err = models.UpdateJob(taskInfo) | ||||
| if err != nil { | if err != nil { | ||||
| log.Warn("UpdateJob failed", err) | log.Warn("UpdateJob failed", err) | ||||
| @@ -1699,9 +1744,13 @@ func SyncCloudbrainStatus() { | |||||
| jobRes, _ := models.ConvertToJobResultPayload(result.Payload) | jobRes, _ := models.ConvertToJobResultPayload(result.Payload) | ||||
| taskRoles := jobRes.TaskRoles | taskRoles := jobRes.TaskRoles | ||||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | ||||
| oldStatus := task.Status | |||||
| task.Status = taskRes.TaskStatuses[0].State | task.Status = taskRes.TaskStatuses[0].State | ||||
| if task.Status != string(models.JobWaiting) { | if task.Status != string(models.JobWaiting) { | ||||
| models.ParseAndSetDurationFromCloudBrainOne(jobRes, task) | models.ParseAndSetDurationFromCloudBrainOne(jobRes, task) | ||||
| if oldStatus != task.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(task, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | ||||
| @@ -1728,6 +1777,9 @@ func SyncCloudbrainStatus() { | |||||
| task.EndTime = timeutil.TimeStampNow() | task.EndTime = timeutil.TimeStampNow() | ||||
| } | } | ||||
| task.ComputeAndSetDuration() | task.ComputeAndSetDuration() | ||||
| if oldStatus != task.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(task, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob(%s) failed:%v", task.DisplayJobName, err) | log.Error("UpdateJob(%s) failed:%v", task.DisplayJobName, err) | ||||
| @@ -1746,6 +1798,7 @@ func SyncCloudbrainStatus() { | |||||
| } | } | ||||
| if result != nil { | if result != nil { | ||||
| oldStatus := task.Status | |||||
| task.Status = result.Status | task.Status = result.Status | ||||
| if task.StartTime == 0 && result.Lease.UpdateTime > 0 { | if task.StartTime == 0 && result.Lease.UpdateTime > 0 { | ||||
| task.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000) | task.StartTime = timeutil.TimeStamp(result.Lease.UpdateTime / 1000) | ||||
| @@ -1755,6 +1808,9 @@ func SyncCloudbrainStatus() { | |||||
| } | } | ||||
| task.CorrectCreateUnix() | task.CorrectCreateUnix() | ||||
| task.ComputeAndSetDuration() | task.ComputeAndSetDuration() | ||||
| if oldStatus != task.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(task, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | ||||
| @@ -1769,6 +1825,7 @@ func SyncCloudbrainStatus() { | |||||
| } | } | ||||
| if result != nil { | if result != nil { | ||||
| oldStatus := task.Status | |||||
| task.Status = modelarts.TransTrainJobStatus(result.IntStatus) | task.Status = modelarts.TransTrainJobStatus(result.IntStatus) | ||||
| task.Duration = result.Duration / 1000 | task.Duration = result.Duration / 1000 | ||||
| task.TrainJobDuration = result.TrainJobDuration | task.TrainJobDuration = result.TrainJobDuration | ||||
| @@ -1781,6 +1838,9 @@ func SyncCloudbrainStatus() { | |||||
| task.EndTime = task.StartTime.Add(task.Duration) | task.EndTime = task.StartTime.Add(task.Duration) | ||||
| } | } | ||||
| task.CorrectCreateUnix() | task.CorrectCreateUnix() | ||||
| if oldStatus != task.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(task, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | 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 { | 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] | 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.Status = grampus.TransTrainJobStatus(result.JobInfo.Status) | ||||
| task.Duration = result.JobInfo.RunSec | task.Duration = result.JobInfo.RunSec | ||||
| task.TrainJobDuration = models.ConvertDurationToStr(task.Duration) | task.TrainJobDuration = models.ConvertDurationToStr(task.Duration) | ||||
| @@ -1812,6 +1873,9 @@ func SyncCloudbrainStatus() { | |||||
| task.EndTime = task.StartTime.Add(task.Duration) | task.EndTime = task.StartTime.Add(task.Duration) | ||||
| } | } | ||||
| task.CorrectCreateUnix() | task.CorrectCreateUnix() | ||||
| if oldStatus != task.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(task, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | log.Error("UpdateJob(%s) failed:%v", task.JobName, err) | ||||
| @@ -2662,3 +2726,170 @@ func GetBenchmarkTypes(ctx *context.Context) *models.BenchmarkTypes { | |||||
| } | } | ||||
| return benchmarkTypesMap[lang] | 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 | |||||
| } | |||||
| @@ -1,15 +1,8 @@ | |||||
| package repo | package repo | ||||
| import ( | 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" | "encoding/json" | ||||
| "errors" | "errors" | ||||
| "github.com/unknwon/com" | |||||
| "io/ioutil" | "io/ioutil" | ||||
| "net/http" | "net/http" | ||||
| "os" | "os" | ||||
| @@ -18,6 +11,15 @@ import ( | |||||
| "strings" | "strings" | ||||
| "time" | "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/models" | ||||
| "code.gitea.io/gitea/modules/base" | "code.gitea.io/gitea/modules/base" | ||||
| "code.gitea.io/gitea/modules/cloudbrain" | "code.gitea.io/gitea/modules/cloudbrain" | ||||
| @@ -64,7 +66,7 @@ func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) err | |||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| t := time.Now() | 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 | ctx.Data["display_job_name"] = displayJobName | ||||
| //get valid images | //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?) | //todo: upload code (send to file_server todo this work?) | ||||
| if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.OutputPath); err != nil { | if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.OutputPath); err != nil { | ||||
| log.Error("Failed to obsMkdir_output: %s (%v)", repo.FullName(), err) | 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) | ctx.RenderWithErr("Failed to obsMkdir_output", tplGrampusTrainJobNPUNew, &form) | ||||
| return | return | ||||
| } | } | ||||
| @@ -550,12 +552,15 @@ func GrampusStopJob(ctx *context.Context) { | |||||
| errorMsg = res.ErrorMsg | errorMsg = res.ErrorMsg | ||||
| break | break | ||||
| } | } | ||||
| oldStatus := task.Status | |||||
| task.Status = string(models.GrampusStatusStopped) | task.Status = string(models.GrampusStatusStopped) | ||||
| if task.EndTime == 0 { | if task.EndTime == 0 { | ||||
| task.EndTime = timeutil.TimeStampNow() | task.EndTime = timeutil.TimeStampNow() | ||||
| } | } | ||||
| task.ComputeAndSetDuration() | task.ComputeAndSetDuration() | ||||
| if oldStatus != task.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(task, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"]) | 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")) | task, err := models.GetCloudbrainByJobIDWithDeleted(ctx.Params(":jobid")) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetCloudbrainByJobID failed:" + err.Error()) | log.Error("GetCloudbrainByJobID failed:" + err.Error()) | ||||
| ctx.ServerError("system error", err) | |||||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||||
| return | return | ||||
| } | } | ||||
| @@ -634,14 +639,15 @@ func GrampusTrainJobShow(ctx *context.Context) { | |||||
| result, err := grampus.GetJob(task.JobID) | result, err := grampus.GetJob(task.JobID) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetJob failed:" + err.Error()) | log.Error("GetJob failed:" + err.Error()) | ||||
| //ctx.ServerError("GetJob failed", err) | |||||
| //return | |||||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||||
| return | |||||
| } | } | ||||
| if result != nil { | if result != nil { | ||||
| if len(result.JobInfo.Tasks[0].CenterID) == 1 && len(result.JobInfo.Tasks[0].CenterName) == 1 { | 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] | 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.Status = grampus.TransTrainJobStatus(result.JobInfo.Status) | ||||
| if task.Status != result.JobInfo.Status || result.JobInfo.Status == models.GrampusStatusRunning { | if task.Status != result.JobInfo.Status || result.JobInfo.Status == models.GrampusStatusRunning { | ||||
| task.Duration = result.JobInfo.RunSec | task.Duration = result.JobInfo.RunSec | ||||
| @@ -654,6 +660,9 @@ func GrampusTrainJobShow(ctx *context.Context) { | |||||
| task.EndTime = task.StartTime.Add(task.Duration) | task.EndTime = task.StartTime.Add(task.Duration) | ||||
| } | } | ||||
| task.CorrectCreateUnix() | task.CorrectCreateUnix() | ||||
| if oldStatus != task.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(task, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob failed:" + err.Error()) | log.Error("UpdateJob failed:" + err.Error()) | ||||
| @@ -265,33 +265,38 @@ func NotebookShow(ctx *context.Context) { | |||||
| var ID = ctx.Params(":id") | var ID = ctx.Params(":id") | ||||
| task, err := models.GetCloudbrainByIDWithDeleted(ID) | task, err := models.GetCloudbrainByIDWithDeleted(ID) | ||||
| if err != nil { | 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 | return | ||||
| } | } | ||||
| result, err := modelarts.GetNotebook2(task.JobID) | result, err := modelarts.GetNotebook2(task.JobID) | ||||
| if err != nil { | 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 | return | ||||
| } | } | ||||
| if result != nil { | if result != nil { | ||||
| if task.DeletedAt.IsZero() { //normal record | if task.DeletedAt.IsZero() { //normal record | ||||
| if task.Status != result.Status { | if task.Status != result.Status { | ||||
| oldStatus := task.Status | |||||
| task.Status = result.Status | task.Status = result.Status | ||||
| models.ParseAndSetDurationFromModelArtsNotebook(result, task) | models.ParseAndSetDurationFromModelArtsNotebook(result, task) | ||||
| notification.NotifyChangeCloudbrainStatus(task, oldStatus) | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | 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 | return | ||||
| } | } | ||||
| } | } | ||||
| } else { //deleted record | } else { //deleted record | ||||
| } | } | ||||
| if task.FlavorCode == "" { | |||||
| task.FlavorCode = result.Flavor | |||||
| } | |||||
| } | } | ||||
| datasetDownload := make([]models.DatasetDownload, 0) | datasetDownload := make([]models.DatasetDownload, 0) | ||||
| @@ -526,6 +531,8 @@ func NotebookManage(ctx *context.Context) { | |||||
| Description: task.Description, | Description: task.Description, | ||||
| CreatedUnix: createTime, | CreatedUnix: createTime, | ||||
| UpdatedUnix: createTime, | UpdatedUnix: createTime, | ||||
| FlavorCode: task.FlavorCode, | |||||
| FlavorName: task.FlavorName, | |||||
| } | } | ||||
| err = models.RestartCloudbrain(task, newTask) | err = models.RestartCloudbrain(task, newTask) | ||||
| @@ -538,11 +545,15 @@ func NotebookManage(ctx *context.Context) { | |||||
| ID = strconv.FormatInt(newTask.ID, 10) | ID = strconv.FormatInt(newTask.ID, 10) | ||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, ID, task.DisplayJobName, models.ActionCreateDebugNPUTask) | notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, ID, task.DisplayJobName, models.ActionCreateDebugNPUTask) | ||||
| } else { | } else { | ||||
| oldStatus := task.Status | |||||
| task.Status = res.Status | task.Status = res.Status | ||||
| if task.EndTime == 0 && models.IsModelArtsDebugJobTerminal(task.Status) { | if task.EndTime == 0 && models.IsModelArtsDebugJobTerminal(task.Status) { | ||||
| task.EndTime = timeutil.TimeStampNow() | task.EndTime = timeutil.TimeStampNow() | ||||
| } | } | ||||
| task.ComputeAndSetDuration() | task.ComputeAndSetDuration() | ||||
| if oldStatus != task.Status { | |||||
| notification.NotifyChangeCloudbrainStatus(task, oldStatus) | |||||
| } | |||||
| err = models.UpdateJob(task) | err = models.UpdateJob(task) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("UpdateJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"]) | 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") | var listType = ctx.Query("debugListType") | ||||
| task := ctx.Cloudbrain | 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) | log.Error("the job(%s) has not been stopped", task.JobName) | ||||
| ctx.RenderWithErr("the job has not been stopped", tplDebugJobIndex, nil) | ctx.RenderWithErr("the job has not been stopped", tplDebugJobIndex, nil) | ||||
| return | return | ||||
| @@ -680,7 +691,7 @@ func trainJobNewDataPrepare(ctx *context.Context) error { | |||||
| //} | //} | ||||
| t := time.Now() | 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 | ctx.Data["display_job_name"] = displayJobName | ||||
| attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | ||||
| @@ -785,7 +796,7 @@ func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArts | |||||
| //} | //} | ||||
| t := time.Now() | 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 | ctx.Data["display_job_name"] = displayJobName | ||||
| attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | 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["config_list"] = configList.ParaConfigs | ||||
| ctx.Data["bootFile"] = form.BootFile | ctx.Data["bootFile"] = form.BootFile | ||||
| ctx.Data["uuid"] = form.Attachment | 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["branch_name"] = form.BranchName | ||||
| ctx.Data["datasetType"] = models.TypeCloudBrainTwo | ctx.Data["datasetType"] = models.TypeCloudBrainTwo | ||||
| @@ -962,7 +979,7 @@ func versionErrorDataPrepare(ctx *context.Context, form auth.CreateModelArtsTrai | |||||
| } | } | ||||
| t := time.Now() | 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 | ctx.Data["job_name"] = task.JobName | ||||
| attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | ||||
| @@ -1727,7 +1744,11 @@ func TrainJobShow(ctx *context.Context) { | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetVersionListTasks(%s) failed:%v", jobID, err.Error()) | 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 | return | ||||
| } | } | ||||
| //设置权限 | //设置权限 | ||||
| @@ -2305,7 +2326,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { | |||||
| ctx.Data["newInference"] = true | ctx.Data["newInference"] = true | ||||
| t := time.Now() | 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 | ctx.Data["display_job_name"] = displayJobName | ||||
| attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | 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["config_list"] = configList.ParaConfigs | ||||
| ctx.Data["bootFile"] = form.BootFile | ctx.Data["bootFile"] = form.BootFile | ||||
| ctx.Data["uuid"] = form.Attachment | 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["branch_name"] = form.BranchName | ||||
| ctx.Data["model_name"] = form.ModelName | ctx.Data["model_name"] = form.ModelName | ||||
| ctx.Data["model_version"] = form.ModelVersion | ctx.Data["model_version"] = form.ModelVersion | ||||
| @@ -2450,7 +2477,7 @@ func InferenceJobShow(ctx *context.Context) { | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("GetInferenceTask(%s) failed:%v", jobID, err.Error()) | log.Error("GetInferenceTask(%s) failed:%v", jobID, err.Error()) | ||||
| ctx.RenderWithErr(err.Error(), tplModelArtsInferenceJobShow, nil) | |||||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||||
| return | return | ||||
| } | } | ||||
| //设置权限 | //设置权限 | ||||
| @@ -5,6 +5,8 @@ import ( | |||||
| "net/http" | "net/http" | ||||
| "net/url" | "net/url" | ||||
| "os" | "os" | ||||
| "strconv" | |||||
| "strings" | |||||
| "time" | "time" | ||||
| "code.gitea.io/gitea/models" | "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" { | if tableName == "public.user_business_analysis_yesterday" { | ||||
| mapInterface["datarecordbegintime"] = setting.RadarMap.GrowthBeginTime | mapInterface["datarecordbegintime"] = setting.RadarMap.GrowthBeginTime | ||||
| if len(result) > 0 { | 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") | mapInterface["lastUpdatedTime"] = dateTime.Format("2006-01-02 15:04:05") | ||||
| } else { | } else { | ||||
| mapInterface["lastUpdatedTime"] = "" | mapInterface["lastUpdatedTime"] = "" | ||||
| @@ -450,7 +452,7 @@ func DownloadUserDefineFile(ctx *context.Context) { | |||||
| func QueryUserMetricsCurrentMonth(ctx *context.Context) { | func QueryUserMetricsCurrentMonth(ctx *context.Context) { | ||||
| currentTimeNow := time.Now() | 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 := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), 1, 0, 0, 0, 0, currentTimeNow.Location()) | ||||
| pageStartTime = getStartTime(pageStartTime) | pageStartTime = getStartTime(pageStartTime) | ||||
| queryMetrics(ctx, "public.user_business_analysis_current_month", pageStartTime, pageEndTime) | 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 := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset) | ||||
| pageStartTime = getStartTime(pageStartTime) | 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) | queryMetrics(ctx, "public.user_business_analysis_current_week", pageStartTime, pageEndTime) | ||||
| } | } | ||||
| func QueryUserStaticCurrentWeek(ctx *context.Context) { | func QueryUserStaticCurrentWeek(ctx *context.Context) { | ||||
| @@ -490,7 +492,7 @@ func QueryUserMetricsCurrentYear(ctx *context.Context) { | |||||
| currentTimeNow := time.Now() | currentTimeNow := time.Now() | ||||
| pageStartTime := time.Date(currentTimeNow.Year(), 1, 1, 0, 0, 0, 0, currentTimeNow.Location()) | pageStartTime := time.Date(currentTimeNow.Year(), 1, 1, 0, 0, 0, 0, currentTimeNow.Location()) | ||||
| pageStartTime = getStartTime(pageStartTime) | 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) | queryMetrics(ctx, "public.user_business_analysis_current_year", pageStartTime, pageEndTime) | ||||
| } | } | ||||
| func QueryUserStaticCurrentYear(ctx *context.Context) { | func QueryUserStaticCurrentYear(ctx *context.Context) { | ||||
| @@ -500,7 +502,7 @@ func QueryUserMetricsLast30Day(ctx *context.Context) { | |||||
| currentTimeNow := time.Now() | currentTimeNow := time.Now() | ||||
| pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, -30) | pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, -30) | ||||
| pageStartTime = getStartTime(pageStartTime) | 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) | queryMetrics(ctx, "public.user_business_analysis_last30_day", pageStartTime, pageEndTime) | ||||
| } | } | ||||
| func QueryUserStaticLast30Day(ctx *context.Context) { | 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)) | queryUserDataPage(ctx, "public.user_business_analysis_last_month", new(models.UserBusinessAnalysisLastMonth)) | ||||
| } | } | ||||
| func QueryUserMetricsYesterday(ctx *context.Context) { | 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 := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local) | ||||
| pageStartTime = getStartTime(pageStartTime) | 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(), 23, 59, 59, 0, currentTimeNow.Location()) | ||||
| @@ -531,7 +533,7 @@ func QueryUserMetricsAll(ctx *context.Context) { | |||||
| currentTimeNow := time.Now() | currentTimeNow := time.Now() | ||||
| pageStartTime := time.Date(2022, 4, 5, 0, 0, 0, 0, currentTimeNow.Location()) | pageStartTime := time.Date(2022, 4, 5, 0, 0, 0, 0, currentTimeNow.Location()) | ||||
| pageStartTime = getStartTime(pageStartTime) | 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) | queryMetrics(ctx, "public.user_business_analysis_all", pageStartTime, pageEndTime) | ||||
| } | } | ||||
| func QueryUserStaticAll(ctx *context.Context) { | 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) | ctx.JSON(http.StatusOK, ctx.Tr("user.static.downloadinfo")+"/api/v1/download_user_define_file?filename="+filename) | ||||
| } else { | } else { | ||||
| mapInterface := make(map[string]interface{}) | 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["data"] = re | ||||
| mapInterface["count"] = count | mapInterface["count"] = count | ||||
| ctx.JSON(http.StatusOK, mapInterface) | 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) | 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()) | |||||
| } | |||||
| } | |||||
| @@ -484,6 +484,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st | |||||
| ) | ) | ||||
| } else if isNoteBook { | } else if isNoteBook { | ||||
| ctx.Data["FileContent"] = string(buf) | ctx.Data["FileContent"] = string(buf) | ||||
| ctx.Data["FileParentURL"] = path.Dir(rawLink+"/"+ctx.Repo.TreePath) + "/" | |||||
| } else { | } else { | ||||
| // Building code view blocks with line number on server side. | // Building code view blocks with line number on server side. | ||||
| var fileContent string | var fileContent string | ||||
| @@ -1016,6 +1016,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| }, context.RepoAssignment(), context.RepoMustNotBeArchived(), reqRepoAdmin) | }, context.RepoAssignment(), context.RepoMustNotBeArchived(), reqRepoAdmin) | ||||
| m.Group("/image/:id", func() { | m.Group("/image/:id", func() { | ||||
| m.Get("", repo.GetImage) | |||||
| m.Get("/:from", cloudbrain.AdminOrImageCreaterRight, repo.CloudBrainImageEdit) | m.Get("/:from", cloudbrain.AdminOrImageCreaterRight, repo.CloudBrainImageEdit) | ||||
| m.Post("", cloudbrain.AdminOrImageCreaterRight, bindIgnErr(auth.EditImageCloudBrainForm{}), repo.CloudBrainImageEditPost) | m.Post("", cloudbrain.AdminOrImageCreaterRight, bindIgnErr(auth.EditImageCloudBrainForm{}), repo.CloudBrainImageEditPost) | ||||
| m.Delete("", cloudbrain.AdminOrImageCreaterRight, repo.CloudBrainImageDelete) | m.Delete("", cloudbrain.AdminOrImageCreaterRight, repo.CloudBrainImageDelete) | ||||
| @@ -1135,7 +1136,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| }) | }) | ||||
| }, context.RepoRef()) | }, context.RepoRef()) | ||||
| m.Group("/modelmanage", func() { | 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_model_convert", reqRepoModelManageWriter, repo.SaveModelConvert) | ||||
| m.Post("/create_new_model", repo.SaveNewNameModel) | m.Post("/create_new_model", repo.SaveNewNameModel) | ||||
| m.Delete("/delete_model", repo.DeleteModel) | m.Delete("/delete_model", repo.DeleteModel) | ||||
| @@ -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()) | 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 { | if err == nil { | ||||
| searchJson, _ := json.Marshal(res) | |||||
| log.Info("searchJson=" + string(searchJson)) | |||||
| esresult := makeRepoResult(res, Key, OnlyReturnNum, language) | esresult := makeRepoResult(res, Key, OnlyReturnNum, language) | ||||
| setForkRepoOrder(esresult) | |||||
| resultObj.Total = resultObj.PrivateTotal + esresult.Total | resultObj.Total = resultObj.PrivateTotal + esresult.Total | ||||
| isNeedSort := false | isNeedSort := false | ||||
| if len(resultObj.Result) > 0 { | 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) { | func sortRepo(Result []map[string]interface{}, SortBy string, ascending bool) { | ||||
| orderBy := "" | orderBy := "" | ||||
| switch SortBy { | switch SortBy { | ||||
| @@ -479,6 +502,7 @@ func makeRepoResult(sRes *elastic.SearchResult, Key string, OnlyReturnNum bool, | |||||
| record["num_stars"] = recordSource["num_stars"] | record["num_stars"] = recordSource["num_stars"] | ||||
| record["num_forks"] = recordSource["num_forks"] | record["num_forks"] = recordSource["num_forks"] | ||||
| record["lower_alias"] = recordSource["lower_alias"] | record["lower_alias"] = recordSource["lower_alias"] | ||||
| record["fork_id"] = recordSource["fork_id"] | |||||
| if recordSource["topics"] != nil { | if recordSource["topics"] != nil { | ||||
| topicsStr := recordSource["topics"].(string) | topicsStr := recordSource["topics"].(string) | ||||
| log.Info("topicsStr=" + topicsStr) | log.Info("topicsStr=" + topicsStr) | ||||
| @@ -23,6 +23,7 @@ import ( | |||||
| "code.gitea.io/gitea/modules/modelarts" | "code.gitea.io/gitea/modules/modelarts" | ||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| "code.gitea.io/gitea/modules/util" | "code.gitea.io/gitea/modules/util" | ||||
| "code.gitea.io/gitea/routers/repo" | |||||
| issue_service "code.gitea.io/gitea/services/issue" | issue_service "code.gitea.io/gitea/services/issue" | ||||
| pull_service "code.gitea.io/gitea/services/pull" | pull_service "code.gitea.io/gitea/services/pull" | ||||
| @@ -834,6 +835,11 @@ func Cloudbrains(ctx *context.Context) { | |||||
| ciTasks[i].CanDebug = true | ciTasks[i].CanDebug = true | ||||
| ciTasks[i].CanDel = true | ciTasks[i].CanDel = true | ||||
| ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource | 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)) | pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, getTotalPage(count, setting.UI.IssuePagingNum)) | ||||
| @@ -116,8 +116,8 @@ func Profile(ctx *context.Context) { | |||||
| } | } | ||||
| var opts = models.FindOrgMembersOpts{ | var opts = models.FindOrgMembersOpts{ | ||||
| OrgID: org.ID, | |||||
| PublicOnly: true, | |||||
| OrgID: org.ID, | |||||
| PublicOnly: true, | |||||
| } | } | ||||
| if ctx.User != nil { | if ctx.User != nil { | ||||
| @@ -261,7 +261,7 @@ func Profile(ctx *context.Context) { | |||||
| IsOwner: isOwner, | IsOwner: isOwner, | ||||
| ListOptions: models.ListOptions{ | ListOptions: models.ListOptions{ | ||||
| Page: page, | Page: page, | ||||
| PageSize: setting.UI.ExplorePagingNum, | |||||
| PageSize: setting.UI.User.RepoPagingNum, | |||||
| }, | }, | ||||
| CloudBrainType: -1, | CloudBrainType: -1, | ||||
| } | } | ||||
| @@ -18,7 +18,7 @@ | |||||
| data-all-compute="{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}" | data-all-compute="{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}" | ||||
| data-all-status="{{.i18n.Tr "admin.cloudbrain.all_status"}}"></div> | data-all-status="{{.i18n.Tr "admin.cloudbrain.all_status"}}"></div> | ||||
| {{template "admin/navbar" .}} | {{template "admin/navbar" .}} | ||||
| <div class="ui container" style="width: 80%;"> | |||||
| <div class="ui container" style="width: 95%;"> | |||||
| {{template "base/alert" .}} | {{template "base/alert" .}} | ||||
| <div class="ui grid"> | <div class="ui grid"> | ||||
| <div class="row" style="border: 1px solid #d4d4d5;margin-top: 15px;padding-top: 0;"> | <div class="row" style="border: 1px solid #d4d4d5;margin-top: 15px;padding-top: 0;"> | ||||
| @@ -34,34 +34,46 @@ | |||||
| <!-- 表头 --> | <!-- 表头 --> | ||||
| <div class="ui grid stackable" style="background: #f0f0f0;;"> | <div class="ui grid stackable" style="background: #f0f0f0;;"> | ||||
| <div class="row"> | <div class="row"> | ||||
| <div class="two wide column nowrap"> | |||||
| <span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task"}}</span> | |||||
| <div class="two wide column nowrap" style="width:10% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_task"}}</span> | |||||
| </div> | </div> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task_type"}}</span> | |||||
| <!-- 集群 --> | |||||
| <div class="one wide column text center nowrap" style="width:6% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.cluster"}}</span> | |||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap" style="width: 10% !important;"> | |||||
| <div class="one wide column text center nowrap" style="width:6% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_task_type"}}</span> | |||||
| </div> | |||||
| <div class="two wide column text center nowrap" style="width: 6% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.status"}}</span> | <span>{{$.i18n.Tr "repo.modelarts.status"}}</span> | ||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap" style="width: 10% !important;"> | |||||
| <div class="two wide column text center nowrap" style="width: 8% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | ||||
| </div> | </div> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <div class="one wide column text center nowrap" style="width: 5% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | ||||
| </div> | </div> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <div class="one wide column text center nowrap" style="width: 5% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | ||||
| </div> | </div> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <!-- 智算中心 --> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.ai_center"}}</span> | |||||
| </div> | |||||
| <!-- XPU类型 --> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.card_type"}}</span> | |||||
| </div> | |||||
| <div class="one wide column text center nowrap" style="width:4% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | ||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap"> | |||||
| <div class="two wide column text center nowrap" style="width:10% !important;"> | |||||
| <span>{{$.i18n.Tr "repository"}}</span> | <span>{{$.i18n.Tr "repository"}}</span> | ||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap"> | |||||
| <div class="two wide column text center nowrap" style="width:10% !important;"> | |||||
| <span>{{.i18n.Tr "admin.cloudbrain.cloudbrain_name"}}</span> | <span>{{.i18n.Tr "admin.cloudbrain.cloudbrain_name"}}</span> | ||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | |||||
| <div class="two wide column text center nowrap" style="width: 12%!important;"> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -78,24 +90,24 @@ | |||||
| {{$JobID = .JobID}} | {{$JobID = .JobID}} | ||||
| {{end}} | {{end}} | ||||
| <!-- {{$JobID}} --> | <!-- {{$JobID}} --> | ||||
| <div class="two wide column nowrap"> | |||||
| <div class="two wide column nowrap" style="width:10% !important;"> | |||||
| {{if eq .JobType "DEBUG"}} | {{if eq .JobType "DEBUG"}} | ||||
| <a class="title" | <a class="title" | ||||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{$JobID}}{{else}}/modelarts/notebook/{{$JobID}}{{end}}" | href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{$JobID}}{{else}}/modelarts/notebook/{{$JobID}}{{end}}" | ||||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}} | {{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}} | ||||
| <a class="title" | <a class="title" | ||||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | ||||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{else if eq .JobType "INFERENCE"}} | {{else if eq .JobType "INFERENCE"}} | ||||
| <a class="title" | <a class="title" | ||||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}" | |||||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .Cloudbrain.Type 1}}modelarts{{else if eq .Cloudbrain.Type 0}}cloudbrain{{end}}/inference-job/{{$JobID}}" | |||||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | title="{{.DisplayJobName}}" style="font-size: 14px;"> | ||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| @@ -103,26 +115,27 @@ | |||||
| {{else if eq .JobType "TRAIN"}} | {{else if eq .JobType "TRAIN"}} | ||||
| <a class="title" | <a class="title" | ||||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .Cloudbrain.Type 0}}/cloudbrain{{else if eq .Cloudbrain.Type 1}}/modelarts{{else if eq .Cloudbrain.Type 2}}/grampus{{end}}/train-job/{{$JobID}}" | href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .Cloudbrain.Type 0}}/cloudbrain{{else if eq .Cloudbrain.Type 1}}/modelarts{{else if eq .Cloudbrain.Type 2}}/grampus{{end}}/train-job/{{$JobID}}" | ||||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{else if eq .JobType "BENCHMARK"}} | {{else if eq .JobType "BENCHMARK"}} | ||||
| <a class="title" | <a class="title" | ||||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | ||||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <!-- 任务类型 --> | |||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="font-size: 12px;">{{.JobType}} </span> | |||||
| <!-- 集群 --> | |||||
| <div class="one wide column text center nowrap" style="width:6% !important;"> | |||||
| <span | |||||
| style="font-size: 12px;">{{if .Cluster}}{{.Cluster}}{{else}}--{{end}}</span> | |||||
| </div> | </div> | ||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column text center nowrap" | <div class="two wide column text center nowrap" | ||||
| style="padding-left: 2.2rem !important; width: 10% !important;"> | |||||
| style="width: 6% !important;"> | |||||
| <span class="job-status" id="{{$JobID}}" | <span class="job-status" id="{{$JobID}}" | ||||
| data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' | data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' | ||||
| data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | ||||
| @@ -131,23 +144,39 @@ | |||||
| style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | ||||
| </span> | </span> | ||||
| </div> | </div> | ||||
| <!-- 任务类型 --> | |||||
| <div class="one wide column text center nowrap" style="width: 6% !important;"> | |||||
| <span style="font-size: 12px;">{{.JobType}} </span> | |||||
| </div> | |||||
| <!-- 任务创建时间 --> | <!-- 任务创建时间 --> | ||||
| <div class="two wide column text center nowrap" style="width: 10% !important;"> | |||||
| <div class="two wide column text center nowrap" style="width: 8% !important;"> | |||||
| <span style="font-size: 12px;" | <span style="font-size: 12px;" | ||||
| class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | ||||
| </div> | </div> | ||||
| <!-- 任务运行时间 --> | <!-- 任务运行时间 --> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <div class="one wide column text center nowrap" style="width: 5% !important;"> | |||||
| <span style="font-size: 12px;" | <span style="font-size: 12px;" | ||||
| id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | ||||
| </div> | </div> | ||||
| <!-- 计算资源 --> | <!-- 计算资源 --> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <div class="one wide column text center nowrap" style="width: 5% !important;"> | |||||
| <span | <span | ||||
| style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | ||||
| </div> | </div> | ||||
| <!-- 智算中心 --> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important;"> | |||||
| <span | |||||
| style="font-size: 12px;">{{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}}</span> | |||||
| </div> | |||||
| <!-- XPU类型 --> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important;"> | |||||
| <span style="font-size: 12px;" title="{{.CardType}}"> | |||||
| {{if .CardType}}{{.CardType}}{{else}}--{{end}} | |||||
| </span> | |||||
| </div> | |||||
| <!-- 创建者 --> | <!-- 创建者 --> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <div class="one wide column text center nowrap" style="width:4% !important;"> | |||||
| {{if .User.Name}} | {{if .User.Name}} | ||||
| <a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img | <a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img | ||||
| class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | ||||
| @@ -157,16 +186,24 @@ | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <!-- 项目 --> | <!-- 项目 --> | ||||
| <div class="two wide column text center nowrap"> | |||||
| <div class="two wide column text center nowrap" style="width:10% !important;"> | |||||
| <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}" | <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}" | ||||
| title="{{.Repo.OwnerName}}/{{.Repo.Alias}}">{{.Repo.OwnerName}}/{{.Repo.Alias}}</a> | title="{{.Repo.OwnerName}}/{{.Repo.Alias}}">{{.Repo.OwnerName}}/{{.Repo.Alias}}</a> | ||||
| </div> | </div> | ||||
| <!-- 云脑侧名称 --> | <!-- 云脑侧名称 --> | ||||
| <div class="two wide column text center nowrap" | <div class="two wide column text center nowrap" | ||||
| style="overflow: hidden;text-overflow:ellipsis;"> | |||||
| <span class="fitted" title="{{.JobName}}">{{.JobName}}</span> | |||||
| style="overflow: hidden;text-overflow:ellipsis;width:10% !important;"> | |||||
| <span class="ui poping up clipboard" data-position="top center" id="clipboard-btn" style="cursor:pointer" | |||||
| data-clipboard-text="{{.JobName}}" | |||||
| data-success="{{$.i18n.Tr "repo.copy_link_success"}}" | |||||
| data-error="{{$.i18n.Tr "repo.copy_link_error"}}" | |||||
| data-content="{{$.i18n.Tr "repo.copy_link"}}" | |||||
| data-variation="inverted tiny" | |||||
| > | |||||
| <span class="fitted" title="{{.JobName}}">{{.JobName}}</span> | |||||
| </span> | |||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | |||||
| <div class="two wide column text center nowrap" style="width: 14%!important;"> | |||||
| {{if eq .JobType "DEBUG"}} | {{if eq .JobType "DEBUG"}} | ||||
| <div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
| <form id="debugAgainForm-{{$JobID}}"> | <form id="debugAgainForm-{{$JobID}}"> | ||||
| @@ -235,36 +272,37 @@ | |||||
| <div class="ui grid stackable item"> | <div class="ui grid stackable item"> | ||||
| <div class="row"> | <div class="row"> | ||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="two wide column nowrap"> | |||||
| <div class="two wide column nowrap" style="width:10% !important;"> | |||||
| {{if eq .JobType "DEBUG"}} | {{if eq .JobType "DEBUG"}} | ||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{else if eq .JobType "INFERENCE"}} | {{else if eq .JobType "INFERENCE"}} | ||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{else if eq .JobType "TRAIN"}} | {{else if eq .JobType "TRAIN"}} | ||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{else if eq .JobType "BENCHMARK"}} | {{else if eq .JobType "BENCHMARK"}} | ||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <!-- 任务类型 --> | |||||
| <div class="one wide column text center nowrap"> | |||||
| <span style="font-size: 12px;">{{.JobType}} </span> | |||||
| <!-- 集群 --> | |||||
| <div class="one wide column text center nowrap" style="width:6% !important;"> | |||||
| <span | |||||
| style="font-size: 12px;">{{if .Cluster}}{{.Cluster}}{{else}}--{{end}}</span> | |||||
| </div> | </div> | ||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column text center nowrap" | <div class="two wide column text center nowrap" | ||||
| style="padding-left: 2.2rem !important; width: 10% !important;"> | |||||
| style="width: 6% !important;"> | |||||
| <span class="job-status" id="{{$JobID}}" data-jobid="{{$JobID}}" | <span class="job-status" id="{{$JobID}}" data-jobid="{{$JobID}}" | ||||
| data-version="{{.VersionName}}"> | data-version="{{.VersionName}}"> | ||||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" | <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" | ||||
| @@ -272,23 +310,39 @@ | |||||
| style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | ||||
| </span> | </span> | ||||
| </div> | </div> | ||||
| <!-- 任务类型 --> | |||||
| <div class="one wide column text center nowrap" style="width:6% !important;"> | |||||
| <span style="font-size: 12px;">{{.JobType}} </span> | |||||
| </div> | |||||
| <!-- 任务创建时间 --> | <!-- 任务创建时间 --> | ||||
| <div class="two wide column text center nowrap" style="width: 10% !important;"> | |||||
| <div class="two wide column text center nowrap" style="width: 8% !important;"> | |||||
| <span style="font-size: 12px;" | <span style="font-size: 12px;" | ||||
| class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | ||||
| </div> | </div> | ||||
| <!-- 任务运行时间 --> | <!-- 任务运行时间 --> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <div class="one wide column text center nowrap" style="width:5% !important;"> | |||||
| <span style="font-size: 12px;" | <span style="font-size: 12px;" | ||||
| id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | ||||
| </div> | </div> | ||||
| <!-- 计算资源 --> | <!-- 计算资源 --> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <div class="one wide column text center nowrap" style="width:5% !important;"> | |||||
| <span | <span | ||||
| style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | ||||
| </div> | </div> | ||||
| <!-- 智算中心 --> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important;"> | |||||
| <span | |||||
| style="font-size: 12px;">{{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}}</span> | |||||
| </div> | |||||
| <!-- XPU类型 --> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important;"> | |||||
| <span style="font-size: 12px;" title="{{.CardType}}"> | |||||
| {{if .CardType}}{{.CardType}}{{else}}--{{end}} | |||||
| </span> | |||||
| </div> | |||||
| <!-- 创建者 --> | <!-- 创建者 --> | ||||
| <div class="one wide column text center nowrap"> | |||||
| <div class="one wide column text center nowrap" style="width:4% !important;"> | |||||
| {{if .User.Name}} | {{if .User.Name}} | ||||
| <a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img | <a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img | ||||
| class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | ||||
| @@ -298,15 +352,24 @@ | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <!-- 项目 --> | <!-- 项目 --> | ||||
| <div class="two wide column text center nowrap"> | |||||
| <div class="two wide column text center nowrap" style="width:10% !important;"> | |||||
| <a href="" title="">--</a> | <a href="" title="">--</a> | ||||
| </div> | </div> | ||||
| <!-- 云脑侧名称 --> | <!-- 云脑侧名称 --> | ||||
| <div class="two wide column text center nowrap" | <div class="two wide column text center nowrap" | ||||
| style="overflow: hidden;text-overflow:ellipsis;"> | |||||
| <span class="fitted">{{.JobName}}</span> | |||||
| style="overflow: hidden;text-overflow:ellipsis;width:10% !important;"> | |||||
| <span class="ui poping up clipboard" data-position="top center" id="clipboard-btn" style="cursor:pointer" | |||||
| data-clipboard-text="{{.JobName}}" | |||||
| data-success="{{$.i18n.Tr "repo.copy_link_success"}}" | |||||
| data-error="{{$.i18n.Tr "repo.copy_link_error"}}" | |||||
| data-content="{{$.i18n.Tr "repo.copy_link"}}" | |||||
| data-variation="inverted tiny" | |||||
| > | |||||
| <span class="fitted" title="{{.JobName}}">{{.JobName}}</span> | |||||
| </span> | |||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | |||||
| <div class="two wide column text center nowrap" style="width: 14%!important;"> | |||||
| {{if eq .JobType "DEBUG"}} | {{if eq .JobType "DEBUG"}} | ||||
| <div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
| <form id="debugAgainForm-{{$JobID}}"> | <form id="debugAgainForm-{{$JobID}}"> | ||||
| @@ -15,7 +15,7 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="ui container" style="width: 80%;"> | |||||
| <div class="ui container" style="width: 90%;"> | |||||
| <div class="ui grid"> | <div class="ui grid"> | ||||
| <div class="row"> | <div class="row"> | ||||
| <div class="ui {{if $.PageIsUserCloudBrain}}sixteen{{else}}six{{end}} wide column" style="margin: 1rem 0;" id="userCloud"> | <div class="ui {{if $.PageIsUserCloudBrain}}sixteen{{else}}six{{end}} wide column" style="margin: 1rem 0;" id="userCloud"> | ||||
| @@ -35,7 +35,7 @@ | |||||
| {{range .Datasets}} | {{range .Datasets}} | ||||
| <tr> | <tr> | ||||
| <td>{{.ID}}</td> | <td>{{.ID}}</td> | ||||
| <td style="display: flex;align-items: center;"><a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Alias}}/datasets">{{.Title}}</a>{{if .Recommend}}<img src="/img/jian.svg" style="margin-left: 0.5rem;">{{end}}</td> | |||||
| <td style="display: flex;align-items: center;"><a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/datasets">{{.Title}}</a>{{if .Recommend}}<img src="/img/jian.svg" style="margin-left: 0.5rem;">{{end}}</td> | |||||
| <td><i class="fa fa{{if .IsPrivate}}-check{{end}}-square-o"></i></td> | <td><i class="fa fa{{if .IsPrivate}}-check{{end}}-square-o"></i></td> | ||||
| <td><span title="{{.CreatedUnix.FormatLong}}">{{.CreatedUnix.FormatShort}}</span></td> | <td><span title="{{.CreatedUnix.FormatLong}}">{{.CreatedUnix.FormatShort}}</span></td> | ||||
| <td>{{if .Recommend}}<span class="set_dataset" style="color: rgb(250, 140, 22);cursor: pointer;" data-url="{{$.Link}}/{{.ID}}/action/unrecommend">{{$.i18n.Tr "admin.datasets.unrecommend"}}</span>{{else}}<span class="set_dataset" style="color: rgb(19, 194, 141);cursor: pointer;" data-url="{{$.Link}}/{{.ID}}/action/recommend">{{$.i18n.Tr "admin.datasets.recommend"}}</span>{{end}}</td> | <td>{{if .Recommend}}<span class="set_dataset" style="color: rgb(250, 140, 22);cursor: pointer;" data-url="{{$.Link}}/{{.ID}}/action/unrecommend">{{$.i18n.Tr "admin.datasets.unrecommend"}}</span>{{else}}<span class="set_dataset" style="color: rgb(19, 194, 141);cursor: pointer;" data-url="{{$.Link}}/{{.ID}}/action/recommend">{{$.i18n.Tr "admin.datasets.recommend"}}</span>{{end}}</td> | ||||
| @@ -48,4 +48,4 @@ | |||||
| {{template "base/paginate" .}} | {{template "base/paginate" .}} | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | |||||
| {{template "base/footer" .}} | |||||
| @@ -109,6 +109,11 @@ | |||||
| ], | ], | ||||
| {{end}} | {{end}} | ||||
| }; | }; | ||||
| {{if .IsSigned}} | |||||
| window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}'); | |||||
| {{else}} | |||||
| window.sessionStorage.removeItem('_csrf'); | |||||
| {{end}} | |||||
| </script> | </script> | ||||
| <link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png"> | <link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png"> | ||||
| <link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926"> | <link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926"> | ||||
| @@ -109,6 +109,11 @@ | |||||
| ], | ], | ||||
| {{end}} | {{end}} | ||||
| }; | }; | ||||
| {{if .IsSigned}} | |||||
| window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}'); | |||||
| {{else}} | |||||
| window.sessionStorage.removeItem('_csrf'); | |||||
| {{end}} | |||||
| </script> | </script> | ||||
| <link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png"> | <link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png"> | ||||
| <link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926"> | <link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926"> | ||||
| @@ -109,6 +109,11 @@ | |||||
| ], | ], | ||||
| {{end}} | {{end}} | ||||
| }; | }; | ||||
| {{if .IsSigned}} | |||||
| window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}'); | |||||
| {{else}} | |||||
| window.sessionStorage.removeItem('_csrf'); | |||||
| {{end}} | |||||
| </script> | </script> | ||||
| <link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png"> | <link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png"> | ||||
| <link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926"> | <link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926"> | ||||
| @@ -109,6 +109,11 @@ | |||||
| ], | ], | ||||
| {{end}} | {{end}} | ||||
| }; | }; | ||||
| {{if .IsSigned}} | |||||
| window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}'); | |||||
| {{else}} | |||||
| window.sessionStorage.removeItem('_csrf'); | |||||
| {{end}} | |||||
| </script> | </script> | ||||
| <link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png"> | <link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png"> | ||||
| <link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926"> | <link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926"> | ||||
| @@ -42,7 +42,8 @@ | |||||
| <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | ||||
| <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | ||||
| {{if .IsOperator}} | {{if .IsOperator}} | ||||
| <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}} | |||||
| <a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{end}} | {{end}} | ||||
| <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | ||||
| </div> | </div> | ||||
| @@ -73,7 +74,8 @@ | |||||
| <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | ||||
| <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | ||||
| {{if .IsOperator}} | {{if .IsOperator}} | ||||
| <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}} | |||||
| <a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{end}} | {{end}} | ||||
| <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | ||||
| </div> | </div> | ||||
| @@ -41,7 +41,8 @@ | |||||
| <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | ||||
| <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | ||||
| {{if .IsOperator}} | {{if .IsOperator}} | ||||
| <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}} | |||||
| <a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{end}} | {{end}} | ||||
| <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | ||||
| </div> | </div> | ||||
| @@ -71,7 +72,8 @@ | |||||
| <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | ||||
| <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | ||||
| {{if .IsOperator}} | {{if .IsOperator}} | ||||
| <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}} | |||||
| <a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{end}} | {{end}} | ||||
| <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | ||||
| </div> | </div> | ||||
| @@ -33,7 +33,8 @@ | |||||
| <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | ||||
| <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | ||||
| {{if .IsOperator}} | {{if .IsOperator}} | ||||
| <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}} | |||||
| <a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{end}} | {{end}} | ||||
| <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | ||||
| </div> | </div> | ||||
| @@ -64,7 +65,8 @@ | |||||
| <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | ||||
| <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | ||||
| {{if .IsOperator}} | {{if .IsOperator}} | ||||
| <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}} | |||||
| <a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{end}} | {{end}} | ||||
| <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | ||||
| </div> | </div> | ||||
| @@ -43,7 +43,8 @@ | |||||
| <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | ||||
| <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | ||||
| {{if .IsOperator}} | {{if .IsOperator}} | ||||
| <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}} | |||||
| <a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{end}} | {{end}} | ||||
| <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | ||||
| </div> | </div> | ||||
| @@ -74,7 +75,8 @@ | |||||
| <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "explore.organizations"}}</a> | ||||
| <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | <a class="item" href="{{AppSubUrl}}/explore/images">{{.i18n.Tr "explore.images"}}</a> | ||||
| {{if .IsOperator}} | {{if .IsOperator}} | ||||
| <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{/* <a class="item" href="{{AppSubUrl}}/explore/data_analysis">{{.i18n.Tr "explore.data_analysis"}}</a> */}} | |||||
| <a class="item" href="{{AppSubUrl}}/kanban/index.html" target="_blank" rel="opener">{{.i18n.Tr "explore.data_analysis"}}</a> | |||||
| {{end}} | {{end}} | ||||
| <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | <a class="item" href="{{AppSubUrl}}/OpenI">{{.i18n.Tr "custom.head.openi.repo"}}</a> | ||||
| </div> | </div> | ||||
| @@ -109,6 +109,11 @@ | |||||
| ], | ], | ||||
| {{end}} | {{end}} | ||||
| }; | }; | ||||
| {{if .IsSigned}} | |||||
| window.sessionStorage.setItem('_csrf', '{{.CsrfToken}}'); | |||||
| {{else}} | |||||
| window.sessionStorage.removeItem('_csrf'); | |||||
| {{end}} | |||||
| </script> | </script> | ||||
| <link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png"> | <link rel="shortcut icon" href="{{StaticUrlPrefix}}/img/favicon.png"> | ||||
| <link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926"> | <link rel="mask-icon" href="{{StaticUrlPrefix}}/img/openi-safari.svg" color="#609926"> | ||||
| @@ -9,6 +9,7 @@ | |||||
| {{end}} --> | {{end}} --> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{if .benchmarkMode}}{{.i18n.Tr "repo.model_manager"}}{{else}}{{.i18n.Tr "dataset.dataset"}}{{end}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{if .benchmarkMode}}{{.i18n.Tr "repo.model_manager"}}{{else}}{{.i18n.Tr "dataset.dataset"}}{{end}}</label> | ||||
| <input type="hidden" name="attachment" :value="dataset_uuid"> | <input type="hidden" name="attachment" :value="dataset_uuid"> | ||||
| <input type="hidden" name="dataset_name" :value="dataset_name"> | |||||
| <input class="disabled" type="text" :value="dataset_name" required onfocus="this.blur();" style="width: 48.5%;"> | <input class="disabled" type="text" :value="dataset_name" required onfocus="this.blur();" style="width: 48.5%;"> | ||||
| <el-button type="text" @click="dialogVisible = true" icon="el-icon-plus" style="color: #0366d6;"> | <el-button type="text" @click="dialogVisible = true" icon="el-icon-plus" style="color: #0366d6;"> | ||||
| {{if .benchmarkMode}}{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}{{else}}{{.i18n.Tr "dataset.select_dataset"}}{{end}} | {{if .benchmarkMode}}{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}{{else}}{{.i18n.Tr "dataset.select_dataset"}}{{end}} | ||||
| @@ -24,9 +24,9 @@ | |||||
| <div class="ui sixteen wide mobile ten wide tablet ten wide computer colum"> | <div class="ui sixteen wide mobile ten wide tablet ten wide computer colum"> | ||||
| {{range .Datasets}} | {{range .Datasets}} | ||||
| <div class="item"> | <div class="item"> | ||||
| <div class="ui header"> | |||||
| <a class="name" href="{{.Repo.Link}}/datasets"> | |||||
| {{.Repo.OwnerName}} / {{.Repo.Alias}} | |||||
| <div class="ui header" style="display: flex;"> | |||||
| <a class="name dataset-title-a" title="{{.Title}}" href="{{.Repo.Link}}/datasets"> | |||||
| {{.Title}} | |||||
| </a> | </a> | ||||
| <div class="ui right metas"> | <div class="ui right metas"> | ||||
| {{if .Task}} | {{if .Task}} | ||||
| @@ -40,7 +40,7 @@ | |||||
| </div> | </div> | ||||
| <div class="description"> | <div class="description"> | ||||
| {{if .Description}} | {{if .Description}} | ||||
| <p class="has-emoji">{{.Description}}</p> | |||||
| <p class="has-emoji" style="word-break: break-all;">{{.Description}}</p> | |||||
| {{else if .Repo.DescriptionHTML}} | {{else if .Repo.DescriptionHTML}} | ||||
| <p class="has-emoji">{{.Repo.DescriptionHTML}}</p> | <p class="has-emoji">{{.Repo.DescriptionHTML}}</p> | ||||
| {{end}} | {{end}} | ||||
| @@ -53,4 +53,7 @@ | |||||
| </div> | </div> | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| </div> | |||||
| </div> | |||||
| <script> | |||||
| console.log({{.Datasets}}) | |||||
| </script> | |||||
| @@ -48,7 +48,7 @@ | |||||
| <button class="ui green button"> | <button class="ui green button"> | ||||
| {{.i18n.Tr "org.create_org"}} | {{.i18n.Tr "org.create_org"}} | ||||
| </button> | </button> | ||||
| <a class="ui button" href="{{AppSubUrl}}/">{{.i18n.Tr "cancel"}}</a> | |||||
| <a class="ui button" href="javascript:history.go(-1)">{{.i18n.Tr "cancel"}}</a> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </form> | </form> | ||||
| @@ -69,8 +69,8 @@ | |||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" | <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" | ||||
| placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" | placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" | ||||
| tabindex="3" autofocus required maxlength="254"> | |||||
| <span class="tooltips" style="display: block;margin-left:11.5rem;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
| tabindex="3" autofocus required maxlength="36"> | |||||
| <span class="tooltips" style="display: block;margin-left:11.5rem;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span> | |||||
| </div> | </div> | ||||
| <div class="required min_title inline field"> | <div class="required min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;" | <label class="label-fix-width" style="font-weight: normal;" | ||||
| @@ -165,8 +165,8 @@ | |||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" | <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" | ||||
| placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" | placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" | ||||
| tabindex="3" autofocus required maxlength="254"> | |||||
| <span class="tooltips" style="display: block;margin-left: 11.5rem;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
| tabindex="3" autofocus required maxlength="36"> | |||||
| <span class="tooltips" style="display: block;margin-left: 11.5rem;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span> | |||||
| </div> | </div> | ||||
| <div class="min_title inline field"> | <div class="min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;" | <label class="label-fix-width" style="font-weight: normal;" | ||||
| @@ -331,7 +331,7 @@ | |||||
| identifier: 'display_job_name', | identifier: 'display_job_name', | ||||
| rules: [ | rules: [ | ||||
| { | { | ||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
| type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | |||||
| promt: '' | promt: '' | ||||
| } | } | ||||
| ] | ] | ||||
| @@ -353,7 +353,15 @@ | |||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | ||||
| {{.Image}} | |||||
| <span class="ui poping up clipboard" data-position="top center" id="clipboard-btn" style="cursor:pointer" | |||||
| data-clipboard-text="{{.Image}}" | |||||
| data-success="{{$.i18n.Tr "repo.copy_link_success"}}" | |||||
| data-error="{{$.i18n.Tr "repo.copy_link_error"}}" | |||||
| data-content="{{$.i18n.Tr "repo.copy_link"}}" | |||||
| data-variation="inverted tiny" | |||||
| > | |||||
| <span title="{{.Image}}">{{.Image}}</span> | |||||
| </span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -58,18 +58,16 @@ | |||||
| <form class="ui form" action="{{.Link}}" method="post"> | <form class="ui form" action="{{.Link}}" method="post"> | ||||
| {{.CsrfTokenHtml}} | {{.CsrfTokenHtml}} | ||||
| <input type="hidden" name="action" value="update"> | <input type="hidden" name="action" value="update"> | ||||
| <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||||
| <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | |||||
| {{if $.model_version}} | |||||
| <input type="hidden" id="ai_model_version" name="model_version" value="{{$.model_version}}"> | |||||
| {{else}} | |||||
| <input type="hidden" id="ai_image_name" value="{{.image}}"> | |||||
| <input type="hidden" id="ai_model_version" name="model_version" value=""> | <input type="hidden" id="ai_model_version" name="model_version" value=""> | ||||
| {{end}} | |||||
| {{if $.label_names}} | |||||
| <input type="hidden" id="ai_model_label" name="label_names" value="{{$.label_names}}"> | |||||
| {{else}} | |||||
| <input type="hidden" id="ai_model_label" name="label_names" value=""> | |||||
| {{end}} | |||||
| <input type="hidden" id="failed_train_url" value="{{$.train_url}}"> | |||||
| <input type="hidden" id="failed_model_name" value="{{$.model_name}}"> | |||||
| <input type="hidden" id="failed_model_version" value="{{$.model_version}}"> | |||||
| <input type="hidden" id="failed_ckpt_name" value="{{$.ckpt_name}}"> | |||||
| <input type="hidden" id="failed_train_url" value="{{$.train_url}}"> | |||||
| <input type="hidden" id="fail_dataset_name" value="{{$.dataset_name}}"> | |||||
| <input type="hidden" id="fail_dataset_uuid" value="{{$.attachment}}"> | |||||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | ||||
| <div class="required min_title inline field"> | <div class="required min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | ||||
| @@ -96,13 +94,17 @@ | |||||
| </div> | </div> | ||||
| <div class="required min_title inline field"> | <div class="required min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="64"> | |||||
| <span class="tooltips" style="margin-left:11.5rem;display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="36"> | |||||
| <span class="tooltips" style="margin-left:11.5rem;display: block;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span> | |||||
| </div> | </div> | ||||
| <div class="unite min_title inline field"> | <div class="unite min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | <label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | ||||
| {{if .description}} | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea> | |||||
| {{else}} | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | ||||
| {{end}} | |||||
| </div> | </div> | ||||
| <div class="ui divider"></div> | <div class="ui divider"></div> | ||||
| @@ -112,13 +114,8 @@ | |||||
| <div class="required eight wide field"> | <div class="required eight wide field"> | ||||
| <label style="font-weight: normal;white-space: nowrap;width: 210px;text-align: right;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label> | <label style="font-weight: normal;white-space: nowrap;width: 210px;text-align: right;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label> | ||||
| <div class="ui fluid search selection dropdown loading " id="select_model"> | <div class="ui fluid search selection dropdown loading " id="select_model"> | ||||
| {{if $.ckpt_name}} | |||||
| <input type="hidden" name="model_name" value="{{$.model_name}}" required> | |||||
| <div class="text">{{$.model_name}}</div> | |||||
| {{else}} | |||||
| <input type="hidden" name="model_name" required> | <input type="hidden" name="model_name" required> | ||||
| <div class="text"></div> | <div class="text"></div> | ||||
| {{end}} | |||||
| <i class="dropdown icon"></i> | <i class="dropdown icon"></i> | ||||
| <div class="menu" id="model_name"> | <div class="menu" id="model_name"> | ||||
| </div> | </div> | ||||
| @@ -126,13 +123,8 @@ | |||||
| </div> | </div> | ||||
| <div class="three wide field"> | <div class="three wide field"> | ||||
| <div class="ui fluid search selection dropdown" id="select_model_version"> | <div class="ui fluid search selection dropdown" id="select_model_version"> | ||||
| {{if $.ckpt_name}} | |||||
| <input type="hidden" name="train_url" value="{{$.train_url}}" required> | |||||
| <div class="text">{{$.model_version}}</div> | |||||
| {{else}} | |||||
| <input type="hidden" name="train_url" required> | <input type="hidden" name="train_url" required> | ||||
| <div class="text"></div> | <div class="text"></div> | ||||
| {{end}} | |||||
| <i class="dropdown icon"></i> | <i class="dropdown icon"></i> | ||||
| <div class="menu" id="model_name_version"> | <div class="menu" id="model_name_version"> | ||||
| </div> | </div> | ||||
| @@ -141,13 +133,8 @@ | |||||
| </div> | </div> | ||||
| <div class="five wide field"> | <div class="five wide field"> | ||||
| <div class="ui fluid search selection dropdown" id="select_model_checkpoint"> | <div class="ui fluid search selection dropdown" id="select_model_checkpoint"> | ||||
| {{if $.ckpt_name}} | |||||
| <input type="hidden" name="ckpt_name" value="{{$.ckpt_name}}" required> | |||||
| <div class="text">{{$.ckpt_name}}</div> | |||||
| {{else}} | |||||
| <input type="hidden" name="ckpt_name" required> | <input type="hidden" name="ckpt_name" required> | ||||
| <div class="text"></div> | <div class="text"></div> | ||||
| {{end}} | |||||
| <i class="dropdown icon"></i> | <i class="dropdown icon"></i> | ||||
| <div class="menu" id="model_checkpoint"> | <div class="menu" id="model_checkpoint"> | ||||
| </div> | </div> | ||||
| @@ -186,8 +173,21 @@ | |||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | ||||
| <select id="cloudbrain_gpu_type" class="ui search width48 dropdown gpu-type" placeholder="选择GPU类型" | <select id="cloudbrain_gpu_type" class="ui search width48 dropdown gpu-type" placeholder="选择GPU类型" | ||||
| style='width:385px' name="gpu_type"> | style='width:385px' name="gpu_type"> | ||||
| {{range .inference_gpu_types}} | |||||
| <option value="{{.Queue}}">{{.Value}}</option> | |||||
| {{if .gpu_type}} | |||||
| {{range .inference_gpu_types}} | |||||
| {{if eq $.gpu_type .Queue}} | |||||
| <option value="{{.Queue}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{range .inference_gpu_types}} | |||||
| {{if ne $.gpu_type .Queue}} | |||||
| <option value="{{.Queue}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{else}} | |||||
| {{range .inference_gpu_types}} | |||||
| <option value="{{.Queue}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -196,8 +196,8 @@ | |||||
| <span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | <span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | ||||
| <div class="inline min_title field required"> | <div class="inline min_title field required"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | ||||
| {{if .bootFile}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||||
| {{if .boot_file}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.boot_file}}" tabindex="3" autofocus required maxlength="255" > | |||||
| {{else}} | {{else}} | ||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | ||||
| {{end}} | {{end}} | ||||
| @@ -212,23 +212,8 @@ | |||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | ||||
| <span id="add_run_para" style="cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | <span id="add_run_para" style="cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | ||||
| <input id="store_run_para" type="hidden" name="run_para_list"> | <input id="store_run_para" type="hidden" name="run_para_list"> | ||||
| <div class="dynamic field" style="margin-top: 1rem;"> | |||||
| {{if ne 0 (len .params)}} | |||||
| {{range $k ,$v := .params}} | |||||
| <div class="two fields width85" id="para{{$k}}"> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_first-name" value={{$v.Label}} required> | |||||
| </div> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_last-name" value={{$v.Value}} required> | |||||
| </div> | |||||
| <span> | |||||
| <i class="trash icon"></i> | |||||
| </span> | |||||
| <div class="dynamic field" style="margin-top: 1rem;" data-params="{{.run_para_list}}"> | |||||
| </div> | |||||
| {{end}} | |||||
| {{end}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -244,9 +229,22 @@ | |||||
| <div class="required min_title inline field"> | <div class="required min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | ||||
| <select id="cloudbrain_resource_spec" class="ui search dropdown width80" placeholder="选择资源规格" name="resource_spec_id"> | <select id="cloudbrain_resource_spec" class="ui search dropdown width80" placeholder="选择资源规格" name="resource_spec_id"> | ||||
| {{range .inference_resource_specs}} | |||||
| <option name="resource_spec_id" value="{{.Id}}"> | |||||
| GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
| {{if .resource_spec_id}} | |||||
| {{range .inference_resource_specs}} | |||||
| {{if eq $.resource_spec_id .Id}} | |||||
| <option value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{range .inference_resource_specs}} | |||||
| {{if ne $.resource_spec_id .Id}} | |||||
| <option value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{else}} | |||||
| {{range .inference_resource_specs}} | |||||
| <option name="resource_spec_id" value="{{.Id}}"> | |||||
| GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -270,27 +268,35 @@ | |||||
| const RepoLink = {{.RepoLink}} | const RepoLink = {{.RepoLink}} | ||||
| let nameMap,nameList | let nameMap,nameList | ||||
| // 获取模型列表和模型名称对应的模型版本 | // 获取模型列表和模型名称对应的模型版本 | ||||
| $.get(`${RepoLink}/modelmanage/query_model_for_predict?type=0`, (data) => { | |||||
| $(document).ready(function(){ | |||||
| modelVersion() | modelVersion() | ||||
| modelCkpt() | modelCkpt() | ||||
| nameMap = data.nameMap | |||||
| nameList = data.nameList | |||||
| let html = '' | |||||
| nameList.forEach(element => { | |||||
| html += `<div class="item" data-value=${element}>${element}</div>` | |||||
| }); | |||||
| if(nameList.length!==0){ | |||||
| const initModelVersion = nameMap[nameList[0]][0] | |||||
| const initTrainTaskInfo = JSON.parse(initModelVersion.TrainTaskInfo) | |||||
| $('#model_name').append(html) | |||||
| $("#select_model").dropdown('set text',nameList[0]) | |||||
| $("#select_model").dropdown('set value',nameList[0],nameList[0]) | |||||
| } | |||||
| $('#select_model').removeClass("loading") | |||||
| $.get(`${RepoLink}/modelmanage/query_model_for_predict?type=0`, (data) => { | |||||
| nameMap = data.nameMap | |||||
| nameList = data.nameList | |||||
| let faildModelName = document.getElementById('failed_model_name').value | |||||
| let html = '' | |||||
| nameList.forEach(element => { | |||||
| html += `<div class="item" data-value=${element}>${element}</div>` | |||||
| }); | |||||
| if(nameList.length!==0){ | |||||
| $('#model_name').append(html) | |||||
| if(faildModelName){ | |||||
| $("#select_model").dropdown('set text',faildModelName) | |||||
| $("#select_model").dropdown('set value',faildModelName) | |||||
| }else{ | |||||
| $("#select_model").dropdown('set text',nameList[0]) | |||||
| $("#select_model").dropdown('set value',nameList[0],nameList[0]) | |||||
| } | |||||
| } | |||||
| $('#select_model').removeClass("loading") | |||||
| }) | |||||
| }) | }) | ||||
| // 根据选中的模型名称获取相应的模型版本 | // 根据选中的模型名称获取相应的模型版本 | ||||
| function modelVersion(){ | function modelVersion(){ | ||||
| let faildModelVersion = $('#failed_model_version').val() | |||||
| let faildTrainUrl = $('#failed_train_url').val() | |||||
| $('#select_model').dropdown({ | $('#select_model').dropdown({ | ||||
| onChange: function(value, text, $selectedItem) { | onChange: function(value, text, $selectedItem) { | ||||
| $("#select_model_version").addClass("loading") | $("#select_model_version").addClass("loading") | ||||
| @@ -305,13 +311,20 @@ | |||||
| $("#select_model_version").removeClass("loading") | $("#select_model_version").removeClass("loading") | ||||
| const initVersionText = $('#model_name_version div.item:first-child').text() | const initVersionText = $('#model_name_version div.item:first-child').text() | ||||
| const initVersionValue = $('#model_name_version div.item:first-child').data('value') | const initVersionValue = $('#model_name_version div.item:first-child').data('value') | ||||
| $("#select_model_version").dropdown('set text',initVersionText) | |||||
| $("#select_model_version").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child')) | |||||
| if(faildModelVersion&&faildTrainUrl){ | |||||
| $("#select_model_version").dropdown('set text',faildModelVersion) | |||||
| $("#select_model_version").dropdown('set value',faildTrainUrl,faildModelVersion,$('#model_name_version div.item:first-child')) | |||||
| }else{ | |||||
| $("#select_model_version").dropdown('set text',initVersionText) | |||||
| $("#select_model_version").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child')) | |||||
| } | |||||
| } | } | ||||
| }) | }) | ||||
| } | } | ||||
| // 根据选中的模型版本获取相应的模型权重文件 | // 根据选中的模型版本获取相应的模型权重文件 | ||||
| function modelCkpt(){ | function modelCkpt(){ | ||||
| let faildCkptName = $('#failed_ckpt_name').val() | |||||
| $('#select_model_version').dropdown({ | $('#select_model_version').dropdown({ | ||||
| onChange: function(value, text, $selectedItem) { | onChange: function(value, text, $selectedItem) { | ||||
| const dataID = $selectedItem[0].getAttribute("data-id") | const dataID = $selectedItem[0].getAttribute("data-id") | ||||
| @@ -326,17 +339,19 @@ | |||||
| if(!element.IsDir && loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length-1])){ | if(!element.IsDir && loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length-1])){ | ||||
| html += `<div class="item" data-value=${element.FileName}>${element.FileName}</div>` | html += `<div class="item" data-value=${element.FileName}>${element.FileName}</div>` | ||||
| } | } | ||||
| }) | }) | ||||
| $('#model_checkpoint').append(html) | $('#model_checkpoint').append(html) | ||||
| $("#select_model_checkpoint").removeClass("loading") | $("#select_model_checkpoint").removeClass("loading") | ||||
| const initVersionText = $('#model_checkpoint div.item:first-child').text() | const initVersionText = $('#model_checkpoint div.item:first-child').text() | ||||
| const initVersionValue = $('#model_checkpoint div.item:first-child').data('value') | const initVersionValue = $('#model_checkpoint div.item:first-child').data('value') | ||||
| $("#select_model_checkpoint").dropdown('set text',initVersionText) | |||||
| $("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child')) | |||||
| if(faildCkptName){ | |||||
| $("#select_model_checkpoint").dropdown('set text',faildCkptName) | |||||
| $("#select_model_checkpoint").dropdown('set value',faildCkptName,faildCkptName,$('#model_name_version div.item:first-child')) | |||||
| }else{ | |||||
| $("#select_model_checkpoint").dropdown('set text',initVersionText) | |||||
| $("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child')) | |||||
| } | |||||
| }) | }) | ||||
| $("input#ai_model_version").val(text) | $("input#ai_model_version").val(text) | ||||
| $("input#ai_model_label").val(label) | $("input#ai_model_label").val(label) | ||||
| } | } | ||||
| @@ -354,56 +369,64 @@ | |||||
| $(this).popup('show') | $(this).popup('show') | ||||
| }); | }); | ||||
| $(document).ready(function(){ | |||||
| let params = $('.dynamic.field').data('params') | |||||
| params&¶ms.parameter.forEach((item,index)=>{ | |||||
| Add_parameter(index,flag=true,item) | |||||
| }) | |||||
| }) | |||||
| // 参数增加、删除、修改、保存 | // 参数增加、删除、修改、保存 | ||||
| function Add_parameter(i){ | |||||
| value = '<div class="two fields width85" id= "para'+ i +'">' + | |||||
| '<div class="field">' + | |||||
| '<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
| '</div> ' + | |||||
| '<div class="field"> ' + | |||||
| '<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||||
| '</div>'+ | |||||
| '<span>' + | |||||
| '<i class="trash icon">' + | |||||
| '</i>' + | |||||
| '</span>' + | |||||
| '</div>' | |||||
| function Add_parameter(i,flag=false,paramsObject={}) { | |||||
| let value = '' | |||||
| value += `<div class="two fields width85" id= "para${i}">` | |||||
| value += '<div class="field">' | |||||
| if(flag){ | |||||
| value +=`<input type="text" class="shipping_first-name" value="${paramsObject.label}">` | |||||
| }else{ | |||||
| value +='<input type="text" class="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}>' | |||||
| } | |||||
| value += '</div>' | |||||
| value += '<div class="field">' | |||||
| if(flag){ | |||||
| value +=`<input type="text" class="shipping_last-name" value="${paramsObject.value}">` | |||||
| }else{ | |||||
| value +='<input type="text" class="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' | |||||
| } | |||||
| value += '</div>' | |||||
| value += '<span><i class="trash icon"></i></span>' | |||||
| value += '</div>' | |||||
| $(".dynamic.field").append(value) | $(".dynamic.field").append(value) | ||||
| } | } | ||||
| $('#add_run_para').click(function(){ | |||||
| $('#add_run_para').click(function () { | |||||
| var len = $(".dynamic.field .two.fields").length | var len = $(".dynamic.field .two.fields").length | ||||
| Add_parameter(len) | Add_parameter(len) | ||||
| }); | }); | ||||
| $(".dynamic.field").on("click",".trash.icon", function() { | |||||
| $(".dynamic.field").on("click", ".trash.icon", function () { | |||||
| var index = $(this).parent().parent().index() | var index = $(this).parent().parent().index() | ||||
| $(this).parent().parent().remove() | $(this).parent().parent().remove() | ||||
| var len = $(".dynamic.field .two.fields").length | var len = $(".dynamic.field .two.fields").length | ||||
| $(".dynamic.field .two.fields").each(function(){ | |||||
| $(".dynamic.field .two.fields").each(function () { | |||||
| var cur_index = $(this).index() | var cur_index = $(this).index() | ||||
| $(this).attr('id', 'para' + cur_index) | $(this).attr('id', 'para' + cur_index) | ||||
| }) | }) | ||||
| }); | }); | ||||
| function send_run_para(){ | |||||
| function send_run_para() { | |||||
| var run_parameters = [] | var run_parameters = [] | ||||
| var msg = {} | var msg = {} | ||||
| $(".dynamic.field .two.fields").each(function(){ | |||||
| var para_name = $(this).find('input[name=shipping_first-name]').val() | |||||
| var para_value = $(this).find('input[name=shipping_last-name]').val() | |||||
| run_parameters.push({"label": para_name, "value": para_value}) | |||||
| $(".dynamic.field .two.fields").each(function () { | |||||
| var para_name = $(this).find('input.shipping_first-name').val() | |||||
| var para_value = $(this).find('input.shipping_last-name').val() | |||||
| run_parameters.push({ "label": para_name, "value": para_value }) | |||||
| }) | }) | ||||
| msg["parameter"] = run_parameters | msg["parameter"] = run_parameters | ||||
| msg = JSON.stringify(msg) | msg = JSON.stringify(msg) | ||||
| $('#store_run_para').val(msg) | $('#store_run_para').val(msg) | ||||
| } | } | ||||
| function get_name(){ | |||||
| let name1=$("#engine_name .text").text() | |||||
| let name2=$("#flaver_name .text").text() | |||||
| $("input#ai_engine_name").val(name1) | |||||
| $("input#ai_flaver_name").val(name2) | |||||
| } | |||||
| function validate(){ | function validate(){ | ||||
| $('.ui.form') | $('.ui.form') | ||||
| .form({ | .form({ | ||||
| @@ -421,7 +444,7 @@ | |||||
| identifier : 'display_job_name', | identifier : 'display_job_name', | ||||
| rules: [ | rules: [ | ||||
| { | { | ||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[^-]$/]', | |||||
| type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | |||||
| } | } | ||||
| ] | ] | ||||
| }, | }, | ||||
| @@ -472,9 +495,9 @@ | |||||
| document.getElementById("mask").style.display = "none" | document.getElementById("mask").style.display = "none" | ||||
| } | } | ||||
| } | } | ||||
| validate(); | |||||
| $('.ui.create_train_job.green.button').click(function(e) { | $('.ui.create_train_job.green.button').click(function(e) { | ||||
| send_run_para() | |||||
| get_name() | |||||
| validate() | |||||
| send_run_para(); | |||||
| validate(); | |||||
| }) | }) | ||||
| </script> | </script> | ||||
| @@ -381,7 +381,15 @@ | |||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | ||||
| {{.Image}} | |||||
| <span class="ui poping up clipboard" data-position="top center" id="clipboard-btn" style="cursor:pointer" | |||||
| data-clipboard-text="{{.Image}}" | |||||
| data-success="{{$.i18n.Tr "repo.copy_link_success"}}" | |||||
| data-error="{{$.i18n.Tr "repo.copy_link_error"}}" | |||||
| data-content="{{$.i18n.Tr "repo.copy_link"}}" | |||||
| data-variation="inverted tiny" | |||||
| > | |||||
| <span title="{{.Image}}">{{.Image}}</span> | |||||
| </span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -294,6 +294,27 @@ | |||||
| context.value = '' | context.value = '' | ||||
| $(".icon.icons").css("visibility", "hidden") | $(".icon.icons").css("visibility", "hidden") | ||||
| } | } | ||||
| function validate(){ | |||||
| $('.ui.form').form({ | |||||
| on: 'blur', | |||||
| fields: { | |||||
| display_job_name:{ | |||||
| identifier : 'display_job_name', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| }, | |||||
| onSuccess: function(){ | |||||
| }, | |||||
| onFailure: function(e){ | |||||
| return false; | |||||
| } | |||||
| }) | |||||
| } | |||||
| validate(); | |||||
| form.onsubmit = function (e) { | form.onsubmit = function (e) { | ||||
| let value_task = $("input[name='display_job_name']").val() | let value_task = $("input[name='display_job_name']").val() | ||||
| let value_image = $("input[name='image']").val() | let value_image = $("input[name='image']").val() | ||||
| @@ -252,7 +252,9 @@ | |||||
| </span> | </span> | ||||
| <span class="cti-mgRight-sm uc-accordionTitle-black" | <span class="cti-mgRight-sm uc-accordionTitle-black" | ||||
| id="{{.VersionName}}-duration-span">{{$.duration}}</span> | id="{{.VersionName}}-duration-span">{{$.duration}}</span> | ||||
| <span id="refresh-status" data-tooltip="刷新" style="cursor: pointer;" data-inverted="" data-version="{{.VersionName}}"> | |||||
| <i class="redo icon redo-color"></i> | |||||
| </span> | |||||
| </div> | </div> | ||||
| </span> | </span> | ||||
| </span> | </span> | ||||
| @@ -390,7 +392,15 @@ | |||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | ||||
| {{.Image}} | |||||
| <span class="ui poping up clipboard" data-position="top center" id="clipboard-btn" style="cursor:pointer" | |||||
| data-clipboard-text="{{.Image}}" | |||||
| data-success="{{$.i18n.Tr "repo.copy_link_success"}}" | |||||
| data-error="{{$.i18n.Tr "repo.copy_link_error"}}" | |||||
| data-content="{{$.i18n.Tr "repo.copy_link"}}" | |||||
| data-variation="inverted tiny" | |||||
| > | |||||
| <span title="{{.Image}}">{{.Image}}</span> | |||||
| </span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -89,8 +89,7 @@ | |||||
| <form class="ui form" action="{{.Link}}" method="post"> | <form class="ui form" action="{{.Link}}" method="post"> | ||||
| {{.CsrfTokenHtml}} | {{.CsrfTokenHtml}} | ||||
| <input type="hidden" name="action" value="update"> | <input type="hidden" name="action" value="update"> | ||||
| <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||||
| <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | |||||
| <input type="hidden" id="ai_image_name" value="{{.image}}"> | |||||
| <h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | <h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | ||||
| <div class="required unite min_title inline field"> | <div class="required unite min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label> | ||||
| @@ -133,18 +132,18 @@ | |||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" | <input style="width: 60%;" name="display_job_name" id="display_job_name" | ||||
| placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" | placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" | ||||
| tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required | tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required | ||||
| maxlength="64"> | |||||
| <span class="tooltips" style="display: block;margin-left: 11.5rem;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
| maxlength="36"> | |||||
| <span class="tooltips" style="display: block;margin-left: 11.5rem;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span> | |||||
| </div> | </div> | ||||
| <div class="inline min_title field"> | <div class="inline min_title field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;" | <label class="label-fix-width" style="font-weight: normal;" | ||||
| for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | ||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" | |||||
| placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} | |||||
| onchange="this.value=this.value.substring(0, 255)" | |||||
| onkeydown="this.value=this.value.substring(0, 255)" | |||||
| onkeyup="this.value=this.value.substring(0, 255)"></textarea> | |||||
| {{if .description}} | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea> | |||||
| {{else}} | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | |||||
| {{end}} | |||||
| </div> | </div> | ||||
| <div class="ui divider"></div> | <div class="ui divider"></div> | ||||
| @@ -179,13 +178,25 @@ | |||||
| <option name="job_type" value="TRAIN">TRAIN</option> | <option name="job_type" value="TRAIN">TRAIN</option> | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| <div class="required min_title inline field"> | <div class="required min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | ||||
| <select id="cloudbrain_gpu_type" class="ui search width806 dropdown gpu-type" placeholder="选择GPU类型" | <select id="cloudbrain_gpu_type" class="ui search width806 dropdown gpu-type" placeholder="选择GPU类型" | ||||
| style='width:385px' name="gpu_type"> | style='width:385px' name="gpu_type"> | ||||
| {{range .train_gpu_types}} | |||||
| <option value="{{.Queue}}">{{.Value}}</option> | |||||
| {{if .gpu_type}} | |||||
| {{range .train_gpu_types}} | |||||
| {{if eq $.gpu_type .Queue}} | |||||
| <option value="{{.Queue}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{range .train_gpu_types}} | |||||
| {{if ne $.gpu_type .Queue}} | |||||
| <option value="{{.Queue}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{else}} | |||||
| {{range .train_gpu_types}} | |||||
| <option value="{{.Queue}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -195,8 +206,8 @@ | |||||
| <div class="inline field min_title required"> | <div class="inline field min_title required"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | ||||
| {{if .bootFile}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" | |||||
| {{if .boot_file}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.boot_file}}" | |||||
| tabindex="3" autofocus required maxlength="255"> | tabindex="3" autofocus required maxlength="255"> | ||||
| {{else}} | {{else}} | ||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" | <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" | ||||
| @@ -220,35 +231,30 @@ | |||||
| style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i | style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i | ||||
| class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | ||||
| <input id="store_run_para" type="hidden" name="run_para_list"> | <input id="store_run_para" type="hidden" name="run_para_list"> | ||||
| <div class="dynamic field" style="margin-top: 1rem;"> | |||||
| {{if .params}} | |||||
| {{if ne 0 (len .params)}} | |||||
| {{range $k ,$v := .params}} | |||||
| <div class="two fields width85" id="para{{$k}}"> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_first-name" value={{$v.Label}} required> | |||||
| </div> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_last-name" value={{$v.Value}} required> | |||||
| </div> | |||||
| <span> | |||||
| <i class="trash icon"></i> | |||||
| </span> | |||||
| </div> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{end}} | |||||
| <div class="dynamic field" style="margin-top: 1rem;" data-params="{{.run_para_list}}"> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="required min_title inline field"> | <div class="required min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | ||||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格" | <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格" | ||||
| style='width:385px' name="resource_spec_id"> | style='width:385px' name="resource_spec_id"> | ||||
| {{range .train_resource_specs}} | |||||
| <option name="resource_spec_id" value="{{.Id}}"> | |||||
| GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
| {{if .resource_spec_id}} | |||||
| {{range .train_resource_specs}} | |||||
| {{if eq $.resource_spec_id .Id}} | |||||
| <option value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{range .train_resource_specs}} | |||||
| {{if ne $.resource_spec_id .Id}} | |||||
| <option value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{else}} | |||||
| {{range .train_resource_specs}} | |||||
| <option name="resource_spec_id" value="{{.Id}}"> | |||||
| GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -281,34 +287,35 @@ | |||||
| case 13:return false; | case 13:return false; | ||||
| } | } | ||||
| }); | }); | ||||
| let sever_num = $('#trainjob_work_server_num') | |||||
| $('.add').click(function () { | |||||
| sever_num.val(parseInt(sever_num.val()) + 1) | |||||
| if (sever_num.val() >= 26) { | |||||
| sever_num.val(parseInt(sever_num.val()) - 1) | |||||
| } | |||||
| }) | |||||
| $('.min').click(function () { | |||||
| sever_num.val(parseInt(sever_num.val()) - 1) | |||||
| if (sever_num.val() <= 0) { | |||||
| sever_num.val(parseInt(sever_num.val()) + 1) | |||||
| } | |||||
| $(document).ready(function(){ | |||||
| let params = $('.dynamic.field').data('params') | |||||
| params&¶ms.parameter.forEach((item,index)=>{ | |||||
| Add_parameter(index,flag=true,item) | |||||
| }) | |||||
| }) | }) | ||||
| // 参数增加、删除、修改、保存 | // 参数增加、删除、修改、保存 | ||||
| function Add_parameter(i) { | |||||
| value = '<div class="two fields width85" id= "para' + i + '">' + | |||||
| '<div class="field">' + | |||||
| '<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
| '</div> ' + | |||||
| '<div class="field"> ' + | |||||
| '<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||||
| '</div>' + | |||||
| '<span>' + | |||||
| '<i class="trash icon">' + | |||||
| '</i>' + | |||||
| '</span>' + | |||||
| '</div>' | |||||
| function Add_parameter(i,flag=false,paramsObject={}) { | |||||
| let value = '' | |||||
| value += `<div class="two fields width85" id= "para${i}">` | |||||
| value += '<div class="field">' | |||||
| if(flag){ | |||||
| value +=`<input type="text" class="shipping_first-name" value="${paramsObject.label}">` | |||||
| }else{ | |||||
| value +='<input type="text" class="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}>' | |||||
| } | |||||
| value += '</div>' | |||||
| value += '<div class="field">' | |||||
| if(flag){ | |||||
| value +=`<input type="text" class="shipping_last-name" value="${paramsObject.value}">` | |||||
| }else{ | |||||
| value +='<input type="text" class="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' | |||||
| } | |||||
| value += '</div>' | |||||
| value += '<span><i class="trash icon"></i></span>' | |||||
| value += '</div>' | |||||
| $(".dynamic.field").append(value) | $(".dynamic.field").append(value) | ||||
| } | } | ||||
| $('#add_run_para').click(function () { | $('#add_run_para').click(function () { | ||||
| @@ -326,80 +333,13 @@ | |||||
| }) | }) | ||||
| }); | }); | ||||
| $('.ui.parameter.green.button').click(function () { | |||||
| var parameters = []; | |||||
| $('table tr').each(function () { | |||||
| $(this).find('td:eq(1)').each(function () { | |||||
| parameters.push($(this).text()); | |||||
| }) | |||||
| $(this).find('input').each(function () { | |||||
| parameters.push($(this).text()) | |||||
| }) | |||||
| }); | |||||
| $('.ui.parameter.modal') | |||||
| .modal('hide'); | |||||
| for (var i = 2; i < parameters.length; i++) { | |||||
| switch (i) { | |||||
| // 数据集uuid待完成 | |||||
| // case (2): | |||||
| // console.log(1) | |||||
| // break; | |||||
| // $("#trainjob_datasets").val(parameters[i]); | |||||
| // console.log($("#trainjob_datasets").val()) | |||||
| case (3): | |||||
| $("input[name='boot_file']").val(parameters[i]); | |||||
| break; | |||||
| case (4): | |||||
| var para = parameters[i].split(" ") | |||||
| for (var j = 0; j < para.length; j++) { | |||||
| var para_name = para[j].split('=')[0] | |||||
| var para_value = para[j].split('=')[1] | |||||
| var len = $(".dynamic.field .two.fields").length | |||||
| Add_parameter(len) | |||||
| var pid = 'para' + len | |||||
| $(".dynamic.field" + " #" + pid + "").find("input[name=shipping_first-name]").val(para_name) | |||||
| $(".dynamic.field" + " #" + pid + "").find("input[name=shipping_last-name]").val(para_value) | |||||
| } | |||||
| break; | |||||
| // 数据集pool_id待完成 | |||||
| // case (5): | |||||
| // $("select[name='pool_id']").val(parameters[i]); | |||||
| // break; | |||||
| case (6): | |||||
| $("input[name='work_server_number']").val(parameters[i]); | |||||
| break; | |||||
| } | |||||
| } | |||||
| }) | |||||
| $('.ui.save.checkbox').click(function () { | |||||
| $(this).checkbox({ | |||||
| onChange: function () { | |||||
| if ($('.ui.save.checkbox').checkbox('is checked')) { | |||||
| $('#save_para').removeClass("disabled") | |||||
| } else { | |||||
| $('#save_para').addClass("disabled") | |||||
| } | |||||
| } | |||||
| }); | |||||
| }) | |||||
| $('.question.circle.icon').hover(function () { | $('.question.circle.icon').hover(function () { | ||||
| $(this).popup('show') | $(this).popup('show') | ||||
| }); | }); | ||||
| $(".item.active.parameter_config").click(function () { | |||||
| $('.ui.parameter.modal') | |||||
| .modal('setting', 'closable', false) | |||||
| .modal('show'); | |||||
| }) | |||||
| $('.ui.deny.button').click(function () { | |||||
| $('.ui.parameter.modal') | |||||
| .modal('hide'); | |||||
| }) | |||||
| $('select.dropdown') | $('select.dropdown') | ||||
| .dropdown(); | .dropdown(); | ||||
| @@ -420,7 +360,7 @@ | |||||
| identifier: 'display_job_name', | identifier: 'display_job_name', | ||||
| rules: [ | rules: [ | ||||
| { | { | ||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
| type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | |||||
| } | } | ||||
| ] | ] | ||||
| }, | }, | ||||
| @@ -468,24 +408,17 @@ | |||||
| var run_parameters = [] | var run_parameters = [] | ||||
| var msg = {} | var msg = {} | ||||
| $(".dynamic.field .two.fields").each(function () { | $(".dynamic.field .two.fields").each(function () { | ||||
| var para_name = $(this).find('input[name=shipping_first-name]').val() | |||||
| var para_value = $(this).find('input[name=shipping_last-name]').val() | |||||
| var para_name = $(this).find('input.shipping_first-name').val() | |||||
| var para_value = $(this).find('input.shipping_last-name').val() | |||||
| run_parameters.push({ "label": para_name, "value": para_value }) | run_parameters.push({ "label": para_name, "value": para_value }) | ||||
| }) | }) | ||||
| msg["parameter"] = run_parameters | msg["parameter"] = run_parameters | ||||
| msg = JSON.stringify(msg) | msg = JSON.stringify(msg) | ||||
| $('#store_run_para').val(msg) | $('#store_run_para').val(msg) | ||||
| } | } | ||||
| function get_name() { | |||||
| let name1 = $("#engine_name .text").text() | |||||
| let name2 = $("#flaver_name .text").text() | |||||
| $("input#ai_engine_name").val(name1) | |||||
| $("input#ai_flaver_name").val(name2) | |||||
| } | |||||
| validate(); | |||||
| $('.ui.create_train_job.green.button').click(function (e) { | $('.ui.create_train_job.green.button').click(function (e) { | ||||
| get_name() | |||||
| send_run_para() | |||||
| validate() | |||||
| send_run_para(); | |||||
| validate(); | |||||
| }) | }) | ||||
| </script> | </script> | ||||
| @@ -384,7 +384,15 @@ | |||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | ||||
| {{.Image}} | |||||
| <span class="ui poping up clipboard" data-position="top center" id="clipboard-btn" style="cursor:pointer" | |||||
| data-clipboard-text="{{.Image}}" | |||||
| data-success="{{$.i18n.Tr "repo.copy_link_success"}}" | |||||
| data-error="{{$.i18n.Tr "repo.copy_link_error"}}" | |||||
| data-content="{{$.i18n.Tr "repo.copy_link"}}" | |||||
| data-variation="inverted tiny" | |||||
| > | |||||
| <span title="{{.Image}}">{{.Image}}</span> | |||||
| </span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -176,7 +176,7 @@ | |||||
| <button class="ui green button" id="submit_reponame"> | <button class="ui green button" id="submit_reponame"> | ||||
| {{.i18n.Tr "repo.create_repo"}} | {{.i18n.Tr "repo.create_repo"}} | ||||
| </button> | </button> | ||||
| <a class="ui button" href="{{AppSubUrl}}/">{{.i18n.Tr "cancel"}}</a> | |||||
| <a class="ui button" href="javascript:history.go(-1)">{{.i18n.Tr "cancel"}}</a> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </form> | </form> | ||||
| @@ -386,7 +386,7 @@ | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a id="ai-stop-{{.Cloudbrain.ID}}" | <a id="ai-stop-{{.Cloudbrain.ID}}" | ||||
| class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED" "CREATE_FAILED"}}disabled {{else}}blue {{end}}button' | |||||
| class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED" "CREATE_FAILED" "DELETED"}}disabled {{else}}blue {{end}}button' | |||||
| data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/stop" | data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/stop" | ||||
| data-jobid="{{.Cloudbrain.ID}}"> | data-jobid="{{.Cloudbrain.ID}}"> | ||||
| {{$.i18n.Tr "repo.stop"}} | {{$.i18n.Tr "repo.stop"}} | ||||
| @@ -405,7 +405,7 @@ | |||||
| {{$.CsrfTokenHtml}} | {{$.CsrfTokenHtml}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a id="ai-delete-{{.Cloudbrain.ID}}" | <a id="ai-delete-{{.Cloudbrain.ID}}" | ||||
| class='ui basic ai_delete {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "SUCCEEDED" "CREATE_FAILED"}}blue {{else}}disabled {{end}}button' | |||||
| class='ui basic ai_delete {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "SUCCEEDED" "CREATE_FAILED" "DELETED"}}blue {{else}}disabled {{end}}button' | |||||
| style="border-radius: .28571429rem;"> | style="border-radius: .28571429rem;"> | ||||
| {{$.i18n.Tr "repo.delete"}} | {{$.i18n.Tr "repo.delete"}} | ||||
| </a> | </a> | ||||
| @@ -427,6 +427,7 @@ | |||||
| {{if .CanDebug}} | {{if .CanDebug}} | ||||
| <a id="model-image-{{.Cloudbrain.ID}}" | <a id="model-image-{{.Cloudbrain.ID}}" | ||||
| class='imageBtn ui basic {{if ne .Status "RUNNING"}}disabled {{else}}blue {{end}}button' | class='imageBtn ui basic {{if ne .Status "RUNNING"}}disabled {{else}}blue {{end}}button' | ||||
| target="_blank" | |||||
| href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/commit_image">{{$.i18n.Tr "repo.submit_image"}}</a> | href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/commit_image">{{$.i18n.Tr "repo.submit_image"}}</a> | ||||
| {{else}} | {{else}} | ||||
| <a | <a | ||||
| @@ -80,8 +80,11 @@ | |||||
| <form class="ui form" action="{{.Link}}" method="post"> | <form class="ui form" action="{{.Link}}" method="post"> | ||||
| {{.CsrfTokenHtml}} | {{.CsrfTokenHtml}} | ||||
| <input type="hidden" name="action" value="update"> | <input type="hidden" name="action" value="update"> | ||||
| <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||||
| <input type="hidden" id="ai_engine_name" name="engine_name" value=""> | |||||
| <input type="hidden" id="ai_flavor_name" name="flavor_name" value=""> | <input type="hidden" id="ai_flavor_name" name="flavor_name" value=""> | ||||
| <input type="hidden" id="ai_image_name" value="{{.image}}"> | |||||
| <input type="hidden" id="fail_dataset_name" value="{{$.dataset_name}}"> | |||||
| <input type="hidden" id="fail_dataset_uuid" value="{{$.attachment}}"> | |||||
| <h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | <h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | ||||
| <div class="required min_title inline field"> | <div class="required min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label> | ||||
| @@ -117,13 +120,17 @@ | |||||
| </div> | </div> | ||||
| <div class="required min_title inline field"> | <div class="required min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | |||||
| <span class="tooltips" style="margin-left: 11.5rem;display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="36"> | |||||
| <span class="tooltips" style="margin-left: 11.5rem;display: block;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span> | |||||
| </div> | </div> | ||||
| <div class="min_title inline field"> | <div class="min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | <label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | ||||
| {{if .description}} | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea> | |||||
| {{else}} | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | ||||
| {{end}} | |||||
| </div> | </div> | ||||
| <div class="ui divider"></div> | <div class="ui divider"></div> | ||||
| @@ -156,8 +163,8 @@ | |||||
| <div class="inline min_title field required"> | <div class="inline min_title field required"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | ||||
| {{if .bootFile}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||||
| {{if .boot_file}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.boot_file}}" tabindex="3" autofocus required maxlength="255" > | |||||
| {{else}} | {{else}} | ||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | ||||
| {{end}} | {{end}} | ||||
| @@ -174,33 +181,29 @@ | |||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | ||||
| <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | ||||
| <input id="store_run_para" type="hidden" name="run_para_list"> | <input id="store_run_para" type="hidden" name="run_para_list"> | ||||
| <div class="dynamic field" style="margin-top: 1rem;"> | |||||
| {{if .params}} | |||||
| {{if ne 0 (len .params)}} | |||||
| {{range $k ,$v := .params}} | |||||
| <div class="two fields width85" id="para{{$k}}"> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_first-name" value={{$v.Label}} required> | |||||
| </div> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_last-name" value={{$v.Value}} required> | |||||
| </div> | |||||
| <span> | |||||
| <i class="trash icon"></i> | |||||
| </span> | |||||
| </div> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{end}} | |||||
| <div class="dynamic field" style="margin-top: 1rem;" data-params="{{.run_para_list}}"> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="required min_title inline field" id="flavor_name"> | <div class="required min_title inline field" id="flavor_name"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | ||||
| <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | ||||
| {{range .flavor_infos}} | |||||
| {{if .flavor}} | |||||
| {{range .flavor_infos}} | |||||
| {{if eq $.flavor .ID}} | |||||
| <option value="{{.ID}}">{{.Name}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{range .flavor_infos}} | |||||
| {{if ne $.flavor .ID}} | |||||
| <option value="{{.ID}}">{{.Name}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{else}} | |||||
| {{range .flavor_infos}} | |||||
| <option name="flavor" value="{{.ID}}">{{.Name}}</option> | <option name="flavor" value="{{.ID}}">{{.Name}}</option> | ||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -230,125 +233,58 @@ | |||||
| $('.menu .item') | $('.menu .item') | ||||
| .tab(); | .tab(); | ||||
| let sever_num = $('#trainjob_work_server_num') | |||||
| $('.add').click(function(){ | |||||
| sever_num.val(parseInt(sever_num.val())+1) | |||||
| if(sever_num.val()>=26){ | |||||
| sever_num.val(parseInt(sever_num.val())-1) | |||||
| } | |||||
| }) | |||||
| $('.min').click(function(){ | |||||
| sever_num.val(parseInt(sever_num.val())-1) | |||||
| if(sever_num.val()<=0){ | |||||
| sever_num.val(parseInt(sever_num.val())+1) | |||||
| } | |||||
| $(document).ready(function(){ | |||||
| let params = $('.dynamic.field').data('params') | |||||
| params&¶ms.parameter.forEach((item,index)=>{ | |||||
| Add_parameter(index,flag=true,item) | |||||
| }) | |||||
| }) | }) | ||||
| // 参数增加、删除、修改、保存 | // 参数增加、删除、修改、保存 | ||||
| function Add_parameter(i){ | |||||
| value = '<div class="two fields width85" id= "para'+ i +'">' + | |||||
| '<div class="field">' + | |||||
| '<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
| '</div> ' + | |||||
| '<div class="field"> ' + | |||||
| '<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||||
| '</div>'+ | |||||
| '<span>' + | |||||
| '<i class="trash icon">' + | |||||
| '</i>' + | |||||
| '</span>' + | |||||
| '</div>' | |||||
| function Add_parameter(i,flag=false,paramsObject={}) { | |||||
| let value = '' | |||||
| value += `<div class="two fields width85" id= "para${i}">` | |||||
| value += '<div class="field">' | |||||
| if(flag){ | |||||
| value +=`<input type="text" class="shipping_first-name" value="${paramsObject.label}">` | |||||
| }else{ | |||||
| value +='<input type="text" class="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}>' | |||||
| } | |||||
| value += '</div>' | |||||
| value += '<div class="field">' | |||||
| if(flag){ | |||||
| value +=`<input type="text" class="shipping_last-name" value="${paramsObject.value}">` | |||||
| }else{ | |||||
| value +='<input type="text" class="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' | |||||
| } | |||||
| value += '</div>' | |||||
| value += '<span><i class="trash icon"></i></span>' | |||||
| value += '</div>' | |||||
| $(".dynamic.field").append(value) | $(".dynamic.field").append(value) | ||||
| } | |||||
| $('#add_run_para').click(function(){ | |||||
| } | |||||
| $('#add_run_para').click(function () { | |||||
| var len = $(".dynamic.field .two.fields").length | var len = $(".dynamic.field .two.fields").length | ||||
| Add_parameter(len) | Add_parameter(len) | ||||
| }); | }); | ||||
| $(".dynamic.field").on("click",".trash.icon", function() { | |||||
| $(".dynamic.field").on("click", ".trash.icon", function () { | |||||
| var index = $(this).parent().parent().index() | var index = $(this).parent().parent().index() | ||||
| $(this).parent().parent().remove() | $(this).parent().parent().remove() | ||||
| var len = $(".dynamic.field .two.fields").length | var len = $(".dynamic.field .two.fields").length | ||||
| $(".dynamic.field .two.fields").each(function(){ | |||||
| $(".dynamic.field .two.fields").each(function () { | |||||
| var cur_index = $(this).index() | var cur_index = $(this).index() | ||||
| $(this).attr('id', 'para' + cur_index) | $(this).attr('id', 'para' + cur_index) | ||||
| }) | }) | ||||
| }); | }); | ||||
| $('.ui.parameter.green.button').click(function(){ | |||||
| var parameters = []; | |||||
| $('table tr').each(function() { | |||||
| $(this).find('td:eq(1)').each(function(){ | |||||
| parameters.push($(this).text()); | |||||
| }) | |||||
| $(this).find('input').each(function(){ | |||||
| parameters.push($(this).text()) | |||||
| }) | |||||
| }); | |||||
| $('.ui.parameter.modal') | |||||
| .modal('hide'); | |||||
| for(var i = 2; i < parameters.length; i++){ | |||||
| switch(i) { | |||||
| // 数据集uuid待完成 | |||||
| // case (2): | |||||
| // console.log(1) | |||||
| // break; | |||||
| // $("#trainjob_datasets").val(parameters[i]); | |||||
| // console.log($("#trainjob_datasets").val()) | |||||
| case (3): | |||||
| $("input[name='boot_file']").val(parameters[i]); | |||||
| break; | |||||
| case (4): | |||||
| var para = parameters[i].split(" ") | |||||
| for(var j = 0; j < para.length; j++){ | |||||
| var para_name = para[j].split('=')[0] | |||||
| var para_value = para[j].split('=')[1] | |||||
| var len = $(".dynamic.field .two.fields").length | |||||
| Add_parameter(len) | |||||
| var pid = 'para' + len | |||||
| $(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_first-name]").val(para_name) | |||||
| $(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_last-name]").val(para_value) | |||||
| } | |||||
| break; | |||||
| // 数据集pool_id待完成 | |||||
| // case (5): | |||||
| // $("select[name='pool_id']").val(parameters[i]); | |||||
| // break; | |||||
| case (6): | |||||
| $("input[name='work_server_number']").val(parameters[i]); | |||||
| break; | |||||
| } | |||||
| } | |||||
| }) | |||||
| $('.ui.save.checkbox').click(function(){ | |||||
| $(this).checkbox({ | |||||
| onChange: function(){ | |||||
| if ($('.ui.save.checkbox').checkbox('is checked')){ | |||||
| $('#save_para').removeClass("disabled") | |||||
| }else{ | |||||
| $('#save_para').addClass("disabled") | |||||
| } | |||||
| } | |||||
| }); | |||||
| }) | |||||
| $('.question.circle.icon').hover(function(){ | $('.question.circle.icon').hover(function(){ | ||||
| $(this).popup('show') | $(this).popup('show') | ||||
| }); | }); | ||||
| $(".item.active.parameter_config").click(function(){ | |||||
| $('.ui.parameter.modal') | |||||
| .modal('setting', 'closable', false) | |||||
| .modal('show'); | |||||
| }) | |||||
| $('.ui.deny.button').click(function(){ | |||||
| $('.ui.parameter.modal') | |||||
| .modal('hide'); | |||||
| }) | |||||
| $('select.dropdown') | $('select.dropdown') | ||||
| .dropdown(); | .dropdown(); | ||||
| @@ -369,7 +305,7 @@ | |||||
| identifier : 'display_job_name', | identifier : 'display_job_name', | ||||
| rules: [ | rules: [ | ||||
| { | { | ||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
| type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | |||||
| } | } | ||||
| ] | ] | ||||
| }, | }, | ||||
| @@ -414,13 +350,13 @@ | |||||
| document.getElementById("mask").style.display = "none" | document.getElementById("mask").style.display = "none" | ||||
| } | } | ||||
| } | } | ||||
| function send_run_para(){ | |||||
| function send_run_para() { | |||||
| var run_parameters = [] | var run_parameters = [] | ||||
| var msg = {} | var msg = {} | ||||
| $(".dynamic.field .two.fields").each(function(){ | |||||
| var para_name = $(this).find('input[name=shipping_first-name]').val() | |||||
| var para_value = $(this).find('input[name=shipping_last-name]').val() | |||||
| run_parameters.push({"label": para_name, "value": para_value}) | |||||
| $(".dynamic.field .two.fields").each(function () { | |||||
| var para_name = $(this).find('input.shipping_first-name').val() | |||||
| var para_value = $(this).find('input.shipping_last-name').val() | |||||
| run_parameters.push({ "label": para_name, "value": para_value }) | |||||
| }) | }) | ||||
| msg["parameter"] = run_parameters | msg["parameter"] = run_parameters | ||||
| msg = JSON.stringify(msg) | msg = JSON.stringify(msg) | ||||
| @@ -433,9 +369,10 @@ | |||||
| $("input#ai_flavor_name").val(name2) | $("input#ai_flavor_name").val(name2) | ||||
| } | } | ||||
| validate(); | |||||
| $('.ui.create_train_job.green.button').click(function(e) { | $('.ui.create_train_job.green.button').click(function(e) { | ||||
| get_name() | get_name() | ||||
| send_run_para() | send_run_para() | ||||
| validate() | |||||
| validate(); | |||||
| }) | }) | ||||
| </script> | </script> | ||||
| @@ -77,6 +77,8 @@ | |||||
| <input type="hidden" name="action" value="update"> | <input type="hidden" name="action" value="update"> | ||||
| <input type="hidden" id="ai_engine_name" name="engine_name" value=""> | <input type="hidden" id="ai_engine_name" name="engine_name" value=""> | ||||
| <input type="hidden" id="ai_flavor_name" name="flavor_name" value=""> | <input type="hidden" id="ai_flavor_name" name="flavor_name" value=""> | ||||
| <input type="hidden" id="fail_dataset_name" value="{{$.dataset_name}}"> | |||||
| <input type="hidden" id="fail_dataset_uuid" value="{{$.attachment}}"> | |||||
| <h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | <h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | ||||
| <div class="required min_title inline field"> | <div class="required min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label> | ||||
| @@ -113,13 +115,17 @@ | |||||
| <div class="required min_title inline field"> | <div class="required min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | |||||
| <span class="tooltips" style="display: block;margin-left: 11.5rem;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="36"> | |||||
| <span class="tooltips" style="display: block;margin-left: 11.5rem;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span> | |||||
| </div> | </div> | ||||
| <div class="min_title inline field"> | <div class="min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | <label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | ||||
| {{if .description}} | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea> | |||||
| {{else}} | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | ||||
| {{end}} | |||||
| </div> | </div> | ||||
| <div class="ui divider"></div> | <div class="ui divider"></div> | ||||
| @@ -146,20 +152,32 @@ | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| <div class="required min_title inline field" id="engine_name"> | <div class="required min_title inline field" id="engine_name"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}}</label> | ||||
| <select class="ui dropdown width81" id="trainjob_images" name="image_id"> | <select class="ui dropdown width81" id="trainjob_images" name="image_id"> | ||||
| {{range .images}} | |||||
| <option name="image_id" value="{{.ID}}">{{.Name}}</option> | |||||
| {{if .image_id}} | |||||
| {{range .images}} | |||||
| {{if eq $.image_id .ID}} | |||||
| <option value="{{.ID}}">{{.Name}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{range .images}} | |||||
| {{if ne $.image_id .ID}} | |||||
| <option value="{{.ID}}">{{.Name}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{else}} | |||||
| {{range .images}} | |||||
| <option name="image_id" value="{{.ID}}">{{.Name}}</option> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| <div class="inline min_title field required"> | <div class="inline min_title field required"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | ||||
| {{if .bootFile}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||||
| {{if .boot_file}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.boot_file}}" tabindex="3" autofocus required maxlength="255" > | |||||
| {{else}} | {{else}} | ||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | ||||
| {{end}} | {{end}} | ||||
| @@ -175,15 +193,29 @@ | |||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | ||||
| <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | ||||
| <input id="store_run_para" type="hidden" name="run_para_list"> | <input id="store_run_para" type="hidden" name="run_para_list"> | ||||
| <div class="dynamic field" style="margin-top: 1rem;"> | |||||
| <div class="dynamic field" style="margin-top: 1rem;" data-params="{{.run_para_list}}"> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="required min_title inline field" id="flavor_name"> | <div class="required min_title inline field" id="flavor_name"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | ||||
| <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | ||||
| {{range .flavor_infos}} | |||||
| {{if .flavor}} | |||||
| {{range .flavor_infos}} | |||||
| {{if eq $.flavor .ID}} | |||||
| <option value="{{.ID}}">{{.Name}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{range .flavor_infos}} | |||||
| {{if ne $.flavor .ID}} | |||||
| <option value="{{.ID}}">{{.Name}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{else}} | |||||
| {{range .flavor_infos}} | |||||
| <option name="flavor" value="{{.ID}}">{{.Name}}</option> | <option name="flavor" value="{{.ID}}">{{.Name}}</option> | ||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -226,126 +258,58 @@ | |||||
| $('.menu .item') | $('.menu .item') | ||||
| .tab(); | .tab(); | ||||
| // let sever_num = $("#trainjob_work_server_num_select .text").text() //$('#trainjob_work_server_num') | |||||
| // console.log("sever_num:",sever_num) | |||||
| // $('.add').click(function(){ | |||||
| // sever_num.val(parseInt(sever_num.val())+1) | |||||
| // if(sever_num.val()>=26){ | |||||
| // sever_num.val(parseInt(sever_num.val())-1) | |||||
| // } | |||||
| // }) | |||||
| // $('.min').click(function(){ | |||||
| // sever_num.val(parseInt(sever_num.val())-1) | |||||
| // if(sever_num.val()<=0){ | |||||
| // sever_num.val(parseInt(sever_num.val())+1) | |||||
| // } | |||||
| // }) | |||||
| $(document).ready(function(){ | |||||
| let params = $('.dynamic.field').data('params') | |||||
| params&¶ms.parameter.forEach((item,index)=>{ | |||||
| Add_parameter(index,flag=true,item) | |||||
| }) | |||||
| }) | |||||
| // 参数增加、删除、修改、保存 | // 参数增加、删除、修改、保存 | ||||
| function Add_parameter(i){ | |||||
| value = '<div class="two fields width85" id= "para'+ i +'">' + | |||||
| '<div class="field">' + | |||||
| '<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' + | |||||
| '</div> ' + | |||||
| '<div class="field"> ' + | |||||
| '<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' + | |||||
| '</div>'+ | |||||
| '<span>' + | |||||
| '<i class="trash icon">' + | |||||
| '</i>' + | |||||
| '</span>' + | |||||
| '</div>' | |||||
| function Add_parameter(i,flag=false,paramsObject={}) { | |||||
| let value = '' | |||||
| value += `<div class="two fields width85" id= "para${i}">` | |||||
| value += '<div class="field">' | |||||
| if(flag){ | |||||
| value +=`<input type="text" class="shipping_first-name" value="${paramsObject.label}">` | |||||
| }else{ | |||||
| value +='<input type="text" class="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}>' | |||||
| } | |||||
| value += '</div>' | |||||
| value += '<div class="field">' | |||||
| if(flag){ | |||||
| value +=`<input type="text" class="shipping_last-name" value="${paramsObject.value}">` | |||||
| }else{ | |||||
| value +='<input type="text" class="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' | |||||
| } | |||||
| value += '</div>' | |||||
| value += '<span><i class="trash icon"></i></span>' | |||||
| value += '</div>' | |||||
| $(".dynamic.field").append(value) | $(".dynamic.field").append(value) | ||||
| } | } | ||||
| $('#add_run_para').click(function(){ | |||||
| $('#add_run_para').click(function () { | |||||
| var len = $(".dynamic.field .two.fields").length | var len = $(".dynamic.field .two.fields").length | ||||
| Add_parameter(len) | Add_parameter(len) | ||||
| }); | }); | ||||
| $(".dynamic.field").on("click",".trash.icon", function() { | |||||
| $(".dynamic.field").on("click", ".trash.icon", function () { | |||||
| var index = $(this).parent().parent().index() | var index = $(this).parent().parent().index() | ||||
| $(this).parent().parent().remove() | $(this).parent().parent().remove() | ||||
| var len = $(".dynamic.field .two.fields").length | var len = $(".dynamic.field .two.fields").length | ||||
| $(".dynamic.field .two.fields").each(function(){ | |||||
| $(".dynamic.field .two.fields").each(function () { | |||||
| var cur_index = $(this).index() | var cur_index = $(this).index() | ||||
| $(this).attr('id', 'para' + cur_index) | $(this).attr('id', 'para' + cur_index) | ||||
| }) | }) | ||||
| }); | }); | ||||
| $('.ui.parameter.green.button').click(function(){ | |||||
| var parameters = []; | |||||
| $('table tr').each(function() { | |||||
| $(this).find('td:eq(1)').each(function(){ | |||||
| parameters.push($(this).text()); | |||||
| }) | |||||
| $(this).find('input').each(function(){ | |||||
| parameters.push($(this).text()) | |||||
| }) | |||||
| }); | |||||
| $('.ui.parameter.modal') | |||||
| .modal('hide'); | |||||
| for(var i = 2; i < parameters.length; i++){ | |||||
| switch(i) { | |||||
| // 数据集uuid待完成 | |||||
| // case (2): | |||||
| // console.log(1) | |||||
| // break; | |||||
| // $("#trainjob_datasets").val(parameters[i]); | |||||
| // console.log($("#trainjob_datasets").val()) | |||||
| case (3): | |||||
| $("input[name='boot_file']").val(parameters[i]); | |||||
| break; | |||||
| case (4): | |||||
| var para = parameters[i].split(" ") | |||||
| for(var j = 0; j < para.length; j++){ | |||||
| var para_name = para[j].split('=')[0] | |||||
| var para_value = para[j].split('=')[1] | |||||
| var len = $(".dynamic.field .two.fields").length | |||||
| Add_parameter(len) | |||||
| var pid = 'para' + len | |||||
| $(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_first-name]").val(para_name) | |||||
| $(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_last-name]").val(para_value) | |||||
| } | |||||
| break; | |||||
| // 数据集pool_id待完成 | |||||
| // case (5): | |||||
| // $("select[name='pool_id']").val(parameters[i]); | |||||
| // break; | |||||
| case (6): | |||||
| // $("input[name='work_server_number']").val(parameters[i]); | |||||
| break; | |||||
| } | |||||
| } | |||||
| }) | |||||
| $('.ui.save.checkbox').click(function(){ | |||||
| $(this).checkbox({ | |||||
| onChange: function(){ | |||||
| if ($('.ui.save.checkbox').checkbox('is checked')){ | |||||
| $('#save_para').removeClass("disabled") | |||||
| }else{ | |||||
| $('#save_para').addClass("disabled") | |||||
| } | |||||
| } | |||||
| }); | |||||
| }) | |||||
| $('.question.circle.icon').hover(function(){ | $('.question.circle.icon').hover(function(){ | ||||
| $(this).popup('show') | $(this).popup('show') | ||||
| }); | }); | ||||
| $(".item.active.parameter_config").click(function(){ | |||||
| $('.ui.parameter.modal') | |||||
| .modal('setting', 'closable', false) | |||||
| .modal('show'); | |||||
| }) | |||||
| $('.ui.deny.button').click(function(){ | |||||
| $('.ui.parameter.modal') | |||||
| .modal('hide'); | |||||
| }) | |||||
| $('select.dropdown') | $('select.dropdown') | ||||
| .dropdown(); | .dropdown(); | ||||
| @@ -366,7 +330,7 @@ | |||||
| identifier : 'display_job_name', | identifier : 'display_job_name', | ||||
| rules: [ | rules: [ | ||||
| { | { | ||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
| type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | |||||
| } | } | ||||
| ] | ] | ||||
| }, | }, | ||||
| @@ -402,13 +366,13 @@ | |||||
| document.getElementById("mask").style.display = "none" | document.getElementById("mask").style.display = "none" | ||||
| } | } | ||||
| } | } | ||||
| function send_run_para(){ | |||||
| function send_run_para() { | |||||
| var run_parameters = [] | var run_parameters = [] | ||||
| var msg = {} | var msg = {} | ||||
| $(".dynamic.field .two.fields").each(function(){ | |||||
| var para_name = $(this).find('input[name=shipping_first-name]').val() | |||||
| var para_value = $(this).find('input[name=shipping_last-name]').val() | |||||
| run_parameters.push({"label": para_name, "value": para_value}) | |||||
| $(".dynamic.field .two.fields").each(function () { | |||||
| var para_name = $(this).find('input.shipping_first-name').val() | |||||
| var para_value = $(this).find('input.shipping_last-name').val() | |||||
| run_parameters.push({ "label": para_name, "value": para_value }) | |||||
| }) | }) | ||||
| msg["parameter"] = run_parameters | msg["parameter"] = run_parameters | ||||
| msg = JSON.stringify(msg) | msg = JSON.stringify(msg) | ||||
| @@ -425,9 +389,10 @@ | |||||
| $("input#trainjob_work_server_num").val(val_server_num_select) | $("input#trainjob_work_server_num").val(val_server_num_select) | ||||
| } | } | ||||
| validate(); | |||||
| $('.ui.create_train_job.green.button').click(function(e) { | $('.ui.create_train_job.green.button').click(function(e) { | ||||
| get_name() | get_name() | ||||
| send_run_para() | send_run_para() | ||||
| validate() | |||||
| validate(); | |||||
| }) | }) | ||||
| </script> | </script> | ||||
| @@ -190,7 +190,6 @@ | |||||
| <script src="{{StaticUrlPrefix}}/self/js/notebook/katex.min.js"></script> | <script src="{{StaticUrlPrefix}}/self/js/notebook/katex.min.js"></script> | ||||
| <script src="{{StaticUrlPrefix}}/self/js/notebook/katex-auto-render.min.js"></script> | <script src="{{StaticUrlPrefix}}/self/js/notebook/katex-auto-render.min.js"></script> | ||||
| <script src="{{StaticUrlPrefix}}/self/js/notebook/notebook.min.js"></script> | <script src="{{StaticUrlPrefix}}/self/js/notebook/notebook.min.js"></script> | ||||
| <script src="{{StaticUrlPrefix}}/self/js/notebook/notebook.min.js"></script> | |||||
| <link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/katex.min.css" /> | <link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/katex.min.css" /> | ||||
| <link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/prism.css" /> | <link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/prism.css" /> | ||||
| <link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/notebook.css" /> | <link rel="stylesheet" href="{{StaticUrlPrefix}}/self/css/notebook/notebook.css" /> | ||||
| @@ -11,7 +11,7 @@ | |||||
| {{template "base/alert" .}} | {{template "base/alert" .}} | ||||
| <div class="inline required field {{if .Err_CloneAddr}}error{{end}}"> | <div class="inline required field {{if .Err_CloneAddr}}error{{end}}"> | ||||
| <label for="clone_addr">{{.i18n.Tr "repo.migrate.clone_address"}}</label> | <label for="clone_addr">{{.i18n.Tr "repo.migrate.clone_address"}}</label> | ||||
| <input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required> | |||||
| <input id="clone_addr" name="clone_addr" value="{{.clone_addr}}" autofocus required autocomplete="off" /> | |||||
| <span class="help"> | <span class="help"> | ||||
| {{.i18n.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{.i18n.Tr "repo.migrate.clone_local_path"}}{{end}} | {{.i18n.Tr "repo.migrate.clone_address_desc"}}{{if .ContextUser.CanImportLocal}} {{.i18n.Tr "repo.migrate.clone_local_path"}}{{end}} | ||||
| <br/>{{.i18n.Tr "repo.migrate.migrate_items_options"}} | <br/>{{.i18n.Tr "repo.migrate.migrate_items_options"}} | ||||
| @@ -102,7 +102,7 @@ | |||||
| <button class="ui green button" id="submit_reponame"> | <button class="ui green button" id="submit_reponame"> | ||||
| {{.i18n.Tr "repo.migrate_repo"}} | {{.i18n.Tr "repo.migrate_repo"}} | ||||
| </button> | </button> | ||||
| <a class="ui button" href="{{AppSubUrl}}/">{{.i18n.Tr "cancel"}}</a> | |||||
| <a class="ui button" href="javascript:history.go(-1)">{{.i18n.Tr "cancel"}}</a> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </form> | </form> | ||||
| @@ -58,16 +58,16 @@ | |||||
| <input type="hidden" name="action" value="update"> | <input type="hidden" name="action" value="update"> | ||||
| <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | ||||
| <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | ||||
| {{if $.model_version}} | |||||
| <input type="hidden" id="ai_model_version" name="model_version" value="{{$.model_version}}"> | |||||
| {{else}} | |||||
| <input type="hidden" id="ai_model_version" name="model_version" value=""> | <input type="hidden" id="ai_model_version" name="model_version" value=""> | ||||
| {{end}} | |||||
| {{if $.label_names}} | |||||
| <input type="hidden" id="ai_model_label" name="label_names" value="{{$.label_names}}"> | |||||
| {{else}} | |||||
| <input type="hidden" id="ai_model_label" name="label_names" value=""> | |||||
| {{end}} | |||||
| <input type="hidden" id="failed_train_url" value="{{$.train_url}}"> | |||||
| <input type="hidden" id="failed_model_name" value="{{$.model_name}}"> | |||||
| <input type="hidden" id="failed_model_version" value="{{$.model_version}}"> | |||||
| <input type="hidden" id="failed_ckpt_name" value="{{$.ckpt_name}}"> | |||||
| <input type="hidden" id="failed_train_url" value="{{$.train_url}}"> | |||||
| <input type="hidden" id="fail_dataset_name" value="{{$.dataset_name}}"> | |||||
| <input type="hidden" id="fail_dataset_uuid" value="{{$.attachment}}"> | |||||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | ||||
| <div class="required min_title inline field"> | <div class="required min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | ||||
| @@ -94,29 +94,27 @@ | |||||
| </div> | </div> | ||||
| <div class="required min_title inline field"> | <div class="required min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="64"> | |||||
| <span class="tooltips" style="margin-left:11.5rem;display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="36"> | |||||
| <span class="tooltips" style="margin-left:11.5rem;display: block;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span> | |||||
| </div> | </div> | ||||
| <div class="min_title inline field"> | <div class="min_title inline field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | |||||
| <label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | |||||
| {{if .description}} | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea> | |||||
| {{else}} | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | ||||
| {{end}} | |||||
| </div> | </div> | ||||
| <div class="ui divider"></div> | <div class="ui divider"></div> | ||||
| <!-- 模型相关配置 --> | <!-- 模型相关配置 --> | ||||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4> | <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4> | ||||
| <div class="required unite inline min_title fields" style="width: 96.8%;"> | <div class="required unite inline min_title fields" style="width: 96.8%;"> | ||||
| <div class="required eight wide field"> | <div class="required eight wide field"> | ||||
| <label style="font-weight: normal;white-space: nowrap;width: 210px;text-align: right;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label> | <label style="font-weight: normal;white-space: nowrap;width: 210px;text-align: right;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label> | ||||
| <div class="ui fluid search selection dropdown loading " id="select_model"> | <div class="ui fluid search selection dropdown loading " id="select_model"> | ||||
| {{if $.ckpt_name}} | |||||
| <input type="hidden" name="model_name" value="{{$.model_name}}" required> | |||||
| <div class="text">{{$.model_name}}</div> | |||||
| {{else}} | |||||
| <input type="hidden" name="model_name" required> | <input type="hidden" name="model_name" required> | ||||
| <div class="text"></div> | <div class="text"></div> | ||||
| {{end}} | |||||
| <i class="dropdown icon"></i> | <i class="dropdown icon"></i> | ||||
| <div class="menu" id="model_name"> | <div class="menu" id="model_name"> | ||||
| </div> | </div> | ||||
| @@ -124,13 +122,8 @@ | |||||
| </div> | </div> | ||||
| <div class="three wide field"> | <div class="three wide field"> | ||||
| <div class="ui fluid search selection dropdown" id="select_model_version"> | <div class="ui fluid search selection dropdown" id="select_model_version"> | ||||
| {{if $.ckpt_name}} | |||||
| <input type="hidden" name="train_url" value="{{$.train_url}}" required> | |||||
| <div class="text">{{$.model_version}}</div> | |||||
| {{else}} | |||||
| <input type="hidden" name="train_url" required> | <input type="hidden" name="train_url" required> | ||||
| <div class="text"></div> | <div class="text"></div> | ||||
| {{end}} | |||||
| <i class="dropdown icon"></i> | <i class="dropdown icon"></i> | ||||
| <div class="menu" id="model_name_version"> | <div class="menu" id="model_name_version"> | ||||
| </div> | </div> | ||||
| @@ -139,13 +132,8 @@ | |||||
| </div> | </div> | ||||
| <div class="five wide field"> | <div class="five wide field"> | ||||
| <div class="ui fluid search selection dropdown" id="select_model_checkpoint"> | <div class="ui fluid search selection dropdown" id="select_model_checkpoint"> | ||||
| {{if $.ckpt_name}} | |||||
| <input type="hidden" name="ckpt_name" value="{{$.ckpt_name}}" required> | |||||
| <div class="text">{{$.ckpt_name}}</div> | |||||
| {{else}} | |||||
| <input type="hidden" name="ckpt_name" required> | <input type="hidden" name="ckpt_name" required> | ||||
| <div class="text"></div> | <div class="text"></div> | ||||
| {{end}} | |||||
| <i class="dropdown icon"></i> | <i class="dropdown icon"></i> | ||||
| <div class="menu" id="model_checkpoint"> | <div class="menu" id="model_checkpoint"> | ||||
| </div> | </div> | ||||
| @@ -169,9 +157,22 @@ | |||||
| <div class="field" style="flex: 2;" id="engine_name"> | <div class="field" style="flex: 2;" id="engine_name"> | ||||
| <select class="ui dropdown width" id="trainjob_engine_versions" name="engine_id"> | <select class="ui dropdown width" id="trainjob_engine_versions" name="engine_id"> | ||||
| {{if .engine_id}} | |||||
| {{range .engine_versions}} | {{range .engine_versions}} | ||||
| <option name="engine_id" value="{{.ID}}">{{.Value}}</option> | |||||
| {{if eq $.engine_id .ID}} | |||||
| <option value="{{.ID}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{range .engine_versions}} | |||||
| {{if ne $.engine_id .ID}} | |||||
| <option value="{{.ID}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| {{else}} | |||||
| {{range .engine_versions}} | |||||
| <option value="{{.ID}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -251,8 +252,21 @@ | |||||
| <div class="required min_title inline field" id="flaver_name"> | <div class="required min_title inline field" id="flaver_name"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | ||||
| <select class="ui dropdown width80" id="trainjob-flavor" name="flavor"> | <select class="ui dropdown width80" id="trainjob-flavor" name="flavor"> | ||||
| {{range .flavor_infos}} | |||||
| {{if .flavor}} | |||||
| {{range .flavor_infos}} | |||||
| {{if eq $.flavor .Code}} | |||||
| <option value="{{.Code}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{range .flavor_infos}} | |||||
| {{if ne $.flavor .Code}} | |||||
| <option value="{{.Code}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{else}} | |||||
| {{range .flavor_infos}} | |||||
| <option name="flavor" value="{{.Code}}">{{.Value}}</option> | <option name="flavor" value="{{.Code}}">{{.Value}}</option> | ||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -286,30 +300,38 @@ | |||||
| let nameMap,nameList | let nameMap,nameList | ||||
| $(".ui.button").attr('href',url_href) | $(".ui.button").attr('href',url_href) | ||||
| // 获取模型列表和模型名称对应的模型版本 | // 获取模型列表和模型名称对应的模型版本 | ||||
| $.get(`${RepoLink}/modelmanage/query_model_for_predict?type=1`, (data) => { | |||||
| $(document).ready(function(){ | |||||
| modelVersion() | modelVersion() | ||||
| modelCkpt() | modelCkpt() | ||||
| nameMap = data.nameMap | |||||
| nameList = data.nameList | |||||
| let html = '' | |||||
| nameList.forEach(element => { | |||||
| html += `<div class="item" data-value=${element}>${element}</div>` | |||||
| }); | |||||
| if(nameList.length!==0){ | |||||
| const initModelVersion = nameMap[nameList[0]][0] | |||||
| const initTrainTaskInfo = JSON.parse(initModelVersion.TrainTaskInfo) | |||||
| $('#model_name').append(html) | |||||
| $("#select_model").dropdown('set text',nameList[0]) | |||||
| $("#select_model").dropdown('set value',nameList[0],nameList[0]) | |||||
| } | |||||
| $('#select_model').removeClass("loading") | |||||
| $.get(`${RepoLink}/modelmanage/query_model_for_predict?type=1`, (data) => { | |||||
| nameMap = data.nameMap | |||||
| nameList = data.nameList | |||||
| let faildModelName = document.getElementById('failed_model_name').value | |||||
| let html = '' | |||||
| nameList.forEach(element => { | |||||
| html += `<div class="item" data-value=${element}>${element}</div>` | |||||
| }); | |||||
| if(nameList.length!==0){ | |||||
| $('#model_name').append(html) | |||||
| if(faildModelName){ | |||||
| $("#select_model").dropdown('set text',faildModelName) | |||||
| $("#select_model").dropdown('set value',faildModelName) | |||||
| }else{ | |||||
| $("#select_model").dropdown('set text',nameList[0]) | |||||
| $("#select_model").dropdown('set value',nameList[0],nameList[0]) | |||||
| } | |||||
| } | |||||
| $('#select_model').removeClass("loading") | |||||
| }) | |||||
| }) | }) | ||||
| // 根据选中的模型名称获取相应的模型版本 | // 根据选中的模型名称获取相应的模型版本 | ||||
| function modelVersion(){ | function modelVersion(){ | ||||
| let faildModelVersion = $('#failed_model_version').val() | |||||
| let faildTrainUrl = $('#failed_train_url').val() | |||||
| $('#select_model').dropdown({ | $('#select_model').dropdown({ | ||||
| onChange: function(value, text, $selectedItem) { | onChange: function(value, text, $selectedItem) { | ||||
| console.log("-----------------") | |||||
| $("#select_model_version").addClass("loading") | $("#select_model_version").addClass("loading") | ||||
| $('#model_name_version').empty() | $('#model_name_version').empty() | ||||
| let html = '' | let html = '' | ||||
| @@ -322,13 +344,20 @@ | |||||
| $("#select_model_version").removeClass("loading") | $("#select_model_version").removeClass("loading") | ||||
| const initVersionText = $('#model_name_version div.item:first-child').text() | const initVersionText = $('#model_name_version div.item:first-child').text() | ||||
| const initVersionValue = $('#model_name_version div.item:first-child').data('value') | const initVersionValue = $('#model_name_version div.item:first-child').data('value') | ||||
| $("#select_model_version").dropdown('set text',initVersionText) | |||||
| $("#select_model_version").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child')) | |||||
| if(faildModelVersion&&faildTrainUrl){ | |||||
| $("#select_model_version").dropdown('set text',faildModelVersion) | |||||
| $("#select_model_version").dropdown('set value',faildTrainUrl,faildModelVersion,$('#model_name_version div.item:first-child')) | |||||
| }else{ | |||||
| $("#select_model_version").dropdown('set text',initVersionText) | |||||
| $("#select_model_version").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child')) | |||||
| } | |||||
| } | } | ||||
| }) | }) | ||||
| } | } | ||||
| // 根据选中的模型版本获取相应的模型权重文件 | // 根据选中的模型版本获取相应的模型权重文件 | ||||
| function modelCkpt(){ | function modelCkpt(){ | ||||
| let faildCkptName = $('#failed_ckpt_name').val() | |||||
| $('#select_model_version').dropdown({ | $('#select_model_version').dropdown({ | ||||
| onChange: function(value, text, $selectedItem) { | onChange: function(value, text, $selectedItem) { | ||||
| const dataID = $selectedItem[0].getAttribute("data-id") | const dataID = $selectedItem[0].getAttribute("data-id") | ||||
| @@ -343,17 +372,19 @@ | |||||
| if(!element.IsDir && loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length-1])){ | if(!element.IsDir && loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length-1])){ | ||||
| html += `<div class="item" data-value=${element.FileName}>${element.FileName}</div>` | html += `<div class="item" data-value=${element.FileName}>${element.FileName}</div>` | ||||
| } | } | ||||
| }) | }) | ||||
| $('#model_checkpoint').append(html) | $('#model_checkpoint').append(html) | ||||
| $("#select_model_checkpoint").removeClass("loading") | $("#select_model_checkpoint").removeClass("loading") | ||||
| const initVersionText = $('#model_checkpoint div.item:first-child').text() | const initVersionText = $('#model_checkpoint div.item:first-child').text() | ||||
| const initVersionValue = $('#model_checkpoint div.item:first-child').data('value') | const initVersionValue = $('#model_checkpoint div.item:first-child').data('value') | ||||
| $("#select_model_checkpoint").dropdown('set text',initVersionText) | |||||
| $("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child')) | |||||
| if(faildCkptName){ | |||||
| $("#select_model_checkpoint").dropdown('set text',faildCkptName) | |||||
| $("#select_model_checkpoint").dropdown('set value',faildCkptName,faildCkptName,$('#model_name_version div.item:first-child')) | |||||
| }else{ | |||||
| $("#select_model_checkpoint").dropdown('set text',initVersionText) | |||||
| $("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child')) | |||||
| } | |||||
| }) | }) | ||||
| $("input#ai_model_version").val(text) | $("input#ai_model_version").val(text) | ||||
| $("input#ai_model_label").val(label) | $("input#ai_model_label").val(label) | ||||
| } | } | ||||
| @@ -419,7 +450,6 @@ | |||||
| let name2=$("#flaver_name .text").text() | let name2=$("#flaver_name .text").text() | ||||
| $("input#ai_engine_name").val(name1) | $("input#ai_engine_name").val(name1) | ||||
| $("input#ai_flaver_name").val(name2) | $("input#ai_flaver_name").val(name2) | ||||
| } | } | ||||
| function validate(){ | function validate(){ | ||||
| $('.ui.form') | $('.ui.form') | ||||
| @@ -438,7 +468,7 @@ | |||||
| identifier : 'display_job_name', | identifier : 'display_job_name', | ||||
| rules: [ | rules: [ | ||||
| { | { | ||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[^-]$/]', | |||||
| type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | |||||
| } | } | ||||
| ] | ] | ||||
| }, | }, | ||||
| @@ -489,9 +519,10 @@ | |||||
| document.getElementById("mask").style.display = "none" | document.getElementById("mask").style.display = "none" | ||||
| } | } | ||||
| } | } | ||||
| validate(); | |||||
| $('.ui.create_train_job.green.button').click(function(e) { | $('.ui.create_train_job.green.button').click(function(e) { | ||||
| send_run_para() | send_run_para() | ||||
| get_name() | get_name() | ||||
| validate() | |||||
| validate(); | |||||
| }) | }) | ||||
| </script> | </script> | ||||
| @@ -50,7 +50,7 @@ | |||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | <label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | ||||
| <input name="display_job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||||
| <input name="display_job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="36" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||||
| </div> | </div> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| @@ -110,15 +110,37 @@ | |||||
| $('#messageInfo').css('display','none') | $('#messageInfo').css('display','none') | ||||
| function validate(){ | |||||
| $('.ui.form').form({ | |||||
| on: 'blur', | |||||
| fields: { | |||||
| display_job_name:{ | |||||
| identifier : 'display_job_name', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| }, | |||||
| onSuccess: function(){ | |||||
| }, | |||||
| onFailure: function(e){ | |||||
| return false; | |||||
| } | |||||
| }) | |||||
| } | |||||
| validate(); | |||||
| form.onsubmit = function(e){ | form.onsubmit = function(e){ | ||||
| let value_task = $("input[name='display_job_name']").val() | let value_task = $("input[name='display_job_name']").val() | ||||
| let re = /^[a-z0-9][a-z0-9-_]{1,36}$/ | |||||
| let re = /^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/ | |||||
| let flag = re.test(value_task) | let flag = re.test(value_task) | ||||
| if(!flag){ | if(!flag){ | ||||
| $('#messageInfo').css('display','block') | $('#messageInfo').css('display','block') | ||||
| let str = '只能以小写字母或数字开头且只包含小写字母、数字、_和-、最长36个字符。' | |||||
| let str = '只能以小写字母或数字开头且只包含小写字母、数字、_和-,不能以_结尾,最长36个字符。' | |||||
| $('#messageInfo p').text(str) | $('#messageInfo p').text(str) | ||||
| return false | return false | ||||
| } | } | ||||
| @@ -257,7 +257,9 @@ | |||||
| class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | ||||
| <span class="cti-mgRight-sm uc-accordionTitle-black" | <span class="cti-mgRight-sm uc-accordionTitle-black" | ||||
| id="{{.VersionName}}-duration-span">{{$.duration}}</span> | id="{{.VersionName}}-duration-span">{{$.duration}}</span> | ||||
| <span id="refresh-status" data-tooltip="刷新" style="cursor: pointer;" data-inverted="" data-version="{{.VersionName}}"> | |||||
| <i class="redo icon redo-color"></i> | |||||
| </span> | |||||
| </div> | </div> | ||||
| </span> | </span> | ||||
| </span> | </span> | ||||
| @@ -357,7 +359,15 @@ | |||||
| <td class="ti-text-form-content"> | <td class="ti-text-form-content"> | ||||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | ||||
| {{.Image}} | |||||
| <span class="ui poping up clipboard" data-position="top center" id="clipboard-btn" style="cursor:pointer" | |||||
| data-clipboard-text="{{.Image}}" | |||||
| data-success="{{$.i18n.Tr "repo.copy_link_success"}}" | |||||
| data-error="{{$.i18n.Tr "repo.copy_link_error"}}" | |||||
| data-content="{{$.i18n.Tr "repo.copy_link"}}" | |||||
| data-variation="inverted tiny" | |||||
| > | |||||
| <span title="{{.Image}}">{{.Image}}</span> | |||||
| </span> | |||||
| </div> | </div> | ||||
| </td> | </td> | ||||
| </tr> | </tr> | ||||
| @@ -122,13 +122,17 @@ | |||||
| </div> | </div> | ||||
| <div class="required inline min_title field"> | <div class="required inline min_title field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | ||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="64"> | |||||
| <span class="tooltips" style="margin-left:11.5rem;display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
| <input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required maxlength="36"> | |||||
| <span class="tooltips" style="margin-left:11.5rem;display: block;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span> | |||||
| </div> | </div> | ||||
| <div class="inline min_title field"> | <div class="inline min_title field"> | ||||
| <label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | <label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | ||||
| {{if .description}} | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea> | |||||
| {{else}} | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)"></textarea> | ||||
| {{end}} | |||||
| </div> | </div> | ||||
| <div class="ui divider"></div> | <div class="ui divider"></div> | ||||
| @@ -170,9 +174,22 @@ | |||||
| <div class="field" style="flex: 2;" id="engine_name"> | <div class="field" style="flex: 2;" id="engine_name"> | ||||
| <select class="ui dropdown width" id="trainjob_engine_versions" name="engine_id"> | <select class="ui dropdown width" id="trainjob_engine_versions" name="engine_id"> | ||||
| {{if .engine_id}} | |||||
| {{range .engine_versions}} | {{range .engine_versions}} | ||||
| <option name="engine_id" value="{{.ID}}">{{.Value}}</option> | |||||
| {{if eq $.engine_id .ID}} | |||||
| <option value="{{.ID}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{range .engine_versions}} | |||||
| {{if ne $.engine_id .ID}} | |||||
| <option value="{{.ID}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| {{else}} | |||||
| {{range .engine_versions}} | |||||
| <option value="{{.ID}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -220,7 +237,6 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="required min_title field " style="display: none;"> | <div class="required min_title field " style="display: none;"> | ||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label> | <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label> | ||||
| <select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id"> | <select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id"> | ||||
| @@ -246,12 +262,24 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="required inline min_title field" id="flaver_name"> | <div class="required inline min_title field" id="flaver_name"> | ||||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | ||||
| <select class="ui dropdown width48" id="trainjob-flavor" name="flavor"> | <select class="ui dropdown width48" id="trainjob-flavor" name="flavor"> | ||||
| {{range .flavor_infos}} | |||||
| <option name="flavor" value="{{.Code}}">{{.Value}}</option> | |||||
| {{if .flavor}} | |||||
| {{range .flavor_infos}} | |||||
| {{if eq $.flavor .Code}} | |||||
| <option value="{{.Code}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{range .flavor_infos}} | |||||
| {{if ne $.flavor .Code}} | |||||
| <option value="{{.Code}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{else}} | |||||
| {{range .flavor_infos}} | |||||
| <option name="flavor" value="{{.Code}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| @@ -441,7 +469,7 @@ | |||||
| identifier: 'display_job_name', | identifier: 'display_job_name', | ||||
| rules: [ | rules: [ | ||||
| { | { | ||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
| type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]', | |||||
| } | } | ||||
| ] | ] | ||||
| }, | }, | ||||
| @@ -500,9 +528,10 @@ | |||||
| $("input#trainjob_work_server_num").val(val_server_num_select) | $("input#trainjob_work_server_num").val(val_server_num_select) | ||||
| } | } | ||||
| validate(); | |||||
| $('.ui.create_train_job.green.button').click(function (e) { | $('.ui.create_train_job.green.button').click(function (e) { | ||||
| get_name() | get_name() | ||||
| send_run_para() | |||||
| validate() | |||||
| send_run_para(); | |||||
| validate(); | |||||
| }) | }) | ||||
| </script> | </script> | ||||
| @@ -270,7 +270,7 @@ | |||||
| {{end}} | {{end}} | ||||
| {{if .CanDel}} | {{if .CanDel}} | ||||
| <a class="ti-action-menu-item stop-show-version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED"}}disabled {{end}}" | |||||
| <a class="ti-action-menu-item stop-show-version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED"}}disabled {{end}}" | |||||
| id="{{.VersionName}}-stop" | id="{{.VersionName}}-stop" | ||||
| data-jobid="{{.JobID}}" | data-jobid="{{.JobID}}" | ||||
| data-repopath="{{$.RepoRelPath}}/modelarts/train-job" | data-repopath="{{$.RepoRelPath}}/modelarts/train-job" | ||||
| @@ -6,7 +6,8 @@ | |||||
| text-align: right; | text-align: right; | ||||
| } | } | ||||
| .inline .ui.dropdown .text { | .inline .ui.dropdown .text { | ||||
| color: rgba(0, 0, 0, .87) !important | |||||
| color: rgba(0, 0, 0, .87) !important; | |||||
| max-width: 360px; | |||||
| } | } | ||||
| .newtext{ | .newtext{ | ||||
| left: 15px !important | left: 15px !important | ||||
| @@ -103,20 +103,23 @@ | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| {{else if .FileSize}} | {{else if .FileSize}} | ||||
| <table> | |||||
| {{if .IsNoteBook}} | |||||
| <div id="notebook"></div> | |||||
| {{else}} | |||||
| <table> | |||||
| <tbody> | <tbody> | ||||
| <tr> | <tr> | ||||
| {{if .IsFileTooLarge}} | {{if .IsFileTooLarge}} | ||||
| <td><strong>{{.i18n.Tr "repo.file_too_large"}}</strong></td> | <td><strong>{{.i18n.Tr "repo.file_too_large"}}</strong></td> | ||||
| {{else if .IsNoteBook}} | |||||
| <td id="notebook"></td> | |||||
| {{else}} | {{else}} | ||||
| <td class="lines-num">{{.LineNums}}</td> | <td class="lines-num">{{.LineNums}}</td> | ||||
| <td class="lines-code"><pre><code class="{{.HighlightClass}}"><ol class="linenums">{{.FileContent}}</ol></code></pre></td> | <td class="lines-code"><pre><code class="{{.HighlightClass}}"><ol class="linenums">{{.FileContent}}</ol></code></pre></td> | ||||
| {{end}} | {{end}} | ||||
| </tr> | </tr> | ||||
| </tbody> | </tbody> | ||||
| </table> | |||||
| </table> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -134,6 +137,9 @@ function showNoteBook(){ | |||||
| var isNoteBook = {{.IsNoteBook}} | var isNoteBook = {{.IsNoteBook}} | ||||
| if (isNoteBook) { | if (isNoteBook) { | ||||
| var jsonStr = "{{.FileContent}}" | var jsonStr = "{{.FileContent}}" | ||||
| nb.markdown.setOptions({ | |||||
| baseUrl: {{.FileParentURL}} | |||||
| }); | |||||
| var notebook = nb.parse(JSON.parse(jsonStr)); | var notebook = nb.parse(JSON.parse(jsonStr)); | ||||
| var rendered = notebook.render(); | var rendered = notebook.render(); | ||||
| $("#notebook").append(rendered); | $("#notebook").append(rendered); | ||||
| @@ -20,7 +20,7 @@ | |||||
| data-all-compute="{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}" | data-all-compute="{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}" | ||||
| data-all-status="{{.i18n.Tr "admin.cloudbrain.all_status"}}"></div> | data-all-status="{{.i18n.Tr "admin.cloudbrain.all_status"}}"></div> | ||||
| {{template "admin/cloudbrain/search_dashboard" .}} | {{template "admin/cloudbrain/search_dashboard" .}} | ||||
| <div class="ui container" style="width: 80%;"> | |||||
| <div class="ui container" style="width: 90%;"> | |||||
| {{template "base/alert" .}} | {{template "base/alert" .}} | ||||
| <div class="ui grid"> | <div class="ui grid"> | ||||
| <div class="row"> | <div class="row"> | ||||
| @@ -30,30 +30,42 @@ | |||||
| <!-- 表头 --> | <!-- 表头 --> | ||||
| <div class="ui grid stackable" style="background: #f0f0f0;;"> | <div class="ui grid stackable" style="background: #f0f0f0;;"> | ||||
| <div class="row"> | <div class="row"> | ||||
| <div class="three wide column nowrap" style="width:15%"> | |||||
| <span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task"}}</span> | |||||
| <div class="three wide column nowrap" style="width:12%!important"> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_task"}}</span> | |||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap" style="width: 11% !important;"> | |||||
| <!-- 集群 --> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.cluster"}}</span> | |||||
| </div> | |||||
| <div class="two wide column text center nowrap" style="width: 8% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.status"}}</span> | <span>{{$.i18n.Tr "repo.modelarts.status"}}</span> | ||||
| </div> | </div> | ||||
| <div class="one wide column text center nowrap" style="width:10%"> | |||||
| <span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task_type"}}</span> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important"> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_task_type"}}</span> | |||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap" style="width: 11% !important;"> | |||||
| <div class="two wide column text center nowrap" style="width: 8% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | ||||
| </div> | </div> | ||||
| <div class="one wide column text center nowrap" style="width:8.5% !important;"> | |||||
| <div class="one wide column text center nowrap" style="width:6% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | ||||
| </div> | </div> | ||||
| <div class="one wide column text center nowrap" style="width:8.5% !important;"> | |||||
| <div class="one wide column text center nowrap" style="width:6% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | ||||
| </div> | </div> | ||||
| <div class="two wide column text center nowrap" style="width: 14.5%!important;"> | |||||
| <!-- 智算中心 --> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.ai_center"}}</span> | |||||
| </div> | |||||
| <!-- XPU类型 --> | |||||
| <div class="one wide column text center nowrap" style="width:10% !important;"> | |||||
| <span>{{$.i18n.Tr "repo.modelarts.card_type"}}</span> | |||||
| </div> | |||||
| <div class="two wide column text center nowrap" style="width: 11%!important;"> | |||||
| <span>{{$.i18n.Tr "repository"}}</span> | <span>{{$.i18n.Tr "repository"}}</span> | ||||
| </div> | </div> | ||||
| <div class="three wide column text center nowrap" style="width: 21.5%!important;"> | |||||
| <div class="three wide column text center nowrap" style="width: 15%!important;"> | |||||
| <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -70,48 +82,52 @@ | |||||
| {{$JobID = .JobID}} | {{$JobID = .JobID}} | ||||
| {{end}} | {{end}} | ||||
| <!-- {{$JobID}} --> | <!-- {{$JobID}} --> | ||||
| <div class="three wide column nowrap" style="width:15%"> | |||||
| <div class="three wide column nowrap" style="width:12% !important"> | |||||
| {{if eq .JobType "DEBUG"}} | {{if eq .JobType "DEBUG"}} | ||||
| <a class="title" | <a class="title" | ||||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{$JobID}}{{else}}/modelarts/notebook/{{$JobID}}{{end}}" | href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{$JobID}}{{else}}/modelarts/notebook/{{$JobID}}{{end}}" | ||||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}} | {{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}} | ||||
| <a class="title" | <a class="title" | ||||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | ||||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{else if eq .JobType "INFERENCE"}} | {{else if eq .JobType "INFERENCE"}} | ||||
| <a class="title" | <a class="title" | ||||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .Cloudbrain.Type 1}}modelarts{{else if eq .Cloudbrain.Type 0}}cloudbrain{{end}}/inference-job/{{$JobID}}" | href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .Cloudbrain.Type 1}}modelarts{{else if eq .Cloudbrain.Type 0}}cloudbrain{{end}}/inference-job/{{$JobID}}" | ||||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{else if eq .JobType "TRAIN"}} | {{else if eq .JobType "TRAIN"}} | ||||
| <a class="title" | <a class="title" | ||||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .Cloudbrain.Type 1}}modelarts{{else if eq .Cloudbrain.Type 0}}cloudbrain{{else if eq .Cloudbrain.Type 2}}grampus{{end}}/train-job/{{$JobID}}" | href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .Cloudbrain.Type 1}}modelarts{{else if eq .Cloudbrain.Type 0}}cloudbrain{{else if eq .Cloudbrain.Type 2}}grampus{{end}}/train-job/{{$JobID}}" | ||||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{else if eq .JobType "BENCHMARK"}} | {{else if eq .JobType "BENCHMARK"}} | ||||
| <a class="title" | <a class="title" | ||||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | ||||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <!-- 集群 --> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important;"> | |||||
| <span | |||||
| style="font-size: 12px;">{{if .Cluster}}{{.Cluster}}{{else}}--{{end}}</span> | |||||
| </div> | |||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column text center nowrap" | <div class="two wide column text center nowrap" | ||||
| style="padding-left: 2.2rem !important; width: 11% !important;"> | |||||
| style="width: 8% !important;"> | |||||
| <span class="job-status" id="{{$JobID}}" | <span class="job-status" id="{{$JobID}}" | ||||
| data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts{{end}}/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' | data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts{{end}}/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' | ||||
| data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | ||||
| @@ -123,32 +139,44 @@ | |||||
| <!-- 任务类型 --> | <!-- 任务类型 --> | ||||
| {{$JobType := $.i18n.Tr (printf "cloudbrain.%s" .JobType)}} | {{$JobType := $.i18n.Tr (printf "cloudbrain.%s" .JobType)}} | ||||
| <div class="one wide column text center nowrap" style="width:10%"> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important"> | |||||
| <span style="font-size: 12px;" title="{{.JobType}}">{{$JobType}}</span> | <span style="font-size: 12px;" title="{{.JobType}}">{{$JobType}}</span> | ||||
| </div> | </div> | ||||
| <!-- 任务创建时间 --> | <!-- 任务创建时间 --> | ||||
| <div class="two wide column text center nowrap" style="width: 11% !important;"> | |||||
| <div class="two wide column text center nowrap" style="width: 8% !important;"> | |||||
| <span style="font-size: 12px;" | <span style="font-size: 12px;" | ||||
| class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | ||||
| </div> | </div> | ||||
| <!-- 任务运行时间 --> | <!-- 任务运行时间 --> | ||||
| <div class="one wide column text center nowrap" style="width:8.5% !important;"> | |||||
| <div class="one wide column text center nowrap" style="width:6% !important;"> | |||||
| <span style="font-size: 12px;" | <span style="font-size: 12px;" | ||||
| id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | ||||
| </div> | </div> | ||||
| <!-- 计算资源 --> | <!-- 计算资源 --> | ||||
| <div class="one wide column text center nowrap" style="width:8.5% !important;"> | |||||
| <div class="one wide column text center nowrap" style="width:6% !important;"> | |||||
| <span | <span | ||||
| style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | ||||
| </div> | </div> | ||||
| <!-- 智算中心 --> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important;"> | |||||
| <span | |||||
| style="font-size: 12px;">{{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}}</span> | |||||
| </div> | |||||
| <!-- XPU类型 --> | |||||
| <div class="one wide column text center nowrap" style="width:10% !important;"> | |||||
| <span style="font-size: 12px;" title="{{.CardType}}"> | |||||
| {{if .CardType}}{{.CardType}}{{else}}--{{end}} | |||||
| </span> | |||||
| </div> | |||||
| <!-- 项目 --> | <!-- 项目 --> | ||||
| <div class="two wide column text center nowrap" style="width: 14.5%!important;"> | |||||
| <div class="two wide column text center nowrap" style="width: 11%!important;"> | |||||
| <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}" | <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}" | ||||
| title="{{.Repo.OwnerName}}/{{.Repo.Alias}}">{{.Repo.OwnerName}}/{{.Repo.Alias}}</a> | title="{{.Repo.OwnerName}}/{{.Repo.Alias}}">{{.Repo.OwnerName}}/{{.Repo.Alias}}</a> | ||||
| </div> | </div> | ||||
| <div class="three wide column text center nowrap" style="width: 21.5%!important;"> | |||||
| <div class="three wide column text center nowrap" style="width: 15%!important;"> | |||||
| {{if eq .JobType "DEBUG"}} | {{if eq .JobType "DEBUG"}} | ||||
| <div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
| <form id="debugAgainForm-{{$JobID}}"> | <form id="debugAgainForm-{{$JobID}}"> | ||||
| @@ -226,33 +254,37 @@ | |||||
| <div class="ui grid stackable item"> | <div class="ui grid stackable item"> | ||||
| <div class="row"> | <div class="row"> | ||||
| <!-- 任务名 --> | <!-- 任务名 --> | ||||
| <div class="three wide column nowrap" style="width:15%"> | |||||
| <div class="three wide column nowrap" style="width:12% !important"> | |||||
| {{if eq .JobType "DEBUG"}} | {{if eq .JobType "DEBUG"}} | ||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{else if eq .JobType "INFERENCE"}} | {{else if eq .JobType "INFERENCE"}} | ||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{else if eq .JobType "TRAIN"}} | {{else if eq .JobType "TRAIN"}} | ||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{else if eq .JobType "BENCHMARK"}} | {{else if eq .JobType "BENCHMARK"}} | ||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||||
| <span class="fitted" | <span class="fitted" | ||||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | ||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <!-- 集群 --> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important;"> | |||||
| <span | |||||
| style="font-size: 12px;">{{if .Cluster}}{{.Cluster}}{{else}}--{{end}}</span> | |||||
| </div> | |||||
| <!-- 任务状态 --> | <!-- 任务状态 --> | ||||
| <div class="two wide column text center nowrap" | <div class="two wide column text center nowrap" | ||||
| style="padding-left: 2.2rem !important; width: 11% !important;"> | |||||
| style="padding-left: 2.2rem !important; width: 8% !important;"> | |||||
| <span class="job-status" id="{{$JobID}}" data-jobid="{{$JobID}}" | <span class="job-status" id="{{$JobID}}" data-jobid="{{$JobID}}" | ||||
| data-version="{{.VersionName}}"> | data-version="{{.VersionName}}"> | ||||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" | <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" | ||||
| @@ -262,31 +294,42 @@ | |||||
| </div> | </div> | ||||
| <!-- 任务类型 --> | <!-- 任务类型 --> | ||||
| {{$JobType := $.i18n.Tr (printf "cloudbrain.%s" .JobType)}} | {{$JobType := $.i18n.Tr (printf "cloudbrain.%s" .JobType)}} | ||||
| <div class="one wide column text center nowrap" style="width:10%"> | |||||
| <div class="one wide column text center nowrap" style="width:8%"> | |||||
| <span style="font-size: 12px;" title="{{.JobType}}">{{$JobType}}</span> | <span style="font-size: 12px;" title="{{.JobType}}">{{$JobType}}</span> | ||||
| </div> | </div> | ||||
| <!-- 任务创建时间 --> | <!-- 任务创建时间 --> | ||||
| <div class="two wide column text center nowrap" style="width: 11% !important;"> | |||||
| <div class="two wide column text center nowrap" style="width: 8% !important;"> | |||||
| <span style="font-size: 12px;" | <span style="font-size: 12px;" | ||||
| class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | ||||
| </div> | </div> | ||||
| <!-- 任务运行时间 --> | <!-- 任务运行时间 --> | ||||
| <div class="one wide column text center nowrap" style="width:8.5% !important;"> | |||||
| <div class="one wide column text center nowrap" style="width:6% !important;"> | |||||
| <span style="font-size: 12px;" | <span style="font-size: 12px;" | ||||
| id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | ||||
| </div> | </div> | ||||
| <!-- 计算资源 --> | <!-- 计算资源 --> | ||||
| <div class="one wide column text center nowrap" style="width:8.5% !important;"> | |||||
| <div class="one wide column text center nowrap" style="width:6% !important;"> | |||||
| <span | <span | ||||
| style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | ||||
| </div> | </div> | ||||
| <!-- 创建者 --> | |||||
| <!-- 智算中心 --> | |||||
| <div class="one wide column text center nowrap" style="width:8% !important;"> | |||||
| <span | |||||
| style="font-size: 12px;">{{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}}</span> | |||||
| </div> | |||||
| <!-- XPU类型 --> | |||||
| <div class="one wide column text center nowrap" style="width:10% !important;"> | |||||
| <span style="font-size: 12px;" title="{{.CardType}}"> | |||||
| {{if .CardType}}{{.CardType}}{{else}}--{{end}} | |||||
| </span> | |||||
| </div> | |||||
| <!-- 项目 --> | <!-- 项目 --> | ||||
| <div class="two wide column text center nowrap" style="width: 14.5%!important;"> | |||||
| <div class="two wide column text center nowrap" style="width: 11%!important;"> | |||||
| <a href="" title="">--</a> | <a href="" title="">--</a> | ||||
| </div> | </div> | ||||
| <div class="three wide column text center nowrap" style="width: 21.5%!important;"> | |||||
| <div class="three wide column text center nowrap" style="width: 15%!important;"> | |||||
| {{if eq .JobType "DEBUG"}} | {{if eq .JobType "DEBUG"}} | ||||
| <div class="ui compact buttons"> | <div class="ui compact buttons"> | ||||
| <form id="debugAgainForm-{{$JobID}}"> | <form id="debugAgainForm-{{$JobID}}"> | ||||
| @@ -361,4 +404,4 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | |||||
| {{template "base/footer" .}} | |||||
| @@ -6,7 +6,7 @@ | |||||
| ref="table" | ref="table" | ||||
| :data="tableData" | :data="tableData" | ||||
| style="min-width: 100%" | style="min-width: 100%" | ||||
| row-key="ID" | |||||
| row-key="rowKey" | |||||
| lazy | lazy | ||||
| :load="load" | :load="load" | ||||
| :tree-props="{children: 'Children', hasChildren: 'hasChildren'}" | :tree-props="{children: 'Children', hasChildren: 'hasChildren'}" | ||||
| @@ -106,7 +106,7 @@ | |||||
| <div class="space-around"> | <div class="space-around"> | ||||
| <a :style="{visibility:!scope.row.Children ? 'visible':'hidden'}" :class="{'disabled':!scope.row.IsCanOper}" @click="showcreateVue(scope.row.Name,scope.row.Version,scope.row.Label)">创建新版本</a> | <a :style="{visibility:!scope.row.Children ? 'visible':'hidden'}" :class="{'disabled':!scope.row.IsCanOper}" @click="showcreateVue(scope.row.Name,scope.row.Version,scope.row.Label)">创建新版本</a> | ||||
| <a :href="loadhref+scope.row.ID" :class="{'disabled':!scope.row.IsCanOper}">下载</a> | <a :href="loadhref+scope.row.ID" :class="{'disabled':!scope.row.IsCanOper}">下载</a> | ||||
| <a :class="{'disabled':!scope.row.IsCanDelete}" @click="deleteModel(scope.row.ID,scope.row.cName)">删除</a> | |||||
| <a :class="{'disabled':!scope.row.IsCanDelete}" @click="deleteModel(scope.row.ID,scope.row.cName,scope.row.rowKey)">删除</a> | |||||
| </div> | </div> | ||||
| </template> | </template> | ||||
| @@ -171,6 +171,7 @@ export default { | |||||
| tableData[i].EngineName = this.getEngineName(tableData[i]) | tableData[i].EngineName = this.getEngineName(tableData[i]) | ||||
| tableData[i].ComputeResource = TrainTaskInfo.ComputeResource | tableData[i].ComputeResource = TrainTaskInfo.ComputeResource | ||||
| tableData[i].cName=tableData[i].Name | tableData[i].cName=tableData[i].Name | ||||
| tableData[i].rowKey = tableData[i].ID + Math.random() | |||||
| tableData[i].Name='' | tableData[i].Name='' | ||||
| tableData[i].VersionCount = '' | tableData[i].VersionCount = '' | ||||
| tableData[i].Children = true | tableData[i].Children = true | ||||
| @@ -310,18 +311,18 @@ export default { | |||||
| const store = this.$refs.table.store | const store = this.$refs.table.store | ||||
| if(!this.loadNodeMap.get(row.cName)){ | if(!this.loadNodeMap.get(row.cName)){ | ||||
| const parent = store.states.data | const parent = store.states.data | ||||
| const index = parent.findIndex(child => child.ID == row.ID) | |||||
| const index = parent.findIndex(child => child.rowKey == row.rowKey) | |||||
| this.getModelList() | this.getModelList() | ||||
| }else{ | }else{ | ||||
| let {tree,treeNode,resolve} = this.loadNodeMap.get(row.cName) | let {tree,treeNode,resolve} = this.loadNodeMap.get(row.cName) | ||||
| const keys = Object.keys(store.states.lazyTreeNodeMap); | const keys = Object.keys(store.states.lazyTreeNodeMap); | ||||
| if(keys.includes(row.ID)){ | |||||
| if(keys.includes(row.rowKey)){ | |||||
| this.getModelList() | this.getModelList() | ||||
| }else{ | }else{ | ||||
| let parentRow = store.states.data.find(child => child.cName == row.cName); | let parentRow = store.states.data.find(child => child.cName == row.cName); | ||||
| let childrenIndex = store.states.lazyTreeNodeMap[parentRow.ID].findIndex(child => child.ID == row.ID) | |||||
| let childrenIndex = store.states.lazyTreeNodeMap[parentRow.rowKey].findIndex(child => child.rowKey == row.rowKey) | |||||
| parentRow.VersionCount = parentRow.VersionCount-1 | parentRow.VersionCount = parentRow.VersionCount-1 | ||||
| const parent = store.states.lazyTreeNodeMap[parentRow.ID] | |||||
| const parent = store.states.lazyTreeNodeMap[parentRow.rowKey] | |||||
| if(parent.length===1){ | if(parent.length===1){ | ||||
| this.getModelList() | this.getModelList() | ||||
| }else{ | }else{ | ||||
| @@ -331,8 +332,8 @@ export default { | |||||
| } | } | ||||
| }, | }, | ||||
| deleteModel(id,name){ | |||||
| let row={cName:name,ID:id} | |||||
| deleteModel(id,name,rowKey){ | |||||
| let row={cName:name,ID:id, rowKey: rowKey} | |||||
| let _this = this | let _this = this | ||||
| let flag=1 | let flag=1 | ||||
| $('.ui.basic.modal.first') | $('.ui.basic.modal.first') | ||||
| @@ -379,8 +380,8 @@ export default { | |||||
| } | } | ||||
| }, | }, | ||||
| getModelList(){ | getModelList(){ | ||||
| try { | |||||
| this.$refs.table.store.states.lazyTreeNodeMap = {} | |||||
| try { | |||||
| this.loadNodeMap.clear(); | |||||
| this.$axios.get(location.href+'_api',{ | this.$axios.get(location.href+'_api',{ | ||||
| params:this.params | params:this.params | ||||
| }).then((res)=>{ | }).then((res)=>{ | ||||
| @@ -391,6 +392,7 @@ export default { | |||||
| for(let i=0;i<this.tableData.length;i++){ | for(let i=0;i<this.tableData.length;i++){ | ||||
| TrainTaskInfo = JSON.parse(this.tableData[i].TrainTaskInfo) | TrainTaskInfo = JSON.parse(this.tableData[i].TrainTaskInfo) | ||||
| this.tableData[i].cName=this.tableData[i].Name | this.tableData[i].cName=this.tableData[i].Name | ||||
| this.tableData[i].rowKey=this.tableData[i].ID + Math.random() | |||||
| this.tableData[i].EngineName = this.getEngineName(this.tableData[i]) | this.tableData[i].EngineName = this.getEngineName(this.tableData[i]) | ||||
| this.tableData[i].ComputeResource = TrainTaskInfo.ComputeResource | this.tableData[i].ComputeResource = TrainTaskInfo.ComputeResource | ||||
| this.tableData[i].hasChildren = res.data.data[i].VersionCount===1 ? false : true | this.tableData[i].hasChildren = res.data.data[i].VersionCount===1 ? false : true | ||||
| @@ -75,8 +75,8 @@ | |||||
| <input | <input | ||||
| type="text" | type="text" | ||||
| placeholder="搜数据集名称/描述..." | placeholder="搜数据集名称/描述..." | ||||
| v-model="search" | |||||
| @keyup.enter="searchName" | |||||
| v-model="search" | |||||
| @keydown.enter.stop.prevent="searchName" | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| <el-row> | <el-row> | ||||
| @@ -727,7 +727,7 @@ export default { | |||||
| "currentTree", | "currentTree", | ||||
| this.paramsCurrent.page | this.paramsCurrent.page | ||||
| ); | ); | ||||
| this.initCurrentTreeNode = [this.currentDatasetList[0].id]; | |||||
| this.initCurrentTreeNode = this.currentDatasetList[0]?.id ? [this.currentDatasetList[0].id] : []; | |||||
| this.totalNumCurrent = parseInt(res.data.count); | this.totalNumCurrent = parseInt(res.data.count); | ||||
| let setCheckedKeysList = this.currentDatasetList.reduce( | let setCheckedKeysList = this.currentDatasetList.reduce( | ||||
| (pre, cur) => { | (pre, cur) => { | ||||
| @@ -742,7 +742,7 @@ export default { | |||||
| ); | ); | ||||
| this.$refs.currentTree.setCheckedKeys(setCheckedKeysList); | this.$refs.currentTree.setCheckedKeys(setCheckedKeysList); | ||||
| }) | }) | ||||
| .catch(function (error) { | |||||
| .catch((error) => { | |||||
| this.loadingCurrent = false; | this.loadingCurrent = false; | ||||
| console.log(error); | console.log(error); | ||||
| }); | }); | ||||
| @@ -763,7 +763,7 @@ export default { | |||||
| "myTree", | "myTree", | ||||
| this.paramsMy.page | this.paramsMy.page | ||||
| ); | ); | ||||
| this.initMyTreeNode = [this.myDatasetList[0].id]; | |||||
| this.initMyTreeNode = this.myDatasetList[0]?.id ? [this.myDatasetList[0].id] : []; | |||||
| this.totalNumMy = parseInt(res.data.count); | this.totalNumMy = parseInt(res.data.count); | ||||
| let setCheckedKeysList = this.myDatasetList.reduce((pre, cur) => { | let setCheckedKeysList = this.myDatasetList.reduce((pre, cur) => { | ||||
| cur.Attachments.forEach((item) => { | cur.Attachments.forEach((item) => { | ||||
| @@ -775,7 +775,7 @@ export default { | |||||
| }, []); | }, []); | ||||
| this.$refs.myTree.setCheckedKeys(setCheckedKeysList); | this.$refs.myTree.setCheckedKeys(setCheckedKeysList); | ||||
| }) | }) | ||||
| .catch(function (error) { | |||||
| .catch((error) => { | |||||
| console.log(error); | console.log(error); | ||||
| }); | }); | ||||
| }, | }, | ||||
| @@ -796,7 +796,7 @@ export default { | |||||
| "publicTree", | "publicTree", | ||||
| this.paramsPublics.page | this.paramsPublics.page | ||||
| ); | ); | ||||
| this.initPublicTreeNode = [this.publicDatasetList[0].id]; | |||||
| this.initPublicTreeNode = this.publicDatasetList[0]?.id ? [this.publicDatasetList[0].id] : []; | |||||
| this.totalNumPublic = parseInt(res.data.count); | this.totalNumPublic = parseInt(res.data.count); | ||||
| let setCheckedKeysList = this.publicDatasetList.reduce((pre, cur) => { | let setCheckedKeysList = this.publicDatasetList.reduce((pre, cur) => { | ||||
| cur.Attachments.forEach((item) => { | cur.Attachments.forEach((item) => { | ||||
| @@ -808,7 +808,7 @@ export default { | |||||
| }, []); | }, []); | ||||
| this.$refs.publicTree.setCheckedKeys(setCheckedKeysList); | this.$refs.publicTree.setCheckedKeys(setCheckedKeysList); | ||||
| }) | }) | ||||
| .catch(function (error) { | |||||
| .catch((error) => { | |||||
| this.loadingPublic = false; | this.loadingPublic = false; | ||||
| console.log(error); | console.log(error); | ||||
| }); | }); | ||||
| @@ -830,7 +830,7 @@ export default { | |||||
| "favoriteTree", | "favoriteTree", | ||||
| this.paramsFavorite.page | this.paramsFavorite.page | ||||
| ); | ); | ||||
| this.initFavoriteTreeNode = [this.MyFavoriteDatasetList[0].id]; | |||||
| this.initFavoriteTreeNode = this.MyFavoriteDatasetList[0]?.id ? [this.MyFavoriteDatasetList[0].id] : []; | |||||
| this.totalNumFavorite = parseInt(res.data.count); | this.totalNumFavorite = parseInt(res.data.count); | ||||
| let setCheckedKeysList = this.MyFavoriteDatasetList.reduce( | let setCheckedKeysList = this.MyFavoriteDatasetList.reduce( | ||||
| (pre, cur) => { | (pre, cur) => { | ||||
| @@ -845,7 +845,7 @@ export default { | |||||
| ); | ); | ||||
| this.$refs.favoriteTree.setCheckedKeys(setCheckedKeysList); | this.$refs.favoriteTree.setCheckedKeys(setCheckedKeysList); | ||||
| }) | }) | ||||
| .catch(function (error) { | |||||
| .catch((error) => { | |||||
| this.loadingFavorite = false; | this.loadingFavorite = false; | ||||
| console.log(error); | console.log(error); | ||||
| }); | }); | ||||
| @@ -955,7 +955,7 @@ export default { | |||||
| ) { | ) { | ||||
| this.benchmarkNew = true; | this.benchmarkNew = true; | ||||
| } | } | ||||
| if (location.href.indexOf("modelarts/notebook/create") !== -1) { | |||||
| if (location.href.indexOf("modelarts/notebook/create") !== -1 || location.href.indexOf("/cloudbrain/create") !== -1) { | |||||
| this.required = false; | this.required = false; | ||||
| } | } | ||||
| window.onresize = () => { | window.onresize = () => { | ||||
| @@ -215,16 +215,16 @@ | |||||
| <div style="display:flex;align-items: center;justify-content: center;"> | <div style="display:flex;align-items: center;justify-content: center;"> | ||||
| <span v-if="scope.row.isPrivate" style="color: rgb(250, 140, 22);">私有</span> | <span v-if="scope.row.isPrivate" style="color: rgb(250, 140, 22);">私有</span> | ||||
| <span v-else style="color: rgb(19, 194, 141);">公开</span> | <span v-else style="color: rgb(19, 194, 141);">公开</span> | ||||
| <el-tooltip class="item" effect="dark" content="镜像提交中..." placement="top"> | |||||
| <i v-if="scope.row.status===0" class="CREATING" style="margin-left:0.3rem"></i> | |||||
| <el-tooltip v-if="scope.row.status===0" class="item" effect="dark" content="镜像提交中..." placement="top"> | |||||
| <i class="CREATING" style="margin-left:0.3rem"></i> | |||||
| </el-tooltip> | </el-tooltip> | ||||
| <el-tooltip class="item" effect="dark" content="检测提交镜像是否大小超过20G!" placement="top"> | |||||
| <i v-if="scope.row.status===2" class="FAILED" style="margin-left:0.3rem"></i> | |||||
| <el-tooltip v-if="scope.row.status===2" class="item" effect="dark" content="检测提交镜像是否大小超过20G!" placement="top"> | |||||
| <i class="FAILED" style="margin-left:0.3rem"></i> | |||||
| </el-tooltip> | </el-tooltip> | ||||
| <el-tooltip class="item" effect="dark" content="镜像提交成功" placement="top"> | |||||
| <i v-if="scope.row.status===1" class="SUCCEEDED" style="margin-left:0.3rem"></i> | |||||
| <el-tooltip v-if="scope.row.status===1" class="item" effect="dark" content="镜像提交成功" placement="top"> | |||||
| <i class="SUCCEEDED" style="margin-left:0.3rem"></i> | |||||
| </el-tooltip> | </el-tooltip> | ||||
| </div> | </div> | ||||
| @@ -473,6 +473,7 @@ export default { | |||||
| tableDataCustom: [], | tableDataCustom: [], | ||||
| starCustom:[], | starCustom:[], | ||||
| loadingCustom:false, | loadingCustom:false, | ||||
| refreshCustomTimer: null, | |||||
| currentPageStar:1, | currentPageStar:1, | ||||
| pageSizeStar:10, | pageSizeStar:10, | ||||
| @@ -485,6 +486,7 @@ export default { | |||||
| methods: { | methods: { | ||||
| handleClick(tab, event) { | handleClick(tab, event) { | ||||
| this.search = '' | this.search = '' | ||||
| this.stopImageListCustomRefresh(); | |||||
| if(tab.name=="first"){ | if(tab.name=="first"){ | ||||
| this.paramsPublic.q = '' | this.paramsPublic.q = '' | ||||
| this.getImageListPublic() | this.getImageListPublic() | ||||
| @@ -560,9 +562,31 @@ export default { | |||||
| }); | }); | ||||
| this.loadingCustom = false | this.loadingCustom = false | ||||
| this.getImageListCustomRefresh() | |||||
| }) | }) | ||||
| }, | }, | ||||
| getImageListCustomRefresh() { | |||||
| this.stopImageListCustomRefresh(); | |||||
| this.refreshCustomTimer = setInterval(() => { | |||||
| this.tableDataCustom.forEach(item => { | |||||
| if (item.status === 0) { | |||||
| this.$axios.get(`/image/${item.id}`, {}).then((res) => { | |||||
| const newData = res.data; | |||||
| this.tableDataCustom.forEach(it => { | |||||
| if (it.id === newData.id) { | |||||
| it.status = newData.status; | |||||
| } | |||||
| }); | |||||
| }) | |||||
| } | |||||
| }); | |||||
| }, 5000); | |||||
| }, | |||||
| stopImageListCustomRefresh() { | |||||
| this.refreshCustomTimer && clearInterval(this.refreshCustomTimer); | |||||
| }, | |||||
| getImageListStar(){ | getImageListStar(){ | ||||
| this.loadingStar = true | this.loadingStar = true | ||||
| this.$axios.get('/explore/images/star',{ | this.$axios.get('/explore/images/star',{ | ||||
| @@ -715,8 +739,10 @@ export default { | |||||
| else{ | else{ | ||||
| this.getImageListPublic() | this.getImageListPublic() | ||||
| } | } | ||||
| }, | |||||
| beforeDestroy() { | |||||
| this.stopImageListCustomRefresh(); | |||||
| } | } | ||||
| }; | }; | ||||
| </script> | </script> | ||||
| @@ -225,6 +225,9 @@ export default { | |||||
| }, | }, | ||||
| }, | }, | ||||
| mounted() { | mounted() { | ||||
| if (document.getElementById("ai_image_name")) { | |||||
| this.imageAddress = document.getElementById("ai_image_name").value; | |||||
| } | |||||
| this.getImageListPublic(); | this.getImageListPublic(); | ||||
| if ( | if ( | ||||
| location.href.indexOf("benchmark") !== -1 || | location.href.indexOf("benchmark") !== -1 || | ||||
| @@ -498,6 +498,9 @@ export default { | |||||
| }, | }, | ||||
| }, | }, | ||||
| mounted() { | mounted() { | ||||
| if (document.getElementById("ai_image_name")) { | |||||
| this.imageAddress = document.getElementById("ai_image_name").value; | |||||
| } | |||||
| this.getImageListPublic(); | this.getImageListPublic(); | ||||
| if ( | if ( | ||||
| location.href.indexOf("train-job") !== -1 || | location.href.indexOf("train-job") !== -1 || | ||||
| @@ -1,23 +1,37 @@ | |||||
| export default async function initClipboard() { | export default async function initClipboard() { | ||||
| const els = document.querySelectorAll('.clipboard'); | |||||
| const els = document.querySelectorAll(".clipboard"); | |||||
| if (!els || !els.length) return; | if (!els || !els.length) return; | ||||
| const { default: ClipboardJS } = await import(/* webpackChunkName: "clipboard" */'clipboard'); | |||||
| const { default: ClipboardJS } = await import( | |||||
| /* webpackChunkName: "clipboard" */ "clipboard" | |||||
| ); | |||||
| const clipboard = new ClipboardJS(els); | const clipboard = new ClipboardJS(els); | ||||
| clipboard.on('success', (e) => { | |||||
| clipboard.on("success", (e) => { | |||||
| e.clearSelection(); | e.clearSelection(); | ||||
| $(`#${e.trigger.getAttribute('id')}`).popup('destroy'); | |||||
| e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-success')); | |||||
| $(`#${e.trigger.getAttribute('id')}`).popup('show'); | |||||
| e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-original')); | |||||
| $(`#${e.trigger.getAttribute("id")}`).popup("destroy"); | |||||
| e.trigger.setAttribute( | |||||
| "data-content", | |||||
| e.trigger.getAttribute("data-success") | |||||
| ); | |||||
| $(`#${e.trigger.getAttribute("id")}`).popup("show"); | |||||
| e.trigger.setAttribute( | |||||
| "data-content", | |||||
| e.trigger.getAttribute("data-original") | |||||
| ); | |||||
| }); | }); | ||||
| clipboard.on('error', (e) => { | |||||
| $(`#${e.trigger.getAttribute('id')}`).popup('destroy'); | |||||
| e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-error')); | |||||
| $(`#${e.trigger.getAttribute('id')}`).popup('show'); | |||||
| e.trigger.setAttribute('data-content', e.trigger.getAttribute('data-original')); | |||||
| clipboard.on("error", (e) => { | |||||
| $(`#${e.trigger.getAttribute("id")}`).popup("destroy"); | |||||
| e.trigger.setAttribute( | |||||
| "data-content", | |||||
| e.trigger.getAttribute("data-error") | |||||
| ); | |||||
| $(`#${e.trigger.getAttribute("id")}`).popup("show"); | |||||
| e.trigger.setAttribute( | |||||
| "data-content", | |||||
| e.trigger.getAttribute("data-original") | |||||
| ); | |||||
| }); | }); | ||||
| } | } | ||||
| @@ -2950,13 +2950,13 @@ $(document).ready(async () => { | |||||
| } | } | ||||
| const $cloneAddr = $("#clone_addr"); | const $cloneAddr = $("#clone_addr"); | ||||
| $cloneAddr.on("change", () => { | |||||
| $cloneAddr.on("input change", () => { | |||||
| const $repoName = $("#alias"); | const $repoName = $("#alias"); | ||||
| const $owner = $("#ownerDropdown div.text").attr("title"); | const $owner = $("#ownerDropdown div.text").attr("title"); | ||||
| const $urlAdd = | const $urlAdd = | ||||
| location.href.split("/")[0] + "//" + location.href.split("/")[2]; | location.href.split("/")[0] + "//" + location.href.split("/")[2]; | ||||
| if ($cloneAddr.val().length > 0 && $repoName.val().length === 0) { | |||||
| // Only modify if repo_name input is blank | |||||
| if ($cloneAddr.val().length > 0 /* && $repoName.val().length === 0 */) { | |||||
| // modify when clone address change | |||||
| const repoValue = $cloneAddr.val().match(/^(.*\/)?((.+?)(\.git)?)$/)[3]; | const repoValue = $cloneAddr.val().match(/^(.*\/)?((.+?)(\.git)?)$/)[3]; | ||||
| $repoName.val($cloneAddr.val().match(/^(.*\/)?((.+?)(\.git)?)$/)[3]); | $repoName.val($cloneAddr.val().match(/^(.*\/)?((.+?)(\.git)?)$/)[3]); | ||||
| $.get( | $.get( | ||||
| @@ -3873,6 +3873,10 @@ function initVueDataset() { | |||||
| MinioUploader, | MinioUploader, | ||||
| }, | }, | ||||
| mounted() { | mounted() { | ||||
| if (document.getElementById("fail_dataset_name")) { | |||||
| this.dataset_name = document.getElementById("fail_dataset_name").value; | |||||
| this.dataset_uuid = document.getElementById("fail_dataset_uuid").value; | |||||
| } | |||||
| this.getTypeList(); | this.getTypeList(); | ||||
| if (!!document.getElementById("dataset-repolink-init")) { | if (!!document.getElementById("dataset-repolink-init")) { | ||||
| @@ -140,27 +140,26 @@ | |||||
| border: 1px solid #ffffff; | border: 1px solid #ffffff; | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } | |||||
| } | } | ||||
| .item { | .item { | ||||
| border-bottom: 1px solid rgba(34,36,38,.15); | |||||
| border-bottom: 1px solid rgba(34, 36, 38, 0.15); | |||||
| .ui.buttons { | .ui.buttons { | ||||
| .button { | .button { | ||||
| box-shadow: none !important; | box-shadow: none !important; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| .ui.grid > .row { | .ui.grid > .row { | ||||
| align-items: center; | align-items: center; | ||||
| } | } | ||||
| .title { | .title { | ||||
| font-size: 16px; | font-size: 16px; | ||||
| font-weight: bold; | font-weight: bold; | ||||
| margin: 0 6px; | |||||
| margin: 0 6px; | |||||
| overflow: hidden; | overflow: hidden; | ||||
| padding-right: 15px; | padding-right: 15px; | ||||
| white-space: nowrap; | white-space: nowrap; | ||||
| @@ -195,7 +194,15 @@ | |||||
| .name { | .name { | ||||
| word-break: break-all; | word-break: break-all; | ||||
| } | } | ||||
| .dataset-title-a { | |||||
| flex: 1; | |||||
| overflow: hidden; | |||||
| text-overflow: ellipsis; | |||||
| min-width: 0; | |||||
| word-break: inherit !important; | |||||
| margin-right: 3rem; | |||||
| white-space: nowrap; | |||||
| } | |||||
| .metas { | .metas { | ||||
| color: #888888; | color: #888888; | ||||
| font-size: 14px; | font-size: 14px; | ||||
| @@ -222,7 +229,7 @@ | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| .panel_creator_reponam{ | |||||
| .panel_creator_reponam { | |||||
| display: inline-block; | display: inline-block; | ||||
| border-radius: 4px; | border-radius: 4px; | ||||
| padding: 4px; | padding: 4px; | ||||
| @@ -231,29 +238,28 @@ | |||||
| background-color: rgba(161, 220, 255, 0.2); | background-color: rgba(161, 220, 255, 0.2); | ||||
| color: #101010; | color: #101010; | ||||
| } | } | ||||
| .panel_dataset_name{ | |||||
| .panel_dataset_name { | |||||
| font-size: 15px; | font-size: 15px; | ||||
| color: #0366D6; | |||||
| color: #0366d6; | |||||
| text-align: center; | text-align: center; | ||||
| margin-left: 1rem; | margin-left: 1rem; | ||||
| } | } | ||||
| .panel_datset_desc{ | |||||
| .panel_datset_desc { | |||||
| white-space: nowrap; | white-space: nowrap; | ||||
| display: inline-block; | display: inline-block; | ||||
| overflow: hidden; | overflow: hidden; | ||||
| width: 90%; | width: 90%; | ||||
| text-overflow: ellipsis; | text-overflow: ellipsis; | ||||
| } | } | ||||
| .el-dialog__body{ | |||||
| padding-top:0 | |||||
| .el-dialog__body { | |||||
| padding-top: 0; | |||||
| } | } | ||||
| #dataset-base{ | |||||
| .active{ | |||||
| color: #0087f5!important; | |||||
| border: 1px solid #0087f5!important; | |||||
| #dataset-base { | |||||
| .active { | |||||
| color: #0087f5 !important; | |||||
| border: 1px solid #0087f5 !important; | |||||
| /* margin: -1px!important; */ | /* margin: -1px!important; */ | ||||
| background: #fff!important; | |||||
| background: #fff !important; | |||||
| } | } | ||||
| } | |||||
| } | |||||
| @@ -311,6 +311,7 @@ footer .column { | |||||
| } | } | ||||
| .FAILED, | .FAILED, | ||||
| .START_FAILED, | .START_FAILED, | ||||
| .DELETED, | |||||
| .CREATE_FAILED { | .CREATE_FAILED { | ||||
| display: inline-block; | display: inline-block; | ||||
| width: 18px; | width: 18px; | ||||