Browse Source

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

pull/1036/head
zouap 3 years ago
parent
commit
d4b674a8c0
9 changed files with 167 additions and 62 deletions
  1. +2
    -2
      models/attachment.go
  2. +1
    -0
      models/cloudbrain.go
  3. +7
    -0
      modules/modelarts/modelarts.go
  4. +0
    -8
      modules/modelarts/resty.go
  5. +8
    -8
      options/locale/locale_en-US.ini
  6. +13
    -7
      routers/repo/attachment.go
  7. +39
    -15
      routers/repo/modelarts.go
  8. +2
    -2
      templates/repo/modelarts/trainjob/index.tmpl
  9. +95
    -20
      templates/repo/modelarts/trainjob/new.tmpl

+ 2
- 2
models/attachment.go View File

@@ -379,7 +379,7 @@ func GetUnDecompressAttachments() ([]*Attachment, error) {


func getUnDecompressAttachments(e Engine) ([]*Attachment, error) { func getUnDecompressAttachments(e Engine) ([]*Attachment, error) {
attachments := make([]*Attachment, 0, 10) attachments := make([]*Attachment, 0, 10)
return attachments, e.Where("decompress_state = ? and dataset_id != 0 and attachment.type = ? and (name like '%.zip' or name like '%.tar.gz' or name like '%.tgz')", DecompressStateInit, TypeCloudBrainOne).Find(&attachments)
return attachments, e.Where("decompress_state = ? and dataset_id != 0 and (name like '%.zip' or name like '%.tar.gz' or name like '%.tgz')", DecompressStateInit).Find(&attachments)
} }


func GetAllPublicAttachments() ([]*AttachmentUsername, error) { func GetAllPublicAttachments() ([]*AttachmentUsername, error) {
@@ -429,7 +429,7 @@ func GetAllUserAttachments(userID int64) ([]*AttachmentUsername, error) {
func getModelArtsUserAttachments(e Engine, userID int64) ([]*AttachmentUsername, error) { func getModelArtsUserAttachments(e Engine, userID int64) ([]*AttachmentUsername, error) {
attachments := make([]*AttachmentUsername, 0, 10) attachments := make([]*AttachmentUsername, 0, 10)
if err := e.Table("attachment").Join("LEFT", "`user`", "attachment.uploader_id "+ if err := e.Table("attachment").Join("LEFT", "`user`", "attachment.uploader_id "+
"= `user`.id").Where("attachment.type = ? and (uploader_id= ? or is_private = ?)", TypeCloudBrainNotebook, userID, false).Find(&attachments); err != nil {
"= `user`.id").Where("attachment.type = ? and (uploader_id= ? or is_private = ?)", TypeCloudBrainTwo, userID, false).Find(&attachments); err != nil {
return nil, err return nil, err
} }
return attachments, nil return attachments, nil


+ 1
- 0
models/cloudbrain.go View File

@@ -70,6 +70,7 @@ type Cloudbrain struct {
VersionID int64 `xorm:"INDEX DEFAULT 0"` VersionID int64 `xorm:"INDEX DEFAULT 0"`
VersionName string VersionName string
Uuid string Uuid string
DatasetName string


User *User `xorm:"-"` User *User `xorm:"-"`
Repo *Repository `xorm:"-"` Repo *Repository `xorm:"-"`


+ 7
- 0
modules/modelarts/modelarts.go View File

@@ -195,6 +195,12 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) error {
return err return err
} }


attach, err := models.GetAttachmentByUUID(req.Uuid)
if err != nil {
log.Error("GetAttachmentByUUID(%s) failed:%v", strconv.FormatInt(jobResult.JobID, 10), err.Error())
return nil
}

err = models.CreateCloudbrain(&models.Cloudbrain{ err = models.CreateCloudbrain(&models.Cloudbrain{
Status: TransTrainJobStatus(jobResult.Status), Status: TransTrainJobStatus(jobResult.Status),
UserID: ctx.User.ID, UserID: ctx.User.ID,
@@ -206,6 +212,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) error {
VersionID: jobResult.VersionID, VersionID: jobResult.VersionID,
VersionName: jobResult.VersionName, VersionName: jobResult.VersionName,
Uuid: req.Uuid, Uuid: req.Uuid,
DatasetName: attach.Name,
}) })


if err != nil { if err != nil {


+ 0
- 8
modules/modelarts/resty.go View File

@@ -366,14 +366,6 @@ sendjob:
return &result, fmt.Errorf("json.Unmarshal failed(%s): %v", res.String(), err.Error()) return &result, fmt.Errorf("json.Unmarshal failed(%s): %v", res.String(), err.Error())
} }
log.Error("createTrainJob failed(%d):%s(%s)", res.StatusCode(), temp.ErrorCode, temp.ErrorMsg) log.Error("createTrainJob failed(%d):%s(%s)", res.StatusCode(), temp.ErrorCode, temp.ErrorMsg)
if temp.ErrorCode == "ModelArts.0404" {
temp.ErrorCode = "0404"
temp.ErrorMsg = "启动文件未找到!"
}
if temp.ErrorCode == "ModelArts.0104" {
temp.ErrorCode = "0104"
temp.ErrorMsg = "运行参数错误!"
}
return &result, fmt.Errorf("createTrainJob failed(%d):%s(%s)", res.StatusCode(), temp.ErrorCode, temp.ErrorMsg) return &result, fmt.Errorf("createTrainJob failed(%d):%s(%s)", res.StatusCode(), temp.ErrorCode, temp.ErrorMsg)
} }




+ 8
- 8
options/locale/locale_en-US.ini View File

@@ -764,15 +764,15 @@ submit_image=Submit Image
download=Download download=Download




cloudbrain=cloudbrain
cloudbrain=Cloudbrain
cloudbrain.new=New cloudbrain cloudbrain.new=New cloudbrain
cloudbrain.desc=cloudbrain
cloudbrain.desc=Cloudbrain
cloudbrain.cancel=Cancel cloudbrain.cancel=Cancel
cloudbrain.commit_image = submit
clone_cnt=download
balance = balance
balance.total_view = total balance
balance.available = available balance:
cloudbrain.commit_image = Submit
clone_cnt=Download
balance = Balance
balance.total_view = Total Balance
balance.available = Available Balance:
cloudbrain1 = cloudbrain1 cloudbrain1 = cloudbrain1
cloudbrain2 = cloudbrain2 cloudbrain2 = cloudbrain2
cloudbrain_selection = select cloudbrain cloudbrain_selection = select cloudbrain
@@ -787,7 +787,7 @@ cloudbrain_status_runtime = Running Time




modelarts.notebook=Debug Task modelarts.notebook=Debug Task
modelarts.train_job=Create Task
modelarts.train_job=Train Task
modelarts.train_job.new_debug= New Debug Task modelarts.train_job.new_debug= New Debug Task
modelarts.train_job.new_train=New Train Task modelarts.train_job.new_train=New Train Task
modelarts.train_job.config=Configuration information modelarts.train_job.config=Configuration information


+ 13
- 7
routers/repo/attachment.go View File

@@ -917,16 +917,22 @@ func HandleUnDecompressAttachment() {
} }


for _, attach := range attachs { for _, attach := range attachs {
err = worker.SendDecompressTask(contexExt.Background(), attach.UUID, attach.Name)
if err != nil {
log.Error("SendDecompressTask(%s) failed:%s", attach.UUID, err.Error())
} else {
attach.DecompressState = models.DecompressStateIng
err = models.UpdateAttachment(attach)
if attach.Type == models.TypeCloudBrainOne {
err = worker.SendDecompressTask(contexExt.Background(), attach.UUID, attach.Name)
if err != nil { if err != nil {
log.Error("UpdateAttachment state(%s) failed:%s", attach.UUID, err.Error())
log.Error("SendDecompressTask(%s) failed:%s", attach.UUID, err.Error())
} else {
attach.DecompressState = models.DecompressStateIng
err = models.UpdateAttachment(attach)
if err != nil {
log.Error("UpdateAttachment state(%s) failed:%s", attach.UUID, err.Error())
}
} }
} else if attach.Type == models.TypeCloudBrainTwo {
attachjson, _ := json.Marshal(attach)
labelmsg.SendDecompressAttachToLabelOBS(string(attachjson))
} }

} }


return return


+ 39
- 15
routers/repo/modelarts.go View File

@@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"os" "os"
"path" "path"
@@ -35,10 +36,10 @@ const (
tplModelArtsNew base.TplName = "repo/modelarts/new" tplModelArtsNew base.TplName = "repo/modelarts/new"
tplModelArtsShow base.TplName = "repo/modelarts/show" tplModelArtsShow base.TplName = "repo/modelarts/show"


tplModelArtsTrainJobIndex base.TplName = "repo/modelarts/trainjob/index"
tplModelArtsTrainJobNew base.TplName = "repo/modelarts/trainjob/new"
tplModelArtsTrainJobShow base.TplName = "repo/modelarts/trainjob/show"
tplModelArtsTrainJobShowModels base.TplName = "repo/modelarts/trainjob/models/index"
tplModelArtsTrainJobIndex base.TplName = "repo/modelarts/trainjob/index"
tplModelArtsTrainJobNew base.TplName = "repo/modelarts/trainjob/new"
tplModelArtsTrainJobShow base.TplName = "repo/modelarts/trainjob/show"
tplModelArtsTrainJobShowModels base.TplName = "repo/modelarts/trainjob/models/index"
) )


// MustEnableDataset check if repository enable internal cb // MustEnableDataset check if repository enable internal cb
@@ -621,7 +622,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath
outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath
logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath
dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + "/"
dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + uuid + "/"


//can, err := canUserCreateTrainJob(ctx.User.ID) //can, err := canUserCreateTrainJob(ctx.User.ID)
//if err != nil { //if err != nil {
@@ -643,10 +644,29 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
return return
} }


attach, err := models.GetAttachmentByUUID(uuid)
if err != nil {
log.Error("GetAttachmentByUUID(%s) failed:%v", uuid, err.Error())
return
}

//todo: del the codeLocalPath
_, err = ioutil.ReadDir(codeLocalPath)
if err == nil {
os.RemoveAll(codeLocalPath)
}
if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{}); err != nil { if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{}); err != nil {
log.Error("Failed to clone repository: %s (%v)", repo.FullName(), err)
log.Error("创建任务失败,任务名称已存在!: %s (%v)", repo.FullName(), err)
trainJobNewDataPrepare(ctx) trainJobNewDataPrepare(ctx)
ctx.RenderWithErr("Failed to clone repository", tplModelArtsTrainJobNew, &form)

ctx.Data["bootFile"] = form.BootFile
ctx.Data["uuid"] = form.Attachment
ctx.Data["datasetName"] = attach.Name
ctx.Data["params"] = form.Params
trainJobNewDataPrepare(ctx)
// ctx.RenderWithErr("Failed to clone repository", tplModelArtsTrainJobNew, &form)
ctx.RenderWithErr("创建任务失败,任务名称已存在!", tplModelArtsTrainJobNew, &form)
// ctx.RenderWithErr(err, tplModelArtsTrainJobNew, &form)
return return
} }


@@ -752,10 +772,14 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
Parameters: param, Parameters: param,
} }


err := modelarts.GenerateTrainJob(ctx, req)
err = modelarts.GenerateTrainJob(ctx, req)
if err != nil { if err != nil {
log.Error("GenerateTrainJob failed:%v", err.Error()) log.Error("GenerateTrainJob failed:%v", err.Error())
trainJobNewDataPrepare(ctx) trainJobNewDataPrepare(ctx)
ctx.Data["bootFile"] = form.BootFile
ctx.Data["uuid"] = form.Attachment
ctx.Data["datasetName"] = attach.Name
ctx.Data["params"] = form.Params
ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form) ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form)
return return
} }
@@ -860,12 +884,12 @@ func TrainJobShow(ctx *context.Context) {
return return
} }


attach, err := models.GetAttachmentByUUID(task.Uuid)
if err != nil {
log.Error("GetAttachmentByUUID(%s) failed:%v", jobID, err.Error())
ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
return
}
// attach, err := models.GetAttachmentByUUID(task.Uuid)
// if err != nil {
// log.Error("GetAttachmentByUUID(%s) failed:%v", jobID, err.Error())
// ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
// return
// }


result, err := modelarts.GetTrainJob(jobID, strconv.FormatInt(task.VersionID, 10)) result, err := modelarts.GetTrainJob(jobID, strconv.FormatInt(task.VersionID, 10))
if err != nil { if err != nil {
@@ -889,7 +913,7 @@ func TrainJobShow(ctx *context.Context) {
return return
} }


result.DatasetName = attach.Name
result.DatasetName = task.DatasetName
} }


resultLogFile, resultLog, err := trainJobGetLog(jobID) resultLogFile, resultLog, err := trainJobGetLog(jobID)


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

@@ -355,7 +355,7 @@
<form id="stopForm-{{.JobID}}" action="{{$.Link}}/{{.JobID}}/stop" method="post" style="margin-left:-1px;"> <form id="stopForm-{{.JobID}}" action="{{$.Link}}/{{.JobID}}/stop" method="post" style="margin-left:-1px;">
{{$.CsrfTokenHtml}} {{$.CsrfTokenHtml}}
{{if $.Permission.CanWrite $.UnitTypeCloudBrain}} {{if $.Permission.CanWrite $.UnitTypeCloudBrain}}
<a id="stop-model-debug-{{.JobID}}" class="ui basic {{if or (eq .Status "KILLED") (eq .Status "FAILED") (eq .Status "START_FAILED")}}disabled {{else}}blue {{end}}button" onclick="document.getElementById('stopForm-{{.JobID}}').submit();">
<a id="stop-model-debug-{{.JobID}}" class="ui basic {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING"}}disabled {{else}}blue {{end}}button" onclick="document.getElementById('stopForm-{{.JobID}}').submit();">
{{$.i18n.Tr "repo.stop"}} {{$.i18n.Tr "repo.stop"}}
</a> </a>
{{else}} {{else}}
@@ -535,7 +535,7 @@
$('#model-delete-'+jobID).removeClass('red') $('#model-delete-'+jobID).removeClass('red')
$('#model-delete-'+jobID).addClass('disabled') $('#model-delete-'+jobID).addClass('disabled')
} }
if(status=="KILLED" || status=="FAILED"){
if(status=="KILLED" || status=="FAILED" || status=="KILLING"){
$('#stop-model-debug-'+jobID).removeClass('blue') $('#stop-model-debug-'+jobID).removeClass('blue')
$('#stop-model-debug-'+jobID).addClass('disabled') $('#stop-model-debug-'+jobID).addClass('disabled')
$('#model-delete-'+jobID).removeClass('disabled') $('#model-delete-'+jobID).removeClass('disabled')


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

@@ -156,16 +156,12 @@
<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 unite min_title inline field"> <div class="required unite min_title inline field">
<label>{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> <label>{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<input style="width: 80%;" name="job_name" id="trainjob_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.job_name}}" tabindex="3" autofocus required maxlength="255">
<input style="width: 60%;" name="job_name" id="trainjob_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.job_name}}" tabindex="3" autofocus required maxlength="255">
</div> </div>
<!--<div class="inline field">
<label>{{.i18n.Tr "repo.modelarts.train_job.version"}}</label>
<span>第一版本</span>
</div>
-->
<div class="unite min_title inline field"> <div class="unite min_title inline field">
<label for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}&nbsp;&nbsp;</label> <label for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}&nbsp;&nbsp;</label>
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="256" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 256)" onkeydown="this.value=this.value.substring(0, 256)" onkeyup="this.value=this.value.substring(0, 256)"></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, 256)"></textarea>
</div> </div>
<!-- <h4 class="ui dividing header">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}</h4> <!-- <h4 class="ui dividing header">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}</h4>
<div class="inline field"> <div class="inline field">
@@ -182,7 +178,7 @@
<div class="required unite min_title inline fields" style="width: 90%;"> <div class="required unite min_title inline fields" style="width: 90%;">
<label>{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</label> <label>{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</label>
<div class="field" style="flex: 1.5;"> <div class="field" style="flex: 1.5;">
<select class="ui search dropdown width" id="trainjob_engines" >
<select class="ui dropdown width" id="trainjob_engines" >
{{range .engines}} {{range .engines}}
<option value="{{.Value}}">{{.Value}}</option> <option value="{{.Value}}">{{.Value}}</option>
{{end}} {{end}}
@@ -190,7 +186,7 @@


</div> </div>
<div class="field" style="flex: 2;"> <div class="field" style="flex: 2;">
<select class="ui search dropdown width" id="trainjob_engine_versions" style='width: 100%;' name="engine_id">
<select class="ui dropdown width" id="trainjob_engine_versions" style='width: 100%;' name="engine_id">
{{range .engine_versions}} {{range .engine_versions}}
<option name="engine_id" value="{{.ID}}">{{.Value}}</option> <option name="engine_id" value="{{.ID}}">{{.Value}}</option>
{{end}} {{end}}
@@ -235,20 +231,28 @@
</div> --> </div> -->
<div class="inline unite min_title field required"> <div class="inline unite min_title field required">
<label>{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> <label>{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
<input style="width: 33.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" >
{{if .bootFile}}
<input style="width: 33.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" >
{{end}}
<span> <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> <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> </span>
</div> </div>
<div class="required unite min_title inline field"> <div class="required unite min_title inline field">
<label>{{.i18n.Tr "repo.modelarts.train_job.dataset"}}</label> <label>{{.i18n.Tr "repo.modelarts.train_job.dataset"}}</label>
<select class="ui search dropdown width80" id="trainjob_datasets" name="attachment">
<select class="ui dropdown width80" id="trainjob_datasets" name="attachment" placeholder="选择数据集">
{{if $.uuid}}
<option name="attachment" value="{{$.uuid}}">{{$.datasetName}}</option>
{{end}}
{{range .attachments}} {{range .attachments}}
<option value="">选择数据集</option>
<option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> <option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option>
{{end}} {{end}}
</select> </select>
</div> </div>
<div class="inline unite min_title field"> <div class="inline unite min_title field">
<label>{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> <label>{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label>
<!-- <i class="plus square outline icon"></i> --> <!-- <i class="plus square outline icon"></i> -->
@@ -263,7 +267,7 @@
<!-- <h4 class="ui dividing header">{{.i18n.Tr "repo.modelarts.train_job.resource_setting"}}</h4> --> <!-- <h4 class="ui dividing header">{{.i18n.Tr "repo.modelarts.train_job.resource_setting"}}</h4> -->
<div class="required field " style="display: none;"> <div class="required field " style="display: none;">
<label>{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label> <label>{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label>
<select class="ui search 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">
{{range .resource_pools}} {{range .resource_pools}}
<option value="{{.ID}}">{{.Value}}</option> <option value="{{.ID}}">{{.Value}}</option>
{{end}} {{end}}
@@ -288,7 +292,7 @@


<div class="required unite min_title inline field"> <div class="required unite min_title inline field">
<label>{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> <label>{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label>
<select class="ui search 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}} {{range .flavor_infos}}
<option name="flavor" value="{{.Code}}">{{.Value}}</option> <option name="flavor" value="{{.Code}}">{{.Value}}</option>
{{end}} {{end}}
@@ -297,11 +301,11 @@
<div class="inline required unite min_title field"> <div class="inline required unite min_title field">
<label>{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> <label>{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label>
<div class="ui labeled input">
<span class="min"><i class="minus icon"></i></span>
<input style="border-radius: 0;" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1">
<div class="ui labeled input" style="width: 5%;">
<!-- <span class="min"><i class="minus icon"></i></span> -->
<input style="border-radius: 0;text-align: center;" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" disabled>
<span class="add"><i class="plus icon"></i></span>
<!-- <span class="add"><i class="plus icon"></i></span> -->
</div> </div>
<!-- <input name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255"> --> <!-- <input name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255"> -->
</div> </div>
@@ -356,6 +360,9 @@
let sever_num = $('#trainjob_work_server_num') let sever_num = $('#trainjob_work_server_num')
$('.add').click(function(){ $('.add').click(function(){
sever_num.val(parseInt(sever_num.val())+1) sever_num.val(parseInt(sever_num.val())+1)
if(sever_num.val()>=26){
sever_num.val(parseInt(sever_num.val())-1)
}
}) })
$('.min').click(function(){ $('.min').click(function(){
sever_num.val(parseInt(sever_num.val())-1) sever_num.val(parseInt(sever_num.val())-1)
@@ -368,10 +375,10 @@
function Add_parameter(i){ function Add_parameter(i){
value = '<div class="two fields width85" id= "para'+ i +'">' + value = '<div class="two fields width85" id= "para'+ i +'">' +
'<div class="field">' + '<div class="field">' +
'<input type="text" name="shipping_first-name" placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' +
'<input type="text" name="shipping_first-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}> ' +
'</div> ' + '</div> ' +
'<div class="field"> ' + '<div class="field"> ' +
'<input type="text" name="shipping_last-name" placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' +
'<input type="text" name="shipping_last-name" required placeholder={{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}>' +
'</div>'+ '</div>'+
'<span>' + '<span>' +
'<i class="trash icon">' + '<i class="trash icon">' +
@@ -471,6 +478,55 @@
$('.ui.parameter.modal') $('.ui.parameter.modal')
.modal('hide'); .modal('hide');
}) })
$('select.dropdown')
.dropdown();

$('.ui.form')
.form({
on: 'blur',
inline:true,
fields: {
boot_file: {
identifier : 'boot_file',
rules: [
{
type: 'regExp[/.+\.py$/g]',
prompt : '启动文件必须为.py结尾'
}
]
},
job_name:{
identifier : 'job_name',
rules: [
{
type: 'regExp[/^[a-zA-Z0-9-_]{1,36}$/]',
prompt : '只包含大小写字母、数字、_和-,最长36个字符。'
}
]
},
attachment:{
identifier : 'attachment',
rules: [
{
type: 'empty',
prompt : '选择一个数据集'
}
]

},
work_server_number: {
identifier : 'work_server_number',
rules: [
{
type : 'integer[1..25]',
prompt : '计算节点需要在1-25之间,请您键入正确的值'
}
]
}
},
})




function validate(){ function validate(){
$('.ui.form') $('.ui.form')
@@ -487,6 +543,25 @@
} }
] ]
}, },
job_name:{
identifier : 'job_name',
rules: [
{
type: 'regExp[/^[a-zA-Z0-9-_]{1,36}$/]',
prompt : '只包含大小写字母、数字、_和-,最长36个字符。'
}
]
},
attachment:{
identifier : 'attachment',
rules: [
{
type: 'empty',
prompt : '选择一个数据集'
}
]

},
work_server_number: { work_server_number: {
identifier : 'work_server_number', identifier : 'work_server_number',
rules: [ rules: [


Loading…
Cancel
Save