Reviewed-by: yuyuanshifu <747342561@qq.com> Reviewed-by: 林嘉怡 <2441898885@qq.com>tags/v0.1.8
@@ -384,6 +384,7 @@ func getPrivateAttachments(e Engine, userID int64) ([]*AttachmentUsername, error | |||||
return attachments, nil | return attachments, nil | ||||
} | } | ||||
/* | |||||
func GetAllUserAttachments(userID int64) ([]*AttachmentUsername, error) { | func GetAllUserAttachments(userID int64) ([]*AttachmentUsername, error) { | ||||
attachsPub, err := getAllPublicAttachments(x) | attachsPub, err := getAllPublicAttachments(x) | ||||
if err != nil { | if err != nil { | ||||
@@ -400,3 +401,17 @@ func GetAllUserAttachments(userID int64) ([]*AttachmentUsername, error) { | |||||
return append(attachsPub, attachsPri...), nil | return append(attachsPub, attachsPri...), nil | ||||
} | } | ||||
*/ | |||||
func getAllUserAttachments(e Engine, userID int64) ([]*AttachmentUsername, error) { | |||||
attachments := make([]*AttachmentUsername, 0, 10) | |||||
if err := e.Table("attachment").Join("LEFT", "`user`", "attachment.uploader_id " + | |||||
"= `user`.id").Where("decompress_state= ? and (uploader_id= ? or is_private = ?)", DecompressStateDone, userID, false).Find(&attachments); err != nil { | |||||
return nil, err | |||||
} | |||||
return attachments, nil | |||||
} | |||||
func GetAllUserAttachments(userID int64) ([]*AttachmentUsername, error) { | |||||
return getAllUserAttachments(x, userID) | |||||
} |
@@ -13,6 +13,7 @@ import ( | |||||
) | ) | ||||
type CloudbrainStatus string | type CloudbrainStatus string | ||||
type JobType string | |||||
const ( | const ( | ||||
JobWaiting CloudbrainStatus = "WAITING" | JobWaiting CloudbrainStatus = "WAITING" | ||||
@@ -20,11 +21,15 @@ const ( | |||||
JobSucceeded CloudbrainStatus = "SUCCEEDED" | JobSucceeded CloudbrainStatus = "SUCCEEDED" | ||||
JobFailed CloudbrainStatus = "FAILED" | JobFailed CloudbrainStatus = "FAILED" | ||||
JobRunning CloudbrainStatus = "RUNNING" | JobRunning CloudbrainStatus = "RUNNING" | ||||
JobTypeDebug JobType = "DEBUG" | |||||
JobTypeBenchmark JobType = "BENCHMARK" | |||||
) | ) | ||||
type Cloudbrain struct { | type Cloudbrain struct { | ||||
ID int64 `xorm:"pk autoincr"` | ID int64 `xorm:"pk autoincr"` | ||||
JobID string `xorm:"INDEX NOT NULL"` | JobID string `xorm:"INDEX NOT NULL"` | ||||
JobType string `xorm:"INDEX NOT NULL DEFAULT 'DEBUG'"` | |||||
JobName string `xorm:"INDEX"` | JobName string `xorm:"INDEX"` | ||||
Status string `xorm:"INDEX"` | Status string `xorm:"INDEX"` | ||||
UserID int64 `xorm:"INDEX"` | UserID int64 `xorm:"INDEX"` | ||||
@@ -131,6 +136,13 @@ type TaskPod struct { | |||||
} `json:"taskStatuses"` | } `json:"taskStatuses"` | ||||
} | } | ||||
type TaskInfo struct { | |||||
Username string `json:"username"` | |||||
TaskName string `json:"task_name"` | |||||
CodeName string `json:"code_name"` | |||||
} | |||||
func ConvertToTaskPod(input map[string]interface{}) (TaskPod, error) { | func ConvertToTaskPod(input map[string]interface{}) (TaskPod, error) { | ||||
data, _ := json.Marshal(input) | data, _ := json.Marshal(input) | ||||
var taskPod TaskPod | var taskPod TaskPod | ||||
@@ -11,6 +11,7 @@ type CreateCloudBrainForm struct { | |||||
Image string `form:"image" binding:"Required"` | Image string `form:"image" binding:"Required"` | ||||
Command string `form:"command" binding:"Required"` | Command string `form:"command" binding:"Required"` | ||||
Attachment string `form:"attachment" binding:"Required"` | Attachment string `form:"attachment" binding:"Required"` | ||||
JobType string `form:"job_type" binding:"Required"` | |||||
} | } | ||||
type CommitImageCloudBrainForm struct { | type CommitImageCloudBrainForm struct { | ||||
@@ -14,13 +14,15 @@ const ( | |||||
CodeMountPath = "/code" | CodeMountPath = "/code" | ||||
DataSetMountPath = "/dataset" | DataSetMountPath = "/dataset" | ||||
ModelMountPath = "/model" | ModelMountPath = "/model" | ||||
BenchMarkMountPath = "/benchmark" | |||||
TaskInfoName = "/taskInfo" | |||||
SubTaskName = "task1" | SubTaskName = "task1" | ||||
Success = "S000" | Success = "S000" | ||||
) | ) | ||||
func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, modelPath string) error { | |||||
func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, jobType string) error { | |||||
dataActualPath := setting.Attachment.Minio.RealPath + | dataActualPath := setting.Attachment.Minio.RealPath + | ||||
setting.Attachment.Minio.Bucket + "/" + | setting.Attachment.Minio.Bucket + "/" + | ||||
setting.Attachment.Minio.BasePath + | setting.Attachment.Minio.BasePath + | ||||
@@ -69,6 +71,13 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, | |||||
ReadOnly: false, | ReadOnly: false, | ||||
}, | }, | ||||
}, | }, | ||||
{ | |||||
HostPath: models.StHostPath{ | |||||
Path: benchmarkPath, | |||||
MountPath: BenchMarkMountPath, | |||||
ReadOnly: true, | |||||
}, | |||||
}, | |||||
}, | }, | ||||
}) | }) | ||||
if err != nil { | if err != nil { | ||||
@@ -88,6 +97,7 @@ func GenerateTask(ctx *context.Context, jobName, image, command, uuid, codePath, | |||||
JobID: jobID, | JobID: jobID, | ||||
JobName: jobName, | JobName: jobName, | ||||
SubTaskName: SubTaskName, | SubTaskName: SubTaskName, | ||||
JobType: jobType, | |||||
}) | }) | ||||
if err != nil { | if err != nil { | ||||
@@ -438,6 +438,11 @@ var ( | |||||
JobPath string | JobPath string | ||||
JobType string | JobType string | ||||
DebugServerHost string | DebugServerHost string | ||||
//benchmark config | |||||
IsBenchmarkEnabled bool | |||||
BenchmarkCode string | |||||
BenchmarkServerHost string | |||||
) | ) | ||||
// DateLang transforms standard language locale name to corresponding value in datetime plugin. | // DateLang transforms standard language locale name to corresponding value in datetime plugin. | ||||
@@ -1113,6 +1118,11 @@ func NewContext() { | |||||
JobPath = sec.Key("JOB_PATH").MustString("/datasets/minio/data/opendata/jobs/") | JobPath = sec.Key("JOB_PATH").MustString("/datasets/minio/data/opendata/jobs/") | ||||
DebugServerHost = sec.Key("DEBUG_SERVER_HOST").MustString("http://192.168.202.73") | DebugServerHost = sec.Key("DEBUG_SERVER_HOST").MustString("http://192.168.202.73") | ||||
JobType = sec.Key("JOB_TYPE").MustString("debug_openi") | JobType = sec.Key("JOB_TYPE").MustString("debug_openi") | ||||
sec = Cfg.Section("benchmark") | |||||
IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false) | |||||
BenchmarkCode = sec.Key("BENCHMARKCODE").MustString("https://yangzhx:justfortest123@git.openi.org.cn/yangzhx/detection_benchmark_script.git") | |||||
BenchmarkServerHost = sec.Key("HOST").MustString("http://192.168.202.90:3366/") | |||||
} | } | ||||
func loadInternalToken(sec *ini.Section) string { | func loadInternalToken(sec *ini.Section) string { | ||||
@@ -2,8 +2,10 @@ package repo | |||||
import ( | import ( | ||||
"code.gitea.io/gitea/modules/git" | "code.gitea.io/gitea/modules/git" | ||||
"encoding/json" | |||||
"errors" | "errors" | ||||
"os" | "os" | ||||
"os/exec" | |||||
"strconv" | "strconv" | ||||
"strings" | "strings" | ||||
"time" | "time" | ||||
@@ -109,6 +111,8 @@ func CloudBrainNew(ctx *context.Context) { | |||||
ctx.Data["code_path"] = cloudbrain.CodeMountPath | ctx.Data["code_path"] = cloudbrain.CodeMountPath | ||||
ctx.Data["dataset_path"] = cloudbrain.DataSetMountPath | ctx.Data["dataset_path"] = cloudbrain.DataSetMountPath | ||||
ctx.Data["model_path"] = cloudbrain.ModelMountPath | ctx.Data["model_path"] = cloudbrain.ModelMountPath | ||||
ctx.Data["benchmark_path"] = cloudbrain.BenchMarkMountPath | |||||
ctx.Data["is_benchmark_enabled"] = setting.IsBenchmarkEnabled | |||||
ctx.HTML(200, tplCloudBrainNew) | ctx.HTML(200, tplCloudBrainNew) | ||||
} | } | ||||
@@ -118,18 +122,24 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||||
image := form.Image | image := form.Image | ||||
command := form.Command | command := form.Command | ||||
uuid := form.Attachment | uuid := form.Attachment | ||||
jobType := form.JobType | |||||
codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | ||||
repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
downloadCode(repo, codePath) | downloadCode(repo, codePath) | ||||
modelPath := setting.JobPath + jobName + "/model" | |||||
modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath | |||||
err := os.MkdirAll(modelPath, os.ModePerm) | err := os.MkdirAll(modelPath, os.ModePerm) | ||||
if err != nil { | if err != nil { | ||||
ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) | ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) | ||||
return | return | ||||
} | } | ||||
err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, codePath, modelPath) | |||||
benchmarkPath := setting.JobPath + jobName + cloudbrain.BenchMarkMountPath | |||||
if setting.IsBenchmarkEnabled && jobType == string(models.JobTypeBenchmark) { | |||||
downloadBenchmarkCode(repo, jobName, benchmarkPath) | |||||
} | |||||
err = cloudbrain.GenerateTask(ctx, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, jobType) | |||||
if err != nil { | if err != nil { | ||||
ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) | ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) | ||||
return | return | ||||
@@ -270,6 +280,17 @@ func CloudBrainDel(ctx *context.Context) { | |||||
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/cloudbrain") | ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/cloudbrain") | ||||
} | } | ||||
func CloudBrainBenchmark(ctx *context.Context) { | |||||
var jobID = ctx.Params(":jobid") | |||||
_, err := models.GetCloudbrainByJobID(jobID) | |||||
if err != nil { | |||||
ctx.ServerError("GetCloudbrainByJobID failed", err) | |||||
return | |||||
} | |||||
ctx.Redirect(setting.BenchmarkServerHost) | |||||
} | |||||
func downloadCode(repo *models.Repository, codePath string) error { | func downloadCode(repo *models.Repository, codePath string) error { | ||||
if err := git.Clone(repo.RepoPath(), codePath, git.CloneRepoOptions{}); err != nil { | if err := git.Clone(repo.RepoPath(), codePath, git.CloneRepoOptions{}); err != nil { | ||||
log.Error("Failed to clone repository: %s (%v)", repo.FullName(), err) | log.Error("Failed to clone repository: %s (%v)", repo.FullName(), err) | ||||
@@ -278,3 +299,47 @@ func downloadCode(repo *models.Repository, codePath string) error { | |||||
return nil | return nil | ||||
} | } | ||||
func downloadBenchmarkCode(repo *models.Repository, taskName string, benchmarkPath string) error { | |||||
err := os.MkdirAll(benchmarkPath, os.ModePerm) | |||||
if err != nil { | |||||
log.Error("mkdir benchmarkPath failed", err.Error()) | |||||
return err | |||||
} | |||||
command := "git clone " + setting.BenchmarkCode + " " + benchmarkPath | |||||
cmd := exec.Command("/bin/bash", "-c", command) | |||||
output, err := cmd.Output() | |||||
log.Info(string(output)) | |||||
if err != nil { | |||||
log.Error("exec.Command(%s) failed:%v", command, err) | |||||
return err | |||||
} | |||||
fileName := benchmarkPath + cloudbrain.TaskInfoName | |||||
f, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm) | |||||
if err != nil { | |||||
log.Error("OpenFile failed", err.Error()) | |||||
return err | |||||
} | |||||
defer f.Close() | |||||
data, err := json.Marshal(models.TaskInfo{ | |||||
Username: repo.Owner.Name, | |||||
TaskName: taskName, | |||||
CodeName: repo.Name, | |||||
}) | |||||
if err != nil { | |||||
log.Error("json.Marshal failed", err.Error()) | |||||
return err | |||||
} | |||||
_, err = f.Write(data) | |||||
if err != nil { | |||||
log.Error("WriteString failed", err.Error()) | |||||
return err | |||||
} | |||||
return nil | |||||
} |
@@ -900,6 +900,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
m.Post("/commit_image", reqRepoCloudBrainWriter, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) | m.Post("/commit_image", reqRepoCloudBrainWriter, bindIgnErr(auth.CommitImageCloudBrainForm{}), repo.CloudBrainCommitImage) | ||||
m.Post("/stop", reqRepoCloudBrainWriter, repo.CloudBrainStop) | m.Post("/stop", reqRepoCloudBrainWriter, repo.CloudBrainStop) | ||||
m.Post("/del", reqRepoCloudBrainWriter, repo.CloudBrainDel) | m.Post("/del", reqRepoCloudBrainWriter, repo.CloudBrainDel) | ||||
m.Get("/benchmark", reqRepoCloudBrainWriter, repo.CloudBrainBenchmark) | |||||
}) | }) | ||||
m.Get("/create", reqRepoCloudBrainWriter, repo.CloudBrainNew) | m.Get("/create", reqRepoCloudBrainWriter, repo.CloudBrainNew) | ||||
m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainCreate) | m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainCreate) | ||||
@@ -169,6 +169,11 @@ | |||||
.dis { | .dis { | ||||
margin-bottom: 20px; | margin-bottom: 20px; | ||||
} | } | ||||
.disabled { | |||||
cursor: pointer; | |||||
pointer-events: none; | |||||
} | |||||
</style> | </style> | ||||
<!-- 弹窗 --> | <!-- 弹窗 --> | ||||
@@ -221,8 +226,8 @@ | |||||
<div class="column right aligned"> | <div class="column right aligned"> | ||||
<div class="ui right dropdown type jump item"> | <div class="ui right dropdown type jump item"> | ||||
<span class="text"> | <span class="text"> | ||||
{{.i18n.Tr "repo.issues.filter_sort"}}<i class="dropdown icon"></i> | |||||
</span> | |||||
{{.i18n.Tr "repo.issues.filter_sort"}}<i class="dropdown icon"></i> | |||||
</span> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -235,7 +240,7 @@ | |||||
<div class="row"> | <div class="row"> | ||||
<!-- 任务名 --> | <!-- 任务名 --> | ||||
<div class="five wide column"> | |||||
<div class="four wide column"> | |||||
<a class="title" href="{{$.Link}}/{{.JobID}}"> | <a class="title" href="{{$.Link}}/{{.JobID}}"> | ||||
<span class="fitted">{{svg "octicon-tasklist" 16}}</span> | <span class="fitted">{{svg "octicon-tasklist" 16}}</span> | ||||
<span class="fitted">{{.JobName}}</span> | <span class="fitted">{{.JobName}}</span> | ||||
@@ -255,8 +260,17 @@ | |||||
<!-- 查看 --> | <!-- 查看 --> | ||||
<div class="one wide column"> | <div class="one wide column"> | ||||
<span class="ui text center clipboard"> | <span class="ui text center clipboard"> | ||||
<a class="title" href="{{$.Link}}/{{.JobID}}"> | |||||
<span class="fitted">查看</span> | |||||
<a class="title" href="{{$.Link}}/{{.JobID}}"> | |||||
<span class="fitted">查看</span> | |||||
</a> | |||||
</span> | |||||
</div> | |||||
<!-- 评分 --> | |||||
<div class="one wide column"> | |||||
<span class="ui text center clipboard"> | |||||
<a class="title" onclick="stop(this)" href="{{if and (ne .Status "WAITING") (eq .JobType "BENCHMARK")}}{{$.Link}}/{{.JobID}}/benchmark{{else}}javascript:void(0);{{end}}" style="{{if and (ne .Status "WAITING") (eq .JobType "BENCHMARK")}}{{else}}color:#CCCCCC{{end}}"> | |||||
<span class="fitted">评分</span> | |||||
</a> | </a> | ||||
</span> | </span> | ||||
</div> | </div> | ||||
@@ -264,19 +278,18 @@ | |||||
<!-- 删除镜像 --> | <!-- 删除镜像 --> | ||||
<div class="one wide column"> | <div class="one wide column"> | ||||
<span class="ui text center clipboard"> | <span class="ui text center clipboard"> | ||||
<form id="delForm-{{.JobID}}" action="{{if ne .Status "STOPPED"}}javascript:void(0){{else}}{{$.Link}}/{{.JobID}}/del{{end}}" method="post"> | |||||
{{$.CsrfTokenHtml}} | |||||
<!-- <a class="fitted" onclick="document.getElementById('delForm-{{.JobID}}').submit();" style="{{if ne .Status "STOPPED"}}color:#CCCCCC{{end}}; font-size:16px; font-weight:bold">删除</a> --> | |||||
<a class="fitted" onclick="assertDelete(this)" style="{{if ne .Status "STOPPED"}}color:#CCCCCC{{end}}; font-size:16px; font-weight:bold">删除</a> | |||||
</form> | |||||
</span> | |||||
<form id="delForm-{{.JobID}}" action="{{if ne .Status "STOPPED"}}javascript:void(0){{else}}{{$.Link}}/{{.JobID}}/del{{end}}" method="post"> | |||||
{{$.CsrfTokenHtml}} | |||||
<a class="fitted" onclick="assertDelete(this)" style="{{if ne .Status "STOPPED"}}color:#CCCCCC{{end}}; font-size:16px; font-weight:bold">删除</a> | |||||
</form> | |||||
</span> | |||||
</div> | </div> | ||||
<!-- 调试 --> | <!-- 调试 --> | ||||
<div class="one wide column"> | <div class="one wide column"> | ||||
<span class="ui text center clipboard"> | <span class="ui text center clipboard"> | ||||
<a class="title" href="{{if not .CanDebug}}javascript:void(0){{else}}{{$.Link}}/{{.JobID}}/debug{{end}}" style="{{if not .CanDebug}}color:#CCCCCC{{end}}"> | |||||
<span class="fitted">调试</span> | |||||
<a class="title" onclick="stop(this)" href="{{if not .CanDebug}}javascript:void(0){{else}}{{$.Link}}/{{.JobID}}/debug{{end}}" style="{{if not .CanDebug}}color:#CCCCCC{{end}}"> | |||||
<span class="fitted">调试</span> | |||||
</a> | </a> | ||||
</span> | </span> | ||||
</div> | </div> | ||||
@@ -284,11 +297,11 @@ | |||||
<!-- 停止 --> | <!-- 停止 --> | ||||
<div class="one wide column"> | <div class="one wide column"> | ||||
<span class="ui text center clipboard"> | <span class="ui text center clipboard"> | ||||
<form id="stopForm-{{.JobID}}" action="{{if ne .Status "RUNNING"}}javascript:void(0){{else}}{{$.Link}}/{{.JobID}}/stop{{end}}" method="post"> | |||||
{{$.CsrfTokenHtml}} | |||||
<a class="fitted" onclick="document.getElementById('stopForm-{{.JobID}}').submit();" style="{{if ne .Status "RUNNING"}}color:#CCCCCC{{end}}; font-size:16px; font-weight:bold">停止</a> | |||||
</form> | |||||
</span> | |||||
<form id="stopForm-{{.JobID}}" action="{{if ne .Status "RUNNING"}}javascript:void(0){{else}}{{$.Link}}/{{.JobID}}/stop{{end}}" method="post"> | |||||
{{$.CsrfTokenHtml}} | |||||
<a class="fitted" onclick="document.getElementById('stopForm-{{.JobID}}').submit();" style="{{if ne .Status "RUNNING"}}color:#CCCCCC{{end}}; font-size:16px; font-weight:bold">停止</a> | |||||
</form> | |||||
</span> | |||||
</div> | </div> | ||||
<!-- 接收结果 --> | <!-- 接收结果 --> | ||||
@@ -325,8 +338,8 @@ | |||||
<div class="inline field"> | <div class="inline field"> | ||||
<label></label> | <label></label> | ||||
<button class="ui green button" onclick="showmask()"> | <button class="ui green button" onclick="showmask()"> | ||||
{{$.i18n.Tr "repo.cloudbrain.commit_image"}} | |||||
</button> | |||||
{{$.i18n.Tr "repo.cloudbrain.commit_image"}} | |||||
</button> | |||||
</div> | </div> | ||||
</form> | </form> | ||||
</div> | </div> | ||||
@@ -373,6 +386,15 @@ | |||||
{{template "base/footer" .}} | {{template "base/footer" .}} | ||||
<script> | <script> | ||||
// 调试和评分新开窗口 | |||||
function stop(obj) { | |||||
if (obj.style.color != "rgb(204, 204, 204)") { | |||||
obj.target = '_blank' | |||||
} else { | |||||
return | |||||
} | |||||
} | |||||
// 删除时用户确认 | // 删除时用户确认 | ||||
function assertDelete(obj) { | function assertDelete(obj) { | ||||
if (obj.style.color == "rgb(204, 204, 204)") { | if (obj.style.color == "rgb(204, 204, 204)") { | ||||
@@ -80,6 +80,10 @@ | |||||
-webkit-transform: scaleY(1.0); | -webkit-transform: scaleY(1.0); | ||||
} | } | ||||
} | } | ||||
.inline.required.field.cloudbrain_benchmark { | |||||
display: none; | |||||
} | |||||
</style> | </style> | ||||
<div id="mask"> | <div id="mask"> | ||||
@@ -102,28 +106,38 @@ | |||||
{{.i18n.Tr "repo.cloudbrain.new"}} | {{.i18n.Tr "repo.cloudbrain.new"}} | ||||
</h3> | </h3> | ||||
<div class="ui attached segment"> | <div class="ui attached segment"> | ||||
<br> | |||||
<!-- <br> --> | |||||
<div class="inline required field"> | <div class="inline required field"> | ||||
<label>任务名称</label> | <label>任务名称</label> | ||||
<input name="job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.job_name}}" tabindex="3" autofocus required maxlength="255"> | <input name="job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.job_name}}" tabindex="3" autofocus required maxlength="255"> | ||||
</div> | </div> | ||||
<br> | |||||
<div class="inline required field" style="{{if .is_benchmark_enabled}}display:block;{{else}}display:none;{{end}}"> | |||||
<label>任务类型</label> | |||||
<select id="cloudbrain_job_type" class="ui search dropdown" placeholder="选择任务类型" style='width:385px' name="job_type"> | |||||
<option name="job_type" value="DEBUG">DEBUG</option> | |||||
<option name="job_type" value="BENCHMARK">BENCHMARK</option> | |||||
</select> | |||||
</div> | |||||
<div class="inline required field"> | <div class="inline required field"> | ||||
<label>镜像</label> | <label>镜像</label> | ||||
<select class="ui search dropdown" id="cloudbrain_image" placeholder="选择镜像" style='width:385px' name="image"> | <select class="ui search dropdown" id="cloudbrain_image" placeholder="选择镜像" style='width:385px' name="image"> | ||||
{{range .images}} | |||||
<option name="image" value="{{.Place}}">{{.PlaceView}}</option> | |||||
{{end}} | |||||
</select> | |||||
{{range .images}} | |||||
<option name="image" value="{{.Place}}">{{.PlaceView}}</option> | |||||
{{end}} | |||||
</select> | |||||
</div> | </div> | ||||
<div class="inline required field"> | <div class="inline required field"> | ||||
<label>数据集(只有zip格式的数据集才能发起云脑任务)</label> | <label>数据集(只有zip格式的数据集才能发起云脑任务)</label> | ||||
<select id="cloudbrain_dataset" class="ui search dropdown" placeholder="选择数据集" style='width:385px' name="attachment"> | <select id="cloudbrain_dataset" class="ui search dropdown" placeholder="选择数据集" style='width:385px' name="attachment"> | ||||
{{range .attachments}} | |||||
<option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | |||||
{{end}} | |||||
</select> | |||||
{{range .attachments}} | |||||
<option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option> | |||||
{{end}} | |||||
</select> | |||||
</div> | </div> | ||||
<div class="inline required field"> | <div class="inline required field"> | ||||
<label>数据集存放路径</label> | <label>数据集存放路径</label> | ||||
<input name="dataset_path" id="cloudbrain_dataset_path" value="{{.dataset_path}}" tabindex="3" autofocus required maxlength="255" readonly="readonly"> | <input name="dataset_path" id="cloudbrain_dataset_path" value="{{.dataset_path}}" tabindex="3" autofocus required maxlength="255" readonly="readonly"> | ||||
@@ -136,6 +150,10 @@ | |||||
<label>代码存放路径</label> | <label>代码存放路径</label> | ||||
<input name="code_path" id="cloudbrain_code_path" value="{{.code_path}}" tabindex="3" autofocus required maxlength="255" readonly="readonly"> | <input name="code_path" id="cloudbrain_code_path" value="{{.code_path}}" tabindex="3" autofocus required maxlength="255" readonly="readonly"> | ||||
</div> | </div> | ||||
<div class="inline required field cloudbrain_benchmark"> | |||||
<label>benchmark脚本存放路径</label> | |||||
<input name="benchmark_path" id="cloudbrain_benchmark_path" value="{{.benchmark_path}}" tabindex="3" autofocus required maxlength="255" readonly="readonly"> | |||||
</div> | |||||
<div class="inline required field" hidden> | <div class="inline required field" hidden> | ||||
<label>启动命令</label> | <label>启动命令</label> | ||||
<textarea name="command" rows="10" readonly="readonly">{{.command}}</textarea> | <textarea name="command" rows="10" readonly="readonly">{{.command}}</textarea> | ||||
@@ -166,4 +184,17 @@ | |||||
document.getElementById("mask").style.display = "none" | document.getElementById("mask").style.display = "none" | ||||
} | } | ||||
} | } | ||||
$('select.dropdown') | |||||
.dropdown(); | |||||
$(function() { | |||||
$("#cloudbrain_job_type").change(function() { | |||||
if ($(this).val() == 'BENCHMARK') { | |||||
$(".cloudbrain_benchmark").show(); | |||||
} else { | |||||
$(".cloudbrain_benchmark").hide(); | |||||
} | |||||
}) | |||||
}) | |||||
</script> | </script> |