| @@ -18,9 +18,9 @@ const ( | |||||
| ) | ) | ||||
| type Cloudbrain struct { | type Cloudbrain struct { | ||||
| ID int64 `xorm:"pk autoincr"` | |||||
| JobID string | |||||
| // Title string `xorm:"INDEX NOT NULL"` | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| JobID string `xorm:"INDEX NOT NULL"` | |||||
| JobName string | |||||
| Status int32 `xorm:"INDEX"` | Status int32 `xorm:"INDEX"` | ||||
| UserID int64 `xorm:"INDEX"` | UserID int64 `xorm:"INDEX"` | ||||
| RepoID int64 `xorm:"INDEX"` | RepoID int64 `xorm:"INDEX"` | ||||
| @@ -9,9 +9,9 @@ import ( | |||||
| func addCloudBrainTable(x *xorm.Engine) error { | func addCloudBrainTable(x *xorm.Engine) error { | ||||
| type Cloudbrain struct { | type Cloudbrain struct { | ||||
| ID int64 `xorm:"pk autoincr"` | |||||
| JobId string | |||||
| // Title string `xorm:"INDEX NOT NULL"` | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| JobID string `xorm:"INDEX NOT NULL"` | |||||
| JobName string | |||||
| Status int32 `xorm:"INDEX"` | Status int32 `xorm:"INDEX"` | ||||
| UserID int64 `xorm:"INDEX"` | UserID int64 `xorm:"INDEX"` | ||||
| RepoID int64 `xorm:"INDEX"` | RepoID int64 `xorm:"INDEX"` | ||||
| @@ -7,6 +7,7 @@ import ( | |||||
| // CreateDatasetForm form for dataset page | // CreateDatasetForm form for dataset page | ||||
| type CreateCloudBrainForm struct { | type CreateCloudBrainForm struct { | ||||
| JobName string `form:"job_name" binding:"Required"` | |||||
| Image string `binding:"Required"` | Image string `binding:"Required"` | ||||
| Command string `binding:"Required"` | Command string `binding:"Required"` | ||||
| } | } | ||||
| @@ -2,19 +2,13 @@ package cloudbrain | |||||
| import ( | import ( | ||||
| "errors" | "errors" | ||||
| "fmt" | |||||
| "strconv" | |||||
| "time" | |||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| ) | ) | ||||
| func GenerateTask(ctx *context.Context, image, command string) error { | |||||
| nowStr := strconv.FormatInt(time.Now().Unix(), 10) | |||||
| jobName := fmt.Sprintf("%s%s", ctx.User.Name, nowStr[len(nowStr)-5:]) | |||||
| func GenerateTask(ctx *context.Context, jobName, image, command string) error { | |||||
| jobResult, err := CreateJob(jobName, models.CreateJobParams{ | jobResult, err := CreateJob(jobName, models.CreateJobParams{ | ||||
| JobName: jobName, | JobName: jobName, | ||||
| RetryCount: 1, | RetryCount: 1, | ||||
| @@ -22,7 +16,7 @@ func GenerateTask(ctx *context.Context, image, command string) error { | |||||
| Image: image, | Image: image, | ||||
| TaskRoles: []models.TaskRole{ | TaskRoles: []models.TaskRole{ | ||||
| { | { | ||||
| Name: jobName, | |||||
| Name: "task1", | |||||
| TaskNumber: 1, | TaskNumber: 1, | ||||
| MinSucceededTaskCount: 1, | MinSucceededTaskCount: 1, | ||||
| MinFailedTaskCount: 1, | MinFailedTaskCount: 1, | ||||
| @@ -45,10 +39,11 @@ func GenerateTask(ctx *context.Context, image, command string) error { | |||||
| var jobID = jobResult.Payload["jobId"].(string) | var jobID = jobResult.Payload["jobId"].(string) | ||||
| err = models.CreateCloudbrain(&models.Cloudbrain{ | err = models.CreateCloudbrain(&models.Cloudbrain{ | ||||
| Status: int32(models.JobWaiting), | |||||
| UserID: ctx.User.ID, | |||||
| RepoID: ctx.Repo.Repository.ID, | |||||
| JobID: jobID, | |||||
| Status: int32(models.JobWaiting), | |||||
| UserID: ctx.User.ID, | |||||
| RepoID: ctx.Repo.Repository.ID, | |||||
| JobID: jobID, | |||||
| JobName: jobName, | |||||
| }) | }) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -1,6 +1,9 @@ | |||||
| package repo | package repo | ||||
| import ( | import ( | ||||
| "strconv" | |||||
| "time" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/auth" | "code.gitea.io/gitea/modules/auth" | ||||
| "code.gitea.io/gitea/modules/base" | "code.gitea.io/gitea/modules/base" | ||||
| @@ -52,9 +55,19 @@ func CloudBrainIndex(ctx *context.Context) { | |||||
| ctx.HTML(200, tplCloudBrainIndex) | ctx.HTML(200, tplCloudBrainIndex) | ||||
| } | } | ||||
| func cutString(str string, lens int) string { | |||||
| if len(str) < lens { | |||||
| return str | |||||
| } | |||||
| return str[:lens] | |||||
| } | |||||
| func CloudBrainNew(ctx *context.Context) { | func CloudBrainNew(ctx *context.Context) { | ||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| t := time.Now() | |||||
| var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[:5] | |||||
| ctx.Data["job_name"] = jobName | |||||
| ctx.Data["image"] = "192.168.202.74:5000/user-images/deepo:v2.0" | ctx.Data["image"] = "192.168.202.74:5000/user-images/deepo:v2.0" | ||||
| ctx.Data["command"] = `pip3 install jupyterlab==1.1.4;service ssh stop;jupyter lab --no-browser --ip=0.0.0.0 --allow-root --notebook-dir=\"/userhome\" --port=80 --NotebookApp.token=\"\" --LabApp.allow_origin=\"self https://cloudbrain.pcl.ac.cn\"` | ctx.Data["command"] = `pip3 install jupyterlab==1.1.4;service ssh stop;jupyter lab --no-browser --ip=0.0.0.0 --allow-root --notebook-dir=\"/userhome\" --port=80 --NotebookApp.token=\"\" --LabApp.allow_origin=\"self https://cloudbrain.pcl.ac.cn\"` | ||||
| ctx.HTML(200, tplCloudBrainNew) | ctx.HTML(200, tplCloudBrainNew) | ||||
| @@ -62,9 +75,10 @@ func CloudBrainNew(ctx *context.Context) { | |||||
| func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | ||||
| ctx.Data["PageIsCloudBrain"] = true | ctx.Data["PageIsCloudBrain"] = true | ||||
| jobName := form.JobName | |||||
| image := form.Image | image := form.Image | ||||
| command := form.Command | command := form.Command | ||||
| err := cloudbrain.GenerateTask(ctx, image, command) | |||||
| err := cloudbrain.GenerateTask(ctx, jobName, image, command) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) | ctx.RenderWithErr(err.Error(), tplCloudBrainNew, &form) | ||||
| return | return | ||||
| @@ -36,7 +36,7 @@ | |||||
| <div class="five wide column"> | <div class="five 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">{{.JobID}}</span> | |||||
| <span class="fitted">{{.JobName}}</span> | |||||
| </a> | </a> | ||||
| </div> | </div> | ||||
| <div class="two wide column"> | <div class="two wide column"> | ||||
| @@ -10,6 +10,11 @@ | |||||
| New Cloudbrain task | New Cloudbrain task | ||||
| </h3> | </h3> | ||||
| <div class="ui attached segment"> | <div class="ui attached segment"> | ||||
| <br> | |||||
| <div class="inline required field"> | |||||
| <label>任务名称</label> | |||||
| <input name="job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.job_name}}" tabindex="3" autofocus required maxlength="255"> | |||||
| </div> | |||||
| <br> | <br> | ||||
| <div class="inline required field"> | <div class="inline required field"> | ||||
| <label>镜像</label> | <label>镜像</label> | ||||