@@ -51,6 +51,7 @@ type Attachment struct { | |||
FileChunk *FileChunk `xorm:"-"` | |||
CanDel bool `xorm:"-"` | |||
Uploader *User `xorm:"-"` | |||
Md5 string `xorm:"-"` | |||
} | |||
type AttachmentUsername struct { | |||
@@ -1,6 +1,7 @@ | |||
package models | |||
import ( | |||
"code.gitea.io/gitea/modules/log" | |||
"errors" | |||
"fmt" | |||
"sort" | |||
@@ -62,19 +63,20 @@ func (datasets DatasetList) loadAttributes(e Engine) error { | |||
} | |||
set := make(map[int64]struct{}) | |||
userIdSet := make(map[int64]struct{}) | |||
datasetIDs := make([]int64, len(datasets)) | |||
for i := range datasets { | |||
set[datasets[i].UserID] = struct{}{} | |||
userIdSet[datasets[i].UserID] = struct{}{} | |||
set[datasets[i].RepoID] = struct{}{} | |||
datasetIDs[i] = datasets[i].ID | |||
} | |||
// Load owners. | |||
users := make(map[int64]*User, len(set)) | |||
users := make(map[int64]*User, len(userIdSet)) | |||
repos := make(map[int64]*Repository, len(set)) | |||
if err := e. | |||
Where("id > 0"). | |||
In("id", keysInt64(set)). | |||
In("id", keysInt64(userIdSet)). | |||
Find(&users); err != nil { | |||
return fmt.Errorf("find users: %v", err) | |||
} | |||
@@ -296,7 +298,13 @@ func getDatasetAttachments(e Engine, typeCloudBrain int, isSigned bool, user *Us | |||
if err != nil { | |||
return err | |||
} | |||
attachment.FileChunk = fileChunks[0] | |||
if len(fileChunks) > 0 { | |||
attachment.Md5 = fileChunks[0].Md5 | |||
} else { | |||
log.Error("has attachment record, but has no file_chunk record") | |||
attachment.Md5 = "no_record" | |||
} | |||
attachment.CanDel = CanDelAttachment(isSigned, user, attachment) | |||
sortedRels.Rel[currentIndex].Attachments = append(sortedRels.Rel[currentIndex].Attachments, attachment) | |||
} | |||
@@ -193,6 +193,7 @@ $def$ | |||
name=NEW.name, | |||
is_closed=NEW.is_closed, | |||
num_comments=NEW.num_comments, | |||
updated_unix=NEW.updated_unix, | |||
comment=(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment where issue_id=NEW.id) | |||
where id=NEW.id; | |||
return new; | |||
@@ -280,6 +280,7 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc | |||
RepoID: ctx.Repo.Repository.ID, | |||
JobID: jobResult.ID, | |||
JobName: jobName, | |||
FlavorCode: flavor, | |||
DisplayJobName: displayJobName, | |||
JobType: string(models.JobTypeDebug), | |||
Type: models.TypeCloudBrainTwo, | |||
@@ -40,6 +40,7 @@ var ( | |||
DisabledRepoUnits []string | |||
DefaultRepoUnits []string | |||
PrefixArchiveFiles bool | |||
RepoMaxSize int64 | |||
// Repository editor settings | |||
Editor struct { | |||
@@ -54,6 +55,7 @@ var ( | |||
AllowedTypes []string `delim:"|"` | |||
FileMaxSize int64 | |||
MaxFiles int | |||
TotalMaxSize int64 | |||
} `ini:"-"` | |||
// Repository local settings | |||
@@ -104,6 +106,7 @@ var ( | |||
DisabledRepoUnits: []string{}, | |||
DefaultRepoUnits: []string{}, | |||
PrefixArchiveFiles: true, | |||
RepoMaxSize: 1024, | |||
// Repository editor settings | |||
Editor: struct { | |||
@@ -121,12 +124,14 @@ var ( | |||
AllowedTypes []string `delim:"|"` | |||
FileMaxSize int64 | |||
MaxFiles int | |||
TotalMaxSize int64 | |||
}{ | |||
Enabled: true, | |||
TempPath: "data/tmp/uploads", | |||
AllowedTypes: []string{}, | |||
FileMaxSize: 3, | |||
MaxFiles: 5, | |||
FileMaxSize: 30, | |||
MaxFiles: 10, | |||
TotalMaxSize: 1024, | |||
}, | |||
// Repository local settings | |||
@@ -919,6 +919,10 @@ cloudbrain_helper=Use GPU/NPU resources to open notebooks, model training tasks, | |||
cloudbrain.exitinfo=Exit Information | |||
cloudbrain.platform=Platform | |||
cloudbrain.endtime=End Time | |||
cloudbrain.runinfo=Task Runtime Information | |||
cloudbrain.time.starttime=Start run time | |||
cloudbrain.time.endtime=End run time | |||
cloudbrain.datasetdownload=Dataset download url | |||
model_manager = Model | |||
model_noright=No right | |||
model_rename=Duplicate model name, please modify model name. | |||
@@ -1256,6 +1260,10 @@ editor.cannot_commit_to_protected_branch = Cannot commit to protected branch '%s | |||
editor.no_commit_to_branch = Unable to commit directly to branch because: | |||
editor.user_no_push_to_branch = User cannot push to branch | |||
editor.require_signed_commit = Branch requires a signed commit | |||
editor.repo_too_large = Repository can not exceed %d MB | |||
editor.repo_file_invalid = Upload files are invalid | |||
editor.upload_file_too_much = Can not upload more than %d files at a time | |||
commits.desc = Browse source code change history. | |||
commits.commits = Commits | |||
@@ -2863,6 +2871,8 @@ uploading = Uploading | |||
upload_complete = Uploading complete | |||
failed = Upload Failed | |||
enable_minio_support = Enable minio support to use the dataset service | |||
max_file_tooltips= Upload a maximum of ? files at a time, each file does not exceed ? MB. | |||
max_size_tooltips= You can only upload a maximum of ? files at a time. The upload limit has been reached, please do not add more files. | |||
[notification] | |||
notifications = Notifications | |||
@@ -966,6 +966,10 @@ cloudbrain.mirror_description = 镜像描述 | |||
cloudbrain.exitinfo=退出信息 | |||
cloudbrain.platform=平台 | |||
cloudbrain.endtime=结束时间 | |||
cloudbrain.runinfo=任务运行简况 | |||
cloudbrain.time.starttime=开始运行时间 | |||
cloudbrain.time.endtime=结束运行时间 | |||
cloudbrain.datasetdownload=数据集下载地址 | |||
record_begintime_get_err=无法获取统计开始时间。 | |||
parameter_is_wrong=输入参数错误,请检查输入参数。 | |||
total_count_get_error=查询总页数失败。 | |||
@@ -1263,6 +1267,9 @@ editor.cannot_commit_to_protected_branch=不可以提交到受保护的分支 '% | |||
editor.no_commit_to_branch=无法直接提交分支,因为: | |||
editor.user_no_push_to_branch=用户不能推送到分支 | |||
editor.require_signed_commit=分支需要签名提交 | |||
editor.repo_too_large = 代码仓总大小不能超过%dMB | |||
editor.repo_file_invalid = 提交的文件非法 | |||
editor.upload_file_too_much = 不能同时提交超过%d个文件 | |||
commits.desc=浏览代码修改历史 | |||
commits.commits=次代码提交 | |||
@@ -2869,6 +2876,8 @@ uploading=正在上传 | |||
upload_complete=上传完成 | |||
failed=上传失败 | |||
enable_minio_support=启用minio支持以使用数据集服务 | |||
max_file_tooltips=单次最多上传?个文件,每个文件不超过? MB。 | |||
max_size_tooltips=一次最多只能上传?个文件, 上传已达到上限,请勿再添加文件。 | |||
[notification] | |||
notifications=通知 | |||
@@ -346,6 +346,24 @@ func CloudBrainRestart(ctx *context.Context) { | |||
break | |||
} | |||
var hasSameResource bool | |||
if gpuInfos == nil { | |||
json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos) | |||
} | |||
for _, resourceType := range gpuInfos.GpuInfo { | |||
if resourceType.Queue == task.GpuQueue { | |||
hasSameResource = true | |||
continue | |||
} | |||
} | |||
if !hasSameResource { | |||
log.Error("has no same resource, can not restart", ctx.Data["MsgID"]) | |||
resultCode = "-1" | |||
errorMsg = "the job's version is too old and can not be restarted" | |||
break | |||
} | |||
count, err := models.GetCloudbrainCountByUserID(ctx.User.ID, string(models.JobTypeDebug)) | |||
if err != nil { | |||
log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) | |||
@@ -417,6 +435,18 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||
return | |||
} | |||
if cloudbrain.ResourceSpecs == nil { | |||
json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | |||
} | |||
for _, tmp := range cloudbrain.ResourceSpecs.ResourceSpec { | |||
if tmp.Id == task.ResourceSpecId { | |||
ctx.Data["GpuNum"] = tmp.GpuNum | |||
ctx.Data["CpuNum"] = tmp.CpuNum | |||
ctx.Data["MemMiB"] = tmp.MemMiB | |||
ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB | |||
} | |||
} | |||
if result != nil { | |||
jobRes, _ := models.ConvertToJobResultPayload(result.Payload) | |||
jobRes.Resource.Memory = strings.ReplaceAll(jobRes.Resource.Memory, "Mi", "MB") | |||
@@ -549,7 +579,7 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||
ctx.Data["code_path"] = cloudbrain.CodeMountPath | |||
ctx.Data["dataset_path"] = cloudbrain.DataSetMountPath | |||
ctx.Data["model_path"] = cloudbrain.ModelMountPath | |||
ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, task) | |||
ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task) | |||
ctx.HTML(200, tpName) | |||
} | |||
@@ -5,6 +5,7 @@ | |||
package repo | |||
import ( | |||
repo_service "code.gitea.io/gitea/services/repository" | |||
"encoding/json" | |||
"fmt" | |||
"io/ioutil" | |||
@@ -614,6 +615,19 @@ func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) { | |||
message += "\n\n" + form.CommitMessage | |||
} | |||
if err := repo_service.CheckPushSizeLimit4Web(ctx.Repo.Repository, form.Files); err != nil { | |||
if repo_service.IsRepoTooLargeErr(err) { | |||
ctx.RenderWithErr(ctx.Tr("repo.editor.repo_too_large", setting.Repository.RepoMaxSize), tplUploadFile, &form) | |||
} else if repo_service.IsUploadFileInvalidErr(err) { | |||
ctx.RenderWithErr(ctx.Tr("repo.editor.repo_file_invalid"), tplUploadFile, &form) | |||
} else if repo_service.IsUploadFileTooMuchErr(err) { | |||
ctx.RenderWithErr(ctx.Tr("repo.editor.upload_file_too_much", setting.Repository.Upload.MaxFiles), tplUploadFile, &form) | |||
} else { | |||
ctx.RenderWithErr(err.Error(), tplUploadFile, &form) | |||
} | |||
return | |||
} | |||
if err := repofiles.UploadRepoFiles(ctx.Repo.Repository, ctx.User, &repofiles.UploadRepoFileOptions{ | |||
LastCommitID: ctx.Repo.CommitID, | |||
OldBranch: oldBranchName, | |||
@@ -2,10 +2,9 @@ package repo | |||
import ( | |||
"archive/zip" | |||
"code.gitea.io/gitea/modules/notification" | |||
"code.gitea.io/gitea/modules/timeutil" | |||
"encoding/json" | |||
"errors" | |||
"fmt" | |||
"io" | |||
"io/ioutil" | |||
"net/http" | |||
@@ -16,6 +15,9 @@ import ( | |||
"time" | |||
"unicode/utf8" | |||
"code.gitea.io/gitea/modules/notification" | |||
"code.gitea.io/gitea/modules/timeutil" | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/auth" | |||
"code.gitea.io/gitea/modules/base" | |||
@@ -247,7 +249,7 @@ func NotebookShow(ctx *context.Context) { | |||
debugListType := ctx.Query("debugListType") | |||
var ID = ctx.Params(":id") | |||
task, err := models.GetCloudbrainByID(ID) | |||
task, err := models.GetCloudbrainByIDWithDeleted(ID) | |||
if err != nil { | |||
ctx.Data["error"] = err.Error() | |||
ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil) | |||
@@ -262,33 +264,64 @@ func NotebookShow(ctx *context.Context) { | |||
} | |||
if result != nil { | |||
task.Status = result.Status | |||
err = models.UpdateJob(task) | |||
if err != nil { | |||
ctx.Data["error"] = err.Error() | |||
ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil) | |||
return | |||
} | |||
if task.DeletedAt.IsZero() { //normal record | |||
if task.Status != result.Status { | |||
task.Status = result.Status | |||
err = models.UpdateJob(task) | |||
if err != nil { | |||
ctx.Data["error"] = err.Error() | |||
ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil) | |||
return | |||
} | |||
} | |||
} else { //deleted record | |||
result.CreateTime = time.Unix(int64(result.CreateAt/1000), 0).Format("2006-01-02 15:04:05") | |||
result.LatestUpdateTime = time.Unix(int64(result.UpdateAt/1000), 0).Format("2006-01-02 15:04:05") | |||
} | |||
} | |||
datasetDownloadLink := "-" | |||
datasetDownloadLink := "" | |||
if ctx.IsSigned { | |||
if task.Uuid != "" && task.UserID == ctx.User.ID { | |||
attachment, err := models.GetAttachmentByUUID(task.Uuid) | |||
if err == nil { | |||
task.DatasetName = attachment.Name | |||
datasetDownloadLink = attachment.S3DownloadURL() | |||
} | |||
} | |||
} | |||
user, err := models.GetUserByID(task.UserID) | |||
if err == nil { | |||
task.User = user | |||
} | |||
if modelarts.FlavorInfos == nil { | |||
json.Unmarshal([]byte(setting.FlavorInfos), &modelarts.FlavorInfos) | |||
} | |||
if modelarts.FlavorInfos != nil { | |||
ctx.Data["resource_spec"] = modelarts.FlavorInfos.FlavorInfo[0].Desc | |||
for _, f := range modelarts.FlavorInfos.FlavorInfo { | |||
if fmt.Sprint(f.Value) == task.FlavorCode { | |||
ctx.Data["resource_spec"] = f.Desc | |||
break | |||
} | |||
} | |||
} | |||
if task.TrainJobDuration == "" { | |||
if task.Duration == 0 { | |||
var duration int64 | |||
if task.Status == string(models.JobRunning) { | |||
duration = time.Now().Unix() - int64(task.CreatedUnix) | |||
} else { | |||
duration = int64(task.UpdatedUnix) - int64(task.CreatedUnix) | |||
} | |||
task.Duration = duration | |||
} | |||
task.TrainJobDuration = models.ConvertDurationToStr(task.Duration) | |||
} | |||
ctx.Data["duration"] = task.TrainJobDuration | |||
ctx.Data["datasetDownloadLink"] = datasetDownloadLink | |||
ctx.Data["task"] = task | |||
ctx.Data["ID"] = ID | |||
ctx.Data["jobName"] = task.JobName | |||
ctx.Data["result"] = result | |||
ctx.Data["debugListType"] = debugListType | |||
ctx.HTML(200, tplModelArtsNotebookShow) | |||
} | |||
@@ -1553,7 +1586,7 @@ func TrainJobShow(ctx *context.Context) { | |||
ctx.Data["displayJobName"] = VersionListTasks[0].DisplayJobName | |||
ctx.Data["version_list_task"] = VersionListTasks | |||
ctx.Data["version_list_count"] = VersionListCount | |||
ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, &VersionListTasks[0].Cloudbrain) | |||
ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, &VersionListTasks[0].Cloudbrain) | |||
ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow) | |||
} | |||
@@ -2184,7 +2217,7 @@ func InferenceJobShow(ctx *context.Context) { | |||
ctx.Data["jobName"] = task.JobName | |||
ctx.Data["displayJobName"] = task.DisplayJobName | |||
ctx.Data["task"] = task | |||
ctx.Data["canDownload"] = cloudbrain.CanDeleteJob(ctx, task) | |||
ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task) | |||
tempUids := []int64{} | |||
tempUids = append(tempUids, task.UserID) | |||
@@ -573,7 +573,8 @@ func trimFontHtml(text []rune) string { | |||
startRune := rune('<') | |||
endRune := rune('>') | |||
count := 0 | |||
for i := 0; i < len(text); i++ { | |||
i := 0 | |||
for ; i < len(text); i++ { | |||
if text[i] == startRune { //start < | |||
re := false | |||
j := i + 1 | |||
@@ -592,11 +593,14 @@ func trimFontHtml(text []rune) string { | |||
} else { | |||
return string(text[0:i]) | |||
} | |||
} | |||
} | |||
} | |||
return string(text) | |||
if count%2 == 1 { | |||
return string(text[0:i]) + "</font>" | |||
} else { | |||
return string(text[0:i]) | |||
} | |||
} | |||
func trimHrefHtml(result string) string { | |||
@@ -1125,7 +1129,7 @@ func makePrivateIssueOrPr(issues []*models.Issue, res *SearchRes, Key string, la | |||
record["num_comments"] = issue.NumComments | |||
record["is_closed"] = issue.IsClosed | |||
record["updated_unix"] = issue.UpdatedUnix | |||
record["updated_html"] = timeutil.TimeSinceUnix(repo.UpdatedUnix, language) | |||
record["updated_html"] = timeutil.TimeSinceUnix(issue.UpdatedUnix, language) | |||
res.Result = append(res.Result, record) | |||
} | |||
} | |||
@@ -8,6 +8,7 @@ import ( | |||
"fmt" | |||
"io/ioutil" | |||
"net/http" | |||
"os" | |||
"strings" | |||
"code.gitea.io/gitea/models" | |||
@@ -172,3 +173,137 @@ func RecommendFromPromote(url string) ([]string, error) { | |||
} | |||
return result, nil | |||
} | |||
func CheckPushSizeLimit4Web(repo *models.Repository, fileIds []string) error { | |||
if err := CheckRepoNumOnceLimit(len(fileIds)); err != nil { | |||
return err | |||
} | |||
totalSize, err := CountUploadFileSizeByIds(fileIds) | |||
if err != nil { | |||
return UploadFileInvalidErr{} | |||
} | |||
if err := CheckRepoTotalSizeLimit(repo, totalSize); err != nil { | |||
return err | |||
} | |||
return nil | |||
} | |||
func CheckPushSizeLimit4Http(repo *models.Repository, uploadFileSize int64) error { | |||
if err := CheckRepoOnceTotalSizeLimit(uploadFileSize); err != nil { | |||
return err | |||
} | |||
if err := CheckRepoTotalSizeLimit(repo, uploadFileSize); err != nil { | |||
return err | |||
} | |||
return nil | |||
} | |||
func CheckRepoTotalSizeLimit(repo *models.Repository, uploadFileSize int64) error { | |||
if repo.Size+uploadFileSize > setting.Repository.RepoMaxSize*1024*1024 { | |||
return RepoTooLargeErr{} | |||
} | |||
return nil | |||
} | |||
func CheckRepoOnceTotalSizeLimit(uploadFileSize int64) error { | |||
if uploadFileSize > setting.Repository.Upload.TotalMaxSize*1024*1024 { | |||
return UploadFileTooLargeErr{} | |||
} | |||
return nil | |||
} | |||
func CheckRepoNumOnceLimit(uploadFileNum int) error { | |||
if uploadFileNum > setting.Repository.Upload.MaxFiles { | |||
return UploadFileTooMuchErr{} | |||
} | |||
return nil | |||
} | |||
func CountUploadFileSizeByIds(fileIds []string) (int64, error) { | |||
if len(fileIds) == 0 { | |||
return 0, nil | |||
} | |||
uploads, err := models.GetUploadsByUUIDs(fileIds) | |||
if err != nil { | |||
return 0, fmt.Errorf("CountUploadFileSizeByIds error [uuids: %v]: %v", fileIds, err) | |||
} | |||
var totalSize int64 | |||
for _, upload := range uploads { | |||
size, err := GetUploadFileSize(upload) | |||
if err != nil { | |||
return 0, err | |||
} | |||
totalSize += size | |||
} | |||
return totalSize, nil | |||
} | |||
func GetUploadFileSize(upload *models.Upload) (int64, error) { | |||
info, err := os.Lstat(upload.LocalPath()) | |||
if err != nil { | |||
return 0, err | |||
} | |||
return info.Size(), nil | |||
} | |||
type RepoTooLargeErr struct { | |||
} | |||
func (RepoTooLargeErr) Error() string { | |||
return fmt.Sprintf("Repository can not exceed %d MB. Please remove some unnecessary files and try again", setting.Repository.RepoMaxSize) | |||
} | |||
func IsRepoTooLargeErr(err error) bool { | |||
_, ok := err.(RepoTooLargeErr) | |||
return ok | |||
} | |||
type UploadFileTooLargeErr struct { | |||
} | |||
func (UploadFileTooLargeErr) Error() string { | |||
return fmt.Sprintf("Upload files can not exceed %d MB at a time", setting.Repository.Upload.TotalMaxSize) | |||
} | |||
func IsUploadFileTooLargeErr(err error) bool { | |||
_, ok := err.(UploadFileTooLargeErr) | |||
return ok | |||
} | |||
type RepoFileTooLargeErr struct { | |||
} | |||
func (RepoFileTooLargeErr) Error() string { | |||
return "repository file is too large" | |||
} | |||
func IsRepoFileTooLargeErr(err error) bool { | |||
_, ok := err.(RepoFileTooLargeErr) | |||
return ok | |||
} | |||
type UploadFileTooMuchErr struct { | |||
} | |||
func (UploadFileTooMuchErr) Error() string { | |||
return "upload files are too lmuch" | |||
} | |||
func IsUploadFileTooMuchErr(err error) bool { | |||
_, ok := err.(UploadFileTooMuchErr) | |||
return ok | |||
} | |||
type UploadFileInvalidErr struct { | |||
} | |||
func (UploadFileInvalidErr) Error() string { | |||
return "upload files are invalid" | |||
} | |||
func IsUploadFileInvalidErr(err error) bool { | |||
_, ok := err.(UploadFileInvalidErr) | |||
return ok | |||
} |
@@ -155,7 +155,7 @@ | |||
</a> | |||
</form> | |||
{{else}} | |||
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class="ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED"}}disabled {{else}} blue {{end}}button" data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/train-job{{else}}/modelarts/{{if eq .JobType "INFERENCE"}}inference-job{{else}}train-job{{end}}{{end}}" data-jobid="{{$JobID}}" data-version="{{.VersionName}}" > | |||
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class="ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED"}}disabled {{else}} blue {{end}}button" data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/train-job{{else}}/modelarts/{{if eq .JobType "INFERENCE"}}inference-job{{else}}train-job{{end}}{{end}}" data-jobid="{{$JobID}}" data-version="{{.VersionName}}" > | |||
{{$.i18n.Tr "repo.stop"}} | |||
</a> | |||
{{end}} | |||
@@ -135,4 +135,4 @@ | |||
</el-dialog> | |||
</div> | |||
</div> |
@@ -0,0 +1,134 @@ | |||
<div class="dataset-repolink" id="dataset-repolink-init" style="display: none;" data-repolink="{{.RepoLink}}" data-cloudranin-type="{{.cloudbraintype}}"></div> | |||
<div class="inline required unite min_title field" id="dataset-base" style="margin-bottom: 0 !important;"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "dataset.dataset"}}</label> | |||
<input type="hidden" name="attachment" :value="dataset_uuid"> | |||
<input class="disabled" type="text" :value="dataset_name" required onfocus="this.blur();" style="width: 35.5%;"> | |||
<el-button type="text" @click="dialogVisible = true" icon="el-icon-plus" style="color: #0366d6;"> {{.i18n.Tr "dataset.select_dataset"}}</el-button> | |||
<el-dialog | |||
title="{{.i18n.Tr "dataset.select_dataset"}}" | |||
:visible.sync="dialogVisible" | |||
width="50%" | |||
> | |||
<div class="ui icon input" style="z-index: 9999;position: absolute;right: 50px;height:30px;"> | |||
<i class="search icon" style="cursor: pointer;pointer-events:auto" @click="searchDataset()"></i> | |||
<input type="text" placeholder="{{.i18n.Tr "dataset.search_dataset"}}" v-model="searchDataItem" @keyup.enter="searchDataset()"> | |||
</div> | |||
<el-tabs v-model="activeName" @tab-click="handleClick('{{.RepoLink}}',activeName,{{.cloudbraintype}})"> | |||
<el-tab-pane label="{{.i18n.Tr "dataset.current_project"}}" name="first"> | |||
<div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" v-for="(dataset,index) in currentRepoDataset" :key="index"> | |||
<div style="width: 90%;"> | |||
<div style="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias} </span><span class="panel_dataset_name">${dataset.Name} </span></div> | |||
<div style="margin-top: 8px;display: flex;"> | |||
<a :title="dataset.UserName" style="cursor: default;"> | |||
<img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> | |||
</a> | |||
<span class="panel_datset_desc">${dataset.Description}</span> | |||
</div> | |||
</div> | |||
<div> | |||
<button v-if="dataset.DecompressState===1" class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">{{.i18n.Tr "dataset.use"}}</button> | |||
<span v-if="dataset.DecompressState===2" style="display: flex;align-items: center;"> | |||
<i class="CREATING"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;" data-tooltip="{{$.i18n.Tr "dataset.unzip_tooltips"}}" data-inverted="" data-variation="mini" data-position="left center">解压中</span> | |||
</span> | |||
<span v-if="dataset.DecompressState===3" style="display: flex;align-items: center;"> | |||
<i class="FAILED"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color:red;" data-tooltip="{{$.i18n.Tr "dataset.zip_failed"}}" data-inverted="" data-variation="mini" data-position="left center">解压失败</span> | |||
</span> | |||
</div> | |||
</div> | |||
</el-tab-pane> | |||
<el-tab-pane label="{{.i18n.Tr "dataset.owner_dataset"}}" name="second"> | |||
<div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" v-for="(dataset,index) in myDataset" :key="index"> | |||
<div style="width: 90%;"> | |||
<div style="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias}</span><span class="panel_dataset_name">${dataset.Name}</span></div> | |||
<div style="margin-top: 8px;display: flex;"> | |||
<a :title="dataset.UserName" style="cursor: default;"> | |||
<img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> | |||
</a> | |||
<span class="panel_datset_desc">${dataset.Description}</span> | |||
</div> | |||
</div> | |||
<div> | |||
<button v-if="dataset.DecompressState===1" class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">{{.i18n.Tr "dataset.use"}}</button> | |||
<span v-if="dataset.DecompressState===2" style="display: flex;align-items: center;"> | |||
<i class="CREATING"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;" data-tooltip="{{$.i18n.Tr "dataset.unzip_tooltips"}}" data-inverted="" data-variation="mini" data-position="left center">解压中</span> | |||
</span> | |||
<span v-if="dataset.DecompressState===3" style="display: flex;align-items: center;"> | |||
<i class="FAILED"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color:red;" data-tooltip="{{$.i18n.Tr "dataset.zip_failed"}}" data-inverted="" data-variation="mini" data-position="left center">解压失败</span> | |||
</span> | |||
</div> | |||
</div> | |||
</el-tab-pane> | |||
<el-tab-pane label="{{.i18n.Tr "dataset.public_dataset"}}" name="third"> | |||
<div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" v-for="(dataset,index) in publicDataset" :key="index"> | |||
<div style="width: 90%;"> | |||
<div style="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias}</span><span class="panel_dataset_name">${dataset.Name}</span></div> | |||
<div style="margin-top: 8px;display: flex;"> | |||
<a :title="dataset.UserName" style="cursor: default;"> | |||
<img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> | |||
</a> | |||
<span class="panel_datset_desc">${dataset.Description}</span> | |||
</div> | |||
</div> | |||
<div> | |||
<button v-if="dataset.DecompressState===1" class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">{{.i18n.Tr "dataset.use"}}</button> | |||
<span v-if="dataset.DecompressState===2" style="display: flex;align-items: center;"> | |||
<i class="CREATING"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;" data-tooltip="{{$.i18n.Tr "dataset.unzip_tooltips"}}" data-inverted="" data-variation="mini" data-position="left center">解压中</span> | |||
</span> | |||
<span v-if="dataset.DecompressState===3" style="display: flex;align-items: center;"> | |||
<i class="FAILED"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color:red;" data-tooltip="{{$.i18n.Tr "dataset.zip_failed"}}" data-inverted="" data-variation="mini" data-position="left center">解压失败</span> | |||
</span> | |||
</div> | |||
</div> | |||
</el-tab-pane> | |||
<el-tab-pane label="{{.i18n.Tr "dataset.I_liked"}}" name="fourth"> | |||
<div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" v-for="(dataset,index) in myFavoriteDataset" :key="index"> | |||
<div style="width: 90%;"> | |||
<div style="display: flex;align-items: center;"><span class="panel_creator_reponam">${dataset.Repo.OwnerName}/${dataset.Repo.Alias}</span><span class="panel_dataset_name">${dataset.Name}</span></div> | |||
<div style="margin-top: 8px;display: flex;"> | |||
<a :title="dataset.UserName" style="cursor: default;"> | |||
<img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="dataset.RelAvatarLink"> | |||
</a> | |||
<span class="panel_datset_desc">${dataset.Description}</span> | |||
</div> | |||
</div> | |||
<div> | |||
<button v-if="dataset.DecompressState===1" class="ui primary basic button mini" @click.stop.prevent="selectDataset(dataset.UUID,dataset.Name)">{{.i18n.Tr "dataset.use"}}</button> | |||
<span v-if="dataset.DecompressState===2" style="display: flex;align-items: center;"> | |||
<i class="CREATING"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;" data-tooltip="{{$.i18n.Tr "dataset.unzip_tooltips"}}" data-inverted="" data-variation="mini" data-position="left center">解压中</span> | |||
</span> | |||
<span v-if="dataset.DecompressState===3" style="display: flex;align-items: center;"> | |||
<i class="FAILED"></i> | |||
<span style="margin-left: 0.4em;font-size: 12px;color:red;" data-tooltip="{{$.i18n.Tr "dataset.zip_failed"}}" data-inverted="" data-variation="mini" data-position="left center">解压失败</span> | |||
</span> | |||
</div> | |||
</div> | |||
</el-tab-pane> | |||
</el-tabs> | |||
<div class="center"> | |||
<el-pagination | |||
background | |||
@current-change="handleCurrentChange" | |||
:current-page="page" | |||
:page-size="5" | |||
layout="total,prev, pager, next" | |||
:total="totalnums"> | |||
</el-pagination> | |||
</div> | |||
</el-dialog> | |||
</div> |
@@ -121,10 +121,10 @@ | |||
<i class="dropdown icon"></i> | |||
</span> | |||
<div class="menu"> | |||
<a class="{{if eq .SortType "newest"}}active{{end}} item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.latest"}}</a> | |||
<a class="{{if eq .SortType "oldest"}}active{{end}} item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.oldest"}}</a> | |||
<a class="{{if eq .SortType "recentupdate"}}active{{end}} item" href="{{$.Link}}?sort=recentupdate&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.recentupdate"}}</a> | |||
<a class="{{if eq .SortType "leastupdate"}}active{{end}} item" href="{{$.Link}}?sort=leastupdate&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.leastupdate"}}</a> | |||
<a class="{{if eq .SortType "newest"}}active{{end}} item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}">{{.i18n.Tr "repo.issues.filter_sort.latest"}}</a> | |||
<a class="{{if eq .SortType "oldest"}}active{{end}} item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}">{{.i18n.Tr "repo.issues.filter_sort.oldest"}}</a> | |||
<a class="{{if eq .SortType "recentupdate"}}active{{end}} item" href="{{$.Link}}?sort=recentupdate&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}">{{.i18n.Tr "repo.issues.filter_sort.recentupdate"}}</a> | |||
<a class="{{if eq .SortType "leastupdate"}}active{{end}} item" href="{{$.Link}}?sort=leastupdate&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{$.License}}">{{.i18n.Tr "repo.issues.filter_sort.leastupdate"}}</a> | |||
<!-- <a class="{{if eq .SortType "downloadtimes"}}active{{end}} item" href="{{$.Link}}?sort=downloadtimes&q={{$.Keyword}}&tab={{$.TabName}}">{{.i18n.Tr "repo.issues.filter_sort.downloadtimes"}}</a> --> | |||
</div> | |||
</div> | |||
@@ -184,9 +184,15 @@ | |||
</div> | |||
<div class="extra content" style="border-top: none !important;"> | |||
<div style="display: flex;align-items: center;"> | |||
{{if eq .UserID 0}} | |||
<a href="{{AppSubUrl}}/{{.Repo.OwnerName}}" title="{{.Repo.OwnerName}}"> | |||
<img class="ui avatar image" style="width: 22px;height:22px;" src="/user/avatar/{{.Repo.OwnerName}}/-1"> | |||
</a> | |||
{{else}} | |||
<a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"> | |||
<img class="ui avatar image" style="width: 22px;height:22px;" src="/user/avatar/{{.User.Name}}/-1"> | |||
</a> | |||
{{end}} | |||
<span style="color: #999999;font-size: 14px;;">创建于:{{TimeSinceUnix1 .CreatedUnix}}</span> | |||
</div> | |||
</div> | |||
@@ -215,4 +221,4 @@ | |||
</div> | |||
</div> | |||
</div> | |||
{{template "base/footer" .}} | |||
{{template "base/footer" .}} |
@@ -42,18 +42,15 @@ | |||
.active{ | |||
color:#0366D6 !important; | |||
} | |||
.mleft{ | |||
margin-left: 30% !important; | |||
} | |||
.mbom{ | |||
margin-bottom: 10px !important; | |||
} | |||
</style> | |||
<div class="row"> | |||
<div class="ui secondary pointing tabular top attached borderless menu navbar mbom"> | |||
<div class="ui secondary tiny pointing borderless menu center aligned grid mbom"> | |||
{{with .Org}} | |||
<a class="{{if $.PageIsOrgHome}}active{{end}} item mleft" href="{{.HomeLink}}"> | |||
<a class="{{if $.PageIsOrgHome}}active{{end}} item" href="{{.HomeLink}}"> | |||
{{svg "octicon-home" 16}} {{$.i18n.Tr "org.home"}} | |||
</a> | |||
{{end}} | |||
@@ -83,47 +83,36 @@ | |||
{{ range .tags}} | |||
{{if eq .TagName "精选项目"}} | |||
<div class="ui three cards" style="margin-bottom: 10px;"> | |||
<div class="ui three stackable cards" style="margin-bottom: 10px;"> | |||
{{ range .RepoList}} | |||
<div class="card" > | |||
<div class="ui raised card"> | |||
<div class="extra full_height cor" > | |||
<div class=" header header_card omit" > | |||
<a class="header_card image poping up " href="{{.Link}}" data-content="{{if .Alias}}{{.Alias}}{{else}}{{.Name}}{{end}}" data-position="top left" data-variation="tiny inverted">{{if .Alias}}{{.Alias}}{{else}}{{.Name}}{{end}}</a> | |||
<div class="content" style="padding-bottom: 0;"> | |||
<div class="header" > | |||
<a href="{{.Link}}">{{if .Alias}}{{.Alias}}{{else}}{{.Name}}{{end}}</a> | |||
</div> | |||
<div class='content descript_height nowrap-2'> | |||
<div class="description"> | |||
<p class="nowrap-2"> | |||
{{.Description}} | |||
</div> | |||
<div class="content " > | |||
</p> | |||
{{if .Topics }} | |||
<div class=" tags " style="position: relative;"> | |||
{{range .Topics}} | |||
{{if ne . "" }}<a style="max-width:100%;display:inline-flex;" href="{{AppSubUrl}}/explore/repos?q={{.}}&topic={{$.Topic}}" ><span class="ui small label topic omit" >{{.}}</span></a>{{end}} | |||
{{end}} | |||
</div> | |||
{{end}} | |||
<p> | |||
{{range .Topics}} | |||
{{if ne . "" }}<a href="{{AppSubUrl}}/explore/repos?q={{.}}&topic={{$.Topic}}" class="ui small label topic omit" >{{.}}</a>{{end}} | |||
{{end}} | |||
</p> | |||
{{end}} | |||
</div> | |||
</div> | |||
<div class=" extra " style="color:#888888;border-top: none !important;padding-top: 0"> | |||
<div class="ui mini right compact marg" > | |||
<a class="item marg "> | |||
{{svg "octicon-eye" 16}} {{.NumWatches}} | |||
</a> | |||
<a class="item marg"> | |||
{{svg "octicon-star" 16}} {{.NumStars}} | |||
</a> | |||
<a class="item marg"> | |||
{{svg "octicon-git-branch" 16}} {{.NumForks}} | |||
</a> | |||
</div> | |||
<div class="extra content"> | |||
<span class="right floated date"> | |||
{{svg "octicon-eye" 16}} {{.NumWatches}}     | |||
{{svg "octicon-star" 16}} {{.NumStars}}     | |||
{{svg "octicon-git-branch" 16}} {{.NumForks}} | |||
</span> | |||
</div> | |||
</div> | |||
{{end}} | |||
</div> | |||
@@ -56,7 +56,7 @@ | |||
margin:10px 5px ; | |||
} | |||
.tab_2_content { | |||
min-height: 560px; | |||
min-height: 380px; | |||
margin-left: 10px; | |||
} | |||
.ac-grid { | |||
@@ -167,6 +167,8 @@ td, th { | |||
padding-top: 0.5rem ; | |||
} | |||
</style> | |||
<div id="mask"> | |||
<div id="loadingPage"> | |||
<div class="rect1"></div> | |||
@@ -198,7 +200,7 @@ td, th { | |||
<div class="{{if eq $k 0}}active{{end}} title padding0"> | |||
<div class="according-panel-heading"> | |||
<div class="accordion-panel-title"> | |||
<i class="dropdown icon"></i> | |||
<!--<i class="dropdown icon"></i> --> | |||
<span class="accordion-panel-title-content"> | |||
<span> | |||
<div class="ac-display-inblock title_text acc-margin-bottom"> | |||
@@ -226,6 +228,7 @@ td, th { | |||
<div class="content-pad"> | |||
<div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | |||
<a class="active item" data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
<a class="item" data-tab="second{{$k}}" onclick="javascript:parseLog()">{{$.i18n.Tr "repo.cloudbrain.runinfo"}}</a> | |||
</div> | |||
<div class="ui tab active" data-tab="first{{$k}}"> | |||
<div style="padding-top: 10px;"> | |||
@@ -255,109 +258,72 @@ td, th { | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||
</td> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.cloudbrain_creator"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
<span style="font-size: 12px;" class=""> | |||
{{if not (eq .StartTime 0)}} | |||
{{TimeSinceUnix1 .StartTime}} | |||
{{else}} | |||
{{TimeSinceUnix1 .CreatedUnix}} | |||
{{end}} | |||
</span> | |||
</div> | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
{{.User.Name}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-duration"> | |||
{{$.duration}} | |||
</div> | |||
</td> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.computing_resources"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-computeresource"> | |||
{{.ComputeResource}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "cloudbrain.mirror"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
{{.Image}} | |||
</div> | |||
</td> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "cloudbrain.task_type"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-computeresource"> | |||
{{.JobType}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "cloudbrain.dataset_storage_path"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="dataset_storage_path"> | |||
{{$.dataset_path}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "cloudbrain.code_storage_path"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="code_storage_path"> | |||
{{$.code_path}} | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<div class="ac-grid-col"> | |||
<table class="ti-form"> | |||
<tbody class="ti-text-form"> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.cloudbrain.platform"}} | |||
{{$.i18n.Tr "cloudbrain.gpu_type"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{$.result.Platform}} | |||
{{$.resource_type}} | |||
</div> | |||
</td> | |||
</tr> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
ExitCode | |||
{{$.i18n.Tr "repo.cloudbrain.time.starttime"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{$.result.JobStatus.AppExitCode}} | |||
<div class="text-span text-span-w" id="{{.VersionName}}-startTime"> | |||
{{if not (eq .StartTime 0)}} | |||
{{TimeSinceUnix1 .StartTime}} | |||
{{else}} | |||
-- | |||
{{end}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.cloudbrain.endtime"}} | |||
{{$.i18n.Tr "repo.cloudbrain.time.endtime"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-BenchmarkTypeName"> | |||
{{if not (eq .StartTime 0)}} | |||
<div class="text-span text-span-w" id="{{.VersionName}}-EndTime"> | |||
{{if not (eq .EndTime 0)}} | |||
{{TimeSinceUnix1 .EndTime}} | |||
{{else}} | |||
-- | |||
@@ -365,6 +331,24 @@ td, th { | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<div class="ac-grid-col"> | |||
<table class="ti-form"> | |||
<tbody class="ti-text-form"> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "cloudbrain.mirror"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
{{.Image}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.dataset"}} | |||
@@ -376,9 +360,7 @@ td, th { | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
@@ -386,19 +368,18 @@ td, th { | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{$.resource_spec}} | |||
{{$.i18n.Tr "cloudbrain.gpu_num"}}:{{$.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{$.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{$.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{$.ShareMemMiB}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.cloudbrain_creator"}} | |||
{{$.i18n.Tr "cloudbrain.dataset_storage_path"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
{{.User.Name}} | |||
<div class="text-span text-span-w" id="dataset_storage_path"> | |||
{{$.dataset_path}} | |||
</div> | |||
</td> | |||
</tr> | |||
@@ -413,26 +394,53 @@ td, th { | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "cloudbrain.code_storage_path"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="code_storage_path"> | |||
{{$.code_path}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-duration"> | |||
{{$.duration}} | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
<div class="ac-grid ac-grid-col2"> | |||
<div class="ac-grid-col"> | |||
<span class="ti-text-form-label">{{$.i18n.Tr "repo.cloudbrain.exitinfo"}}</span> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="ui tab" data-tab="second{{$k}}"> | |||
<div> | |||
<div class="ui message message{{.VersionName}}" style="display: none;"> | |||
<div id="header"></div> | |||
</div> | |||
<div class="ui attached log" id="log{{.VersionName}}" style="height: 390px !important; overflow: auto;"> | |||
<input type="hidden" id="json_value" value="{{$.result.JobStatus.AppExitDiagnostics}}"> | |||
<span id="info_display" class="info_text"> | |||
</div> | |||
</div> | |||
<div class="ac-grid-col"> | |||
<span class="info_text"> | |||
{{$.result.JobStatus.AppExitDiagnostics}} | |||
</span> | |||
</div> | |||
</span> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
@@ -466,7 +474,6 @@ td, th { | |||
<script> | |||
$('.menu .item').tab() | |||
$(document).ready(function(){ | |||
$('.ui.accordion').accordion({selector:{trigger:'.icon'}}); | |||
}); | |||
@@ -474,28 +481,31 @@ td, th { | |||
$('.secondary.menu .item').tab(); | |||
}); | |||
let userName | |||
let repoPath | |||
let jobName | |||
$(document).ready(function(){ | |||
let url = window.location.href; | |||
let urlArr = url.split('/') | |||
userName = urlArr.slice(-5)[0] | |||
repoPath = urlArr.slice(-4)[0] | |||
jobName = urlArr.slice(-1)[0] | |||
}) | |||
function loadLog(version_name){ | |||
document.getElementById("mask").style.display = "block" | |||
$.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/${jobName}/log?version_name=${version_name}&lines=50&order=asc`, (data) => { | |||
$('input[name=end_line]').val(data.EndLine) | |||
$('input[name=start_line]').val(data.StartLine) | |||
$(`#log_file${version_name}`).text(data.Content) | |||
document.getElementById("mask").style.display = "none" | |||
}).fail(function(err) { | |||
console.log(err); | |||
document.getElementById("mask").style.display = "none" | |||
}); | |||
function parseLog(){ | |||
let jsonValue = document.getElementById("json_value").value; | |||
let jsonObj = JSON.parse(jsonValue); | |||
let podRoleName = jsonObj["podRoleName"]; | |||
let html = ""; | |||
if (podRoleName != null){ | |||
let task0 = podRoleName["task1-0"]; | |||
let podEvents = jsonObj["podEvents"]; | |||
let podEventArray = podEvents[task0]; | |||
if(podEventArray != null){ | |||
for(var i=0; i < podEventArray.length;i++){ | |||
html +="<p><b>[" +podEventArray[i]["reason"] + "]</b></p>"; | |||
html +="<p>" +podEventArray[i]["message"] + "</p>"; | |||
html +="<p>" +podEventArray[i]["action"] + "</p>"; | |||
} | |||
} | |||
let extras= jsonObj["extras"]; | |||
if(extras != null){ | |||
for(var i=0; i < extras.length;i++){ | |||
html +="<p><b>[" +extras[i]["reason"] + "]</b></p>"; | |||
html +="<p>" +extras[i]["message"] + "</p>"; | |||
html +="<p>" +extras[i]["action"] + "</p>"; | |||
} | |||
} | |||
} | |||
</script> | |||
document.getElementById("info_display").innerHTML=html; | |||
} | |||
</script> |
@@ -169,9 +169,9 @@ | |||
<div class="inline unite min_title field required"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||
{{if .bootFile}} | |||
<input style="width: 33.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||
<input style="width: 35.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||
{{else}} | |||
<input style="width: 33.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | |||
<input style="width: 35.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | |||
{{end}} | |||
<span> | |||
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | |||
@@ -179,17 +179,9 @@ | |||
<a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU" target="_blank">查看样例</a> | |||
</div> | |||
<div class="required unite min_title inline field" style="position: relative;"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.dataset"}}</label> | |||
<select id="cloudbrain_dataset" class="ui search dropdown width80" placeholder="选择数据集" style='width:385px' name="attachment" required> | |||
{{range .attachments}} | |||
<option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | |||
{{end}} | |||
</select> | |||
<span class="tooltips">训练脚本存储在/code中,数据集存储在/dataset中,训练输出请存储在/model中以供后续下载。</span> | |||
</div> | |||
{{template "custom/select_dataset_train" .}} | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">训练脚本存储在/code中,数据集存储在/dataset中,训练输出请存储在/model中以供后续下载。</span> | |||
<div class="inline unite min_title field"> | |||
<label 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> | |||
@@ -199,7 +199,7 @@ | |||
</div> | |||
</div> | |||
{{range $k, $v :=.Attachments}} | |||
<div class="ui grid stackable item" id="{{.FileChunk.UUID}}"> | |||
<div class="ui grid stackable item" id="{{.UUID}}"> | |||
<div class="row"> | |||
<!-- 数据集名称 --> | |||
@@ -266,8 +266,8 @@ | |||
<a class="ui basic blue button" href="datasets/dirs/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.directory"}}'>{{$.i18n.Tr "preview"}}</a> | |||
{{end}} | |||
{{if and (.CanDel) (not $.Repository.IsPrivate)}} | |||
<span class="ui basic blue button" style="color: #13c28d !important;" @click="setPrivate('{{.FileChunk.UUID}}',false,{{$k}})" v-if="privates[{{$k}}]">{{$.i18n.Tr "dataset.set_public"}}</span> | |||
<span class="ui basic blue button" style="color: #fa8c16 !important;" @click="setPrivate('{{.FileChunk.UUID}}',true,{{$k}})" v-else="privates[{{$k}}]">{{$.i18n.Tr "dataset.set_private"}}</span> | |||
<span class="ui basic blue button" style="color: #13c28d !important;" @click="setPrivate('{{.UUID}}',false,{{$k}})" v-if="privates[{{$k}}]">{{$.i18n.Tr "dataset.set_public"}}</span> | |||
<span class="ui basic blue button" style="color: #fa8c16 !important;" @click="setPrivate('{{.UUID}}',true,{{$k}})" v-else="privates[{{$k}}]">{{$.i18n.Tr "dataset.set_private"}}</span> | |||
{{end}} | |||
<!-- {{if $.CanRead}} | |||
<a class="ui basic blue button" href="datasets/label/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.create_label_task"}}'>标注</a> | |||
@@ -281,13 +281,13 @@ | |||
</span> | |||
<el-dropdown-menu slot="dropdown"> | |||
<el-dropdown-item class="clipboard" data-clipboard-text="{{.DownloadURL}}" data-clipboard-action="copy">{{$.i18n.Tr "dataset.copy_url"}}</el-dropdown-item> | |||
<el-dropdown-item class="clipboard" data-clipboard-text="{{.FileChunk.Md5}}" data-clipboard-action="copy">{{$.i18n.Tr "dataset.copy_md5"}}</el-dropdown-item> | |||
<el-dropdown-item class="clipboard" data-clipboard-text="{{.Md5}}" data-clipboard-action="copy">{{$.i18n.Tr "dataset.copy_md5"}}</el-dropdown-item> | |||
{{if and ($.CanWrite) (eq .DecompressState 1) }} | |||
<el-dropdown-item @click.native="gotoAnnotate('{{$.RepoLink}}','{{.UUID}}',{{.Type}})">{{$.i18n.Tr "dataset.annotation"}}</el-dropdown-item> | |||
{{end}} | |||
{{if .CanDel}} | |||
<el-dropdown-item @click.native="gotoDatasetEidt('{{$.RepoLink}}',{{.ID}})">{{$.i18n.Tr "dataset.modify_description"}}</el-dropdown-item> | |||
<el-dropdown-item style="color: red;" @click.native="delDataset('{{.FileChunk.UUID}}')">{{$.i18n.Tr "dataset.delete"}}</el-dropdown-item> | |||
<el-dropdown-item style="color: red;" @click.native="delDataset('{{.UUID}}')">{{$.i18n.Tr "dataset.delete"}}</el-dropdown-item> | |||
{{end}} | |||
</el-dropdown-menu> | |||
</el-dropdown> | |||
@@ -27,10 +27,10 @@ | |||
</div> | |||
<div class="field"> | |||
<div class="files"></div> | |||
<div class="ui dropzone" id="dropzone" data-upload-url="{{.RepoLink}}/upload-file" data-remove-url="{{.RepoLink}}/upload-remove" data-csrf="{{.CsrfToken}}" data-accepts="{{.UploadAllowedTypes}}" data-max-file="{{.UploadMaxFiles}}" data-max-size="{{.UploadMaxSize}}" data-default-message="{{.i18n.Tr "dropzone.default_message"}}" data-invalid-input-type="{{.i18n.Tr "dropzone.invalid_input_type"}}" data-file-too-big="{{.i18n.Tr "dropzone.file_too_big"}}" data-remove-file="{{.i18n.Tr "dropzone.remove_file"}}"></div> | |||
<div class="ui dropzone" id="dropzone" data-upload-url="{{.RepoLink}}/upload-file" data-remove-url="{{.RepoLink}}/upload-remove" data-csrf="{{.CsrfToken}}" data-accepts="{{.UploadAllowedTypes}}" data-max-file="{{.UploadMaxFiles}}" data-max-size="{{.UploadMaxSize}}" data-default-message="{{.i18n.Tr "dropzone.default_message"}}" data-invalid-input-type="{{.i18n.Tr "dropzone.invalid_input_type"}}" data-file-too-big="{{.i18n.Tr "dropzone.file_too_big"}}" data-remove-file="{{.i18n.Tr "dropzone.remove_file"}}" data-max-file-tooltips="{{.i18n.Tr "dropzone.max_file_tooltips"}}" data-max-size-tooltips="{{.i18n.Tr "dropzone.max_size_tooltips"}}"><div class="maxfilesize ui red message" style="display: none;margin: 2.5rem;"></div></div> | |||
</div> | |||
{{template "repo/editor/commit_form" .}} | |||
</form> | |||
</div> | |||
</div> | |||
{{template "base/footer" .}} | |||
{{template "base/footer" .}} |
@@ -169,24 +169,10 @@ | |||
</select> | |||
</div> | |||
<!-- 数据集 --> | |||
<div class="required unite min_title inline field"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.dataset"}}</label> | |||
<select class="ui dropdown width35" id="trainjob_datasets" name="attachment" placeholder="{{.i18n.Tr "cloudbrain.select_dataset"}}" required> | |||
{{if $.uuid}} | |||
<option name="attachment" value="{{$.uuid}}">{{$.datasetName}}</option> | |||
{{end}} | |||
{{range .attachments}} | |||
<option value="">{{$.i18n.Tr "cloudbrain.select_dataset"}}</option> | |||
<option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | |||
{{end}} | |||
</select> | |||
<span> | |||
<i class="question circle icon" data-content="{{.i18n.Tr "cloudbrain.dataset_path_rule"}}" data-position="top center" data-variation="inverted mini"></i> | |||
</span> | |||
</div> | |||
<!-- 启动文件 --> | |||
{{template "custom/select_dataset_train" .}} | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span> | |||
<div class="inline unite min_title field required"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||
{{if .bootFile}} | |||
<input style="width: 35.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||
{{else}} | |||
@@ -1,68 +1,470 @@ | |||
{{template "base/head" .}} | |||
<style> | |||
.according-panel-heading{ | |||
box-sizing: border-box; | |||
padding: 8px 16px; | |||
color: #252b3a; | |||
background-color: #f2f5fc; | |||
line-height: 1.5; | |||
cursor: pointer; | |||
-moz-user-select: none; | |||
-webkit-user-select: none; | |||
-ms-user-select: none; | |||
-khtml-user-select: none; | |||
user-select: none; | |||
} | |||
.accordion-panel-title { | |||
margin-top: 0; | |||
margin-bottom: 0; | |||
color: #252b3a; | |||
} | |||
.accordion-panel-title-content{ | |||
vertical-align: middle; | |||
display: inline-block; | |||
width: calc(100% - 32px); | |||
cursor: default; | |||
} | |||
.acc-margin-bottom { | |||
margin-bottom: 5px; | |||
} | |||
.title_text { | |||
font-size: 12px; | |||
} | |||
.ac-display-inblock { | |||
display: inline-block; | |||
} | |||
.cti-mgRight-sm { | |||
margin-right: 8px; | |||
} | |||
.ac-text-normal { | |||
font-size: 14px; | |||
color: #575d6c; | |||
} | |||
.uc-accordionTitle-black { | |||
color: #333; | |||
} | |||
.accordion-border{ | |||
border:1px solid #cce2ff; | |||
} | |||
.padding0{ | |||
padding: 0 !important; | |||
} | |||
.content-pad{ | |||
padding: 15px 35px; | |||
} | |||
.content-margin{ | |||
margin:10px 5px ; | |||
} | |||
.tab_2_content { | |||
min-height: 460px; | |||
margin-left: 10px; | |||
} | |||
.ac-grid { | |||
display: block; | |||
*zoom: 1; | |||
} | |||
.ac-grid-col { | |||
float: left; | |||
width: 100%; | |||
} | |||
.ac-grid-col2 .ac-grid-col { | |||
width: 50%; | |||
} | |||
.ti-form { | |||
text-align: left; | |||
max-width: 100%; | |||
vertical-align: middle; | |||
} | |||
.ti-form>tbody { | |||
font-size: 12px; | |||
} | |||
.ti-form>tbody, .ti-form>tbody>tr { | |||
vertical-align: inherit; | |||
} | |||
.info_text { | |||
padding-bottom: 20px; | |||
padding-right: 20px; | |||
font-size: 12px; | |||
} | |||
.ti-text-form-label { | |||
padding-bottom: 20px; | |||
padding-right: 20px; | |||
color: #8a8e99; | |||
font-size: 12px; | |||
white-space: nowrap !important; | |||
width: 80px; | |||
line-height: 30px; | |||
} | |||
.ti-text-form-content{ | |||
line-height: 30px; | |||
padding-bottom: 20px; | |||
} | |||
.ti-form>tbody>tr>td { | |||
vertical-align: top; | |||
white-space: normal; | |||
} | |||
td, th { | |||
padding: 0; | |||
} | |||
.ac-grid-col .text-span { | |||
width: 450px; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
white-space: nowrap; | |||
} | |||
.text-span-new { | |||
width: 800px; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
height: 20%; | |||
word-break: break-all; | |||
} | |||
.redo-color{ | |||
color: #3291F8; | |||
} | |||
.ti-action-menu-item:not(:last-child){ | |||
margin-right: 10px; | |||
padding-right: 11px; | |||
text-decoration: none!important; | |||
color: #526ecc; | |||
cursor: pointer; | |||
display: inline-block; | |||
-moz-user-select: none; | |||
-webkit-user-select: none; | |||
-ms-user-select: none; | |||
-khtml-user-select: none; | |||
user-select: none; | |||
position: relative; | |||
} | |||
.ti-action-menu-item:not(:last-child):after { | |||
content: ""; | |||
display: inline-block; | |||
position: absolute; | |||
height: 12px; | |||
right: 0; | |||
top: 50%; | |||
-webkit-transform: translateY(-6px); | |||
-ms-transform: translateY(-6px); | |||
-o-transform: translateY(-6px); | |||
transform: translateY(-6px); | |||
border-right: 1px solid #dfe1e6; | |||
} | |||
.text-width80{ | |||
width: 100px; | |||
line-height: 30px; | |||
} | |||
.border-according{ | |||
border: 1px solid #dfe1e6; | |||
} | |||
.disabled { | |||
cursor: default; | |||
pointer-events: none; | |||
color: rgba(0,0,0,.6) !important; | |||
opacity: .45 !important; | |||
} | |||
.pad20{ | |||
border:0px !important; | |||
} | |||
.model_file_bread{ | |||
margin-bottom: -0.5rem !important; | |||
padding-left: 1rem; | |||
padding-top: 0.5rem ; | |||
} | |||
</style> | |||
<div id="mask"> | |||
<div id="loadingPage"> | |||
<div class="rect1"></div> | |||
<div class="rect2"></div> | |||
<div class="rect3"></div> | |||
<div class="rect4"></div> | |||
<div class="rect5"></div> | |||
</div> | |||
</div> | |||
<div class="repository"> | |||
{{template "repo/header" .}} | |||
<div class="repository new repo ui middle very relaxed page grid"> | |||
<div class="column"> | |||
{{template "base/alert" .}} | |||
<div class="ui container"> | |||
<h4 class="ui header" id="vertical-segment"> | |||
<div class="ui breadcrumb"> | |||
<a class="section" href="{{.RepoLink}}/debugjob?debugListType=all"> | |||
{{.i18n.Tr "repo.cloudbrain"}} | |||
</a> | |||
<div class="divider"> / </div> | |||
<a class="section backTodeBug" href="{{.RepoLink}}/debugjob?debugListType={{if eq $.debugListType "NPU"}}NPU{{else if eq $.debugListType "CPU/GPU"}}CPU/GPU{{else}}all{{end}}"> | |||
<a class="section" href="{{.RepoLink}}/debugjob?debugListType=all"> | |||
{{.i18n.Tr "repo.cloudbrain"}} | |||
</a> | |||
<div class="divider"> / </div> | |||
<a class="section backTodeBug" href="{{.RepoLink}}/debugjob?debugListType={{if eq $.debugListType "NPU"}}NPU{{else if eq $.debugListType "CPU/GPU"}}CPU/GPU{{else}}all{{end}}"> | |||
{{$.i18n.Tr "repo.modelarts.notebook"}} | |||
</a> | |||
<div class="divider"> / </div> | |||
{{with .task}} | |||
<div class="active section">{{.DisplayJobName}}</div> | |||
{{end}} | |||
</div> | |||
</a> | |||
<div class="divider"> / </div> | |||
{{with .task}} | |||
<div class="active section">{{.DisplayJobName}}</div> | |||
{{end}} | |||
</div> | |||
</h4> | |||
<div> | |||
<div class="ui yellow segment"> | |||
{{with .task}} | |||
<p>任务名称: {{.DisplayJobName}}</p> | |||
{{end}} | |||
</div> | |||
<div class="ui green segment"> | |||
<p>任务详情:</p> | |||
{{with .result}} | |||
<table class="ui celled striped table"> | |||
<tbody> | |||
<tr> | |||
<td class="four wide"> 状态 </td> | |||
<td> {{.Status}} </td> | |||
</tr> | |||
<tr> | |||
<td> 描述 </td> | |||
<td style="max-width: 480px; word-wrap:break-word">{{$.task.Description}}</td> | |||
</tr> | |||
<tr> | |||
<td> 镜像名称 </td> | |||
<td>{{$.task.Image}}</td> | |||
</tr> | |||
<tr> | |||
<td> 数据集下载地址 </td> | |||
<td style="max-width: 480px; word-wrap:break-word">{{$.datasetDownloadLink}}</td> | |||
</tr> | |||
<tr> | |||
<td> 开始时间 </td> | |||
<td>{{.CreateTime}}</td> | |||
</tr> | |||
<tr> | |||
<td> 最后更新时间 </td> | |||
<td>{{.LatestUpdateTime}}</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
{{end}} | |||
</div> | |||
{{with .task}} | |||
<div class="ui accordion border-according" id="accordion" data-repopath="" data-jobid="" data-version=""> | |||
<div class="active title padding0"> | |||
<div class="according-panel-heading"> | |||
<div class="accordion-panel-title"> | |||
<i class="dropdown icon"></i> | |||
<span class="accordion-panel-title-content"> | |||
<span> | |||
<div class="ac-display-inblock title_text acc-margin-bottom"> | |||
<span class="cti-mgRight-sm"> | |||
{{if not (eq .StartTime 0)}} | |||
<td>{{TimeSinceUnix1 .StartTime}}</td> | |||
{{else}} | |||
<td>{{TimeSinceUnix1 .CreatedUnix}}<td> | |||
{{end}} | |||
</span> | |||
<span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | |||
<span id="{{.VersionName}}-status-span"><i id="icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
</span> | |||
<span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | |||
<span class="cti-mgRight-sm uc-accordionTitle-black" id="{{.VersionName}}-duration-span">{{$.duration}}</span> | |||
</div> | |||
</span> | |||
</span> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="active content"> | |||
<div class="content-pad"> | |||
<div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | |||
<a class="active item" data-tab="first">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
</div> | |||
<div class="ui tab active" data-tab="first"> | |||
<div style="padding-top: 10px;"> | |||
<div class="tab_2_content"> | |||
<div class="ac-grid ac-grid-col2"> | |||
<div class="ac-grid-col"> | |||
<table class="ti-form"> | |||
<tbody class="ti-text-form"> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.cloudbrain_task"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.DisplayJobName}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.status"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-status"> | |||
{{.Status}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.cloudbrain_creator"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
{{.User.Name}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.computing_resources"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-computeresource"> | |||
{{.ComputeResource}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-duration"> | |||
{{$.duration}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.cloudbrain.datasetdownload"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span-new" id="model_description"> | |||
{{$.datasetDownloadLink}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "cloudbrain.description"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span-new" id="model_description"> | |||
{{.Description}} | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<div class="ac-grid-col"> | |||
<table class="ti-form"> | |||
<tbody class="ti-text-form"> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "cloudbrain.mirror"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
{{.Image}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.dataset"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-BenchmarkTypeName"> | |||
{{.DatasetName}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{$.resource_spec}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-startTime"> | |||
{{if not (eq .StartTime 0)}} | |||
{{TimeSinceUnix1 .StartTime}} | |||
{{else}} | |||
-- | |||
{{end}} | |||
</div> | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.cloudbrain.time.endtime"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-EndTime"> | |||
{{if not (eq .EndTime 0)}} | |||
{{TimeSinceUnix1 .EndTime}} | |||
{{else}} | |||
-- | |||
{{end}} | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
{{end}} | |||
{{template "base/paginate" .}} | |||
</div> | |||
<!-- 确认模态框 --> | |||
<div id="deletemodel"> | |||
<div class="ui basic modal"> | |||
<div class="ui icon header"> | |||
<i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}} | |||
</div> | |||
<div class="content"> | |||
<p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p> | |||
</div> | |||
<div class="actions"> | |||
<div class="ui red basic inverted cancel button"> | |||
<i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}} | |||
</div> | |||
<div class="ui green basic inverted ok button"> | |||
<i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}} | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
{{template "base/footer" .}} | |||
<script> | |||
$('.menu .item').tab() | |||
$(document).ready(function(){ | |||
$('.ui.accordion').accordion({selector:{trigger:'.icon'}}); | |||
}); | |||
$(document).ready(function(){ | |||
$('.secondary.menu .item').tab(); | |||
}); | |||
let userName | |||
let repoPath | |||
let jobName | |||
$(document).ready(function(){ | |||
let url = window.location.href; | |||
let urlArr = url.split('/') | |||
userName = urlArr.slice(-5)[0] | |||
repoPath = urlArr.slice(-4)[0] | |||
jobName = urlArr.slice(-1)[0] | |||
}) | |||
</script> |
@@ -158,29 +158,18 @@ | |||
<div class="inline unite min_title field required"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||
{{if .bootFile}} | |||
<input style="width: 33.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||
<input style="width: 35.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||
{{else}} | |||
<input style="width: 33.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | |||
<input style="width: 35.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | |||
{{end}} | |||
<span> | |||
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | |||
</span> | |||
<a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||
</div> | |||
<div class="required unite min_title inline field"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.dataset"}}</label> | |||
<select class="ui dropdown width80" id="trainjob_datasets" name="attachment" placeholder="{{.i18n.Tr "cloudbrain.select_dataset"}}"> | |||
{{if $.uuid}} | |||
<option name="attachment" value="{{$.uuid}}">{{$.datasetName}}</option> | |||
{{end}} | |||
{{range .attachments}} | |||
<option value="">{{$.i18n.Tr "cloudbrain.select_dataset"}}</option> | |||
<option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | |||
{{end}} | |||
</select> | |||
<span class="tooltips">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span> | |||
</div> | |||
{{template "custom/select_dataset_train" .}} | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span> | |||
<div class="inline unite min_title field"> | |||
<label 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> | |||
@@ -2751,12 +2751,25 @@ $(document).ready(async () => { | |||
$('td[data-href]').click(function () { | |||
window.location = $(this).data('href'); | |||
}); | |||
// 在String原型对象上添加format方法 | |||
String.prototype.format = function(){ | |||
let str = this; | |||
if(arguments.length == 0){ | |||
return str; | |||
}else{ | |||
Object.keys(arguments).forEach((item,index)=>{ | |||
str = str.replace(/\?/,arguments[item]) | |||
}) | |||
return str | |||
} | |||
} | |||
// Dropzone | |||
const $dropzone = $('#dropzone'); | |||
if ($dropzone.length > 0) { | |||
const filenameDict = {}; | |||
let maxFileTooltips=$dropzone.data('max-file-tooltips').format($dropzone.data('max-file'),$dropzone.data('max-size')) | |||
let maxSizeTooltips=$dropzone.data('max-size-tooltips').format($dropzone.data('max-file')) | |||
await createDropzone('#dropzone', { | |||
url: $dropzone.data('upload-url'), | |||
headers: {'X-Csrf-Token': csrf}, | |||
@@ -2788,6 +2801,22 @@ $(document).ready(async () => { | |||
}); | |||
} | |||
}); | |||
this.on('addedfile',(file)=>{ | |||
if(file.size/(1000*1000)>$dropzone.data('max-size')){ | |||
this.removeFile(file) | |||
$('.maxfilesize.ui.red.message').text(maxFileTooltips) | |||
$('.maxfilesize.ui.red.message').css('display','block') | |||
}else{ | |||
$('.maxfilesize.ui.red.message').css('display','none') | |||
} | |||
}); | |||
this.on('maxfilesexceeded',(file)=>{ | |||
this.removeFile(file) | |||
$('.maxfilesize.ui.red.message').text(maxSizeTooltips) | |||
$('.maxfilesize.ui.red.message').css('display','block') | |||
}) | |||
} | |||
}); | |||
} | |||
@@ -12,6 +12,11 @@ a { | |||
.ui .text.yellow a:hover { | |||
color: #f2711c!important | |||
} | |||
.ui.small.label.topic{ | |||
margin-bottom: 0; | |||
font-weight: 400; | |||
} | |||
.mb-1 { | |||
margin-bottom: 8px !important; | |||
} | |||
@@ -142,6 +147,11 @@ footer { | |||
width:auto; | |||
margin:10px auto; | |||
} | |||
.ui.card>.extra, .ui.cards>.card>.extra{ | |||
border-top:none !important; | |||
padding: .5em .5em 1em; | |||
} | |||
#index-project .ui.card>.content, #index-project.ui.cards>.card>.content{ | |||
padding: 0.5em 0.2em; | |||
} | |||
@@ -953,6 +963,7 @@ display: block; | |||
.highlight{ | |||
color: red; | |||
} | |||
.ui.list .list>.item>img.image+.content, .ui.list>.item>img.image+.content { | |||
width: calc(100% - 4.0em); | |||
margin-left: 0; | |||