| @@ -17,6 +17,8 @@ const ( | |||||
| TypeCloudBrainOne = 0 | TypeCloudBrainOne = 0 | ||||
| TypeCloudBrainNotebook = 1 | TypeCloudBrainNotebook = 1 | ||||
| TypeCloudBrainTrainJob = 2 | TypeCloudBrainTrainJob = 2 | ||||
| TypeCloudBrainTwo = 1 | |||||
| ) | ) | ||||
| type FileChunk struct { | type FileChunk struct { | ||||
| @@ -6,13 +6,14 @@ | |||||
| package models | package models | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/modules/blockchain" | |||||
| "context" | "context" | ||||
| "crypto/md5" | "crypto/md5" | ||||
| "errors" | "errors" | ||||
| "fmt" | "fmt" | ||||
| "html/template" | "html/template" | ||||
| "code.gitea.io/gitea/modules/blockchain" | |||||
| // Needed for jpeg support | // Needed for jpeg support | ||||
| _ "image/jpeg" | _ "image/jpeg" | ||||
| "image/png" | "image/png" | ||||
| @@ -171,11 +172,11 @@ type Repository struct { | |||||
| NumOpenIssues int `xorm:"-"` | NumOpenIssues int `xorm:"-"` | ||||
| NumPulls int | NumPulls int | ||||
| NumClosedPulls int | NumClosedPulls int | ||||
| NumOpenPulls int `xorm:"-"` | |||||
| NumMilestones int `xorm:"NOT NULL DEFAULT 0"` | |||||
| NumClosedMilestones int `xorm:"NOT NULL DEFAULT 0"` | |||||
| NumOpenMilestones int `xorm:"-"` | |||||
| NumCommit int64 `xorm:"NOT NULL DEFAULT 0"` | |||||
| NumOpenPulls int `xorm:"-"` | |||||
| NumMilestones int `xorm:"NOT NULL DEFAULT 0"` | |||||
| NumClosedMilestones int `xorm:"NOT NULL DEFAULT 0"` | |||||
| NumOpenMilestones int `xorm:"-"` | |||||
| NumCommit int64 `xorm:"NOT NULL DEFAULT 0"` | |||||
| IsPrivate bool `xorm:"INDEX"` | IsPrivate bool `xorm:"INDEX"` | ||||
| IsEmpty bool `xorm:"INDEX"` | IsEmpty bool `xorm:"INDEX"` | ||||
| @@ -215,8 +216,8 @@ type Repository struct { | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||
| UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||
| Hot int64 `xorm:"-"` | |||||
| Active int64 `xorm:"-"` | |||||
| Hot int64 `xorm:"-"` | |||||
| Active int64 `xorm:"-"` | |||||
| } | } | ||||
| // SanitizedOriginalURL returns a sanitized OriginalURL | // SanitizedOriginalURL returns a sanitized OriginalURL | ||||
| @@ -2458,7 +2459,7 @@ func (repo *Repository) IncreaseCloneCnt() { | |||||
| } | } | ||||
| func UpdateRepositoryCommitNum(repo *Repository) error { | func UpdateRepositoryCommitNum(repo *Repository) error { | ||||
| if _,err := x.Exec("UPDATE `repository` SET num_commit = ? where id = ?", repo.NumCommit, repo.ID); err != nil { | |||||
| if _, err := x.Exec("UPDATE `repository` SET num_commit = ? where id = ?", repo.NumCommit, repo.ID); err != nil { | |||||
| return err | return err | ||||
| } | } | ||||
| @@ -5,6 +5,16 @@ import ( | |||||
| "gitea.com/macaron/macaron" | "gitea.com/macaron/macaron" | ||||
| ) | ) | ||||
| type CreateModelArtsForm struct { | |||||
| JobName string `form:"job_name" binding:"Required"` | |||||
| Attachment string `form:"attachment"` | |||||
| Description string `form:"description"` | |||||
| } | |||||
| func (f *CreateModelArtsForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||||
| return validate(errs, ctx.Data, f, ctx.Locale) | |||||
| } | |||||
| type CreateModelArtsNotebookForm struct { | type CreateModelArtsNotebookForm struct { | ||||
| JobName string `form:"job_name" binding:"Required"` | JobName string `form:"job_name" binding:"Required"` | ||||
| Attachment string `form:"attachment"` | Attachment string `form:"attachment"` | ||||
| @@ -16,18 +26,18 @@ func (f *CreateModelArtsNotebookForm) Validate(ctx *macaron.Context, errs bindin | |||||
| } | } | ||||
| type CreateModelArtsTrainJobForm struct { | type CreateModelArtsTrainJobForm struct { | ||||
| JobName string `form:"job_name" binding:"Required"` | |||||
| Attachment string `form:"attachment" binding:"Required"` | |||||
| BootFile string `form:"boot_file" binding:"Required"` | |||||
| WorkServerNumber int `form:"work_server_number" binding:"Required"` | |||||
| EngineID int `form:"engine_id" binding:"Required"` | |||||
| PoolID string `form:"pool_id" binding:"Required"` | |||||
| Flavor string `form:"flavor" binding:"Required"` | |||||
| Params string `form:"run_para_list" binding:"Required"` | |||||
| Description string `form:"description"` | |||||
| IsSaveParam string `form:"is_save_para"` | |||||
| JobName string `form:"job_name" binding:"Required"` | |||||
| Attachment string `form:"attachment" binding:"Required"` | |||||
| BootFile string `form:"boot_file" binding:"Required"` | |||||
| WorkServerNumber int `form:"work_server_number" binding:"Required"` | |||||
| EngineID int `form:"engine_id" binding:"Required"` | |||||
| PoolID string `form:"pool_id" binding:"Required"` | |||||
| Flavor string `form:"flavor" binding:"Required"` | |||||
| Params string `form:"run_para_list" binding:"Required"` | |||||
| Description string `form:"description"` | |||||
| IsSaveParam string `form:"is_save_para"` | |||||
| ParameterTemplateName string `form:"parameter_template_name"` | ParameterTemplateName string `form:"parameter_template_name"` | ||||
| PrameterDescription string `form:"parameter_description"` | |||||
| PrameterDescription string `form:"parameter_description"` | |||||
| } | } | ||||
| func (f *CreateModelArtsTrainJobForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *CreateModelArtsTrainJobForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
| @@ -30,11 +30,11 @@ const ( | |||||
| "{\"id\":120,\"value\":\"MindSpore-1.1.1-c76-tr5-python3.7-euleros2.8-aarch64\"}," + | "{\"id\":120,\"value\":\"MindSpore-1.1.1-c76-tr5-python3.7-euleros2.8-aarch64\"}," + | ||||
| "{\"id\":117,\"value\":\"TF-1.15-c75-python3.7-euleros2.8-aarch64\"}" + | "{\"id\":117,\"value\":\"TF-1.15-c75-python3.7-euleros2.8-aarch64\"}" + | ||||
| "]}" | "]}" | ||||
| FlavorInfos = "{\"flavor\":[{\"code\":\"modelarts.bm.910.arm.public.2\",\"value\":\"Ascend : 2 * Ascend 910 CPU:48 核 512GiB\"}," + | |||||
| "{\"code\":\"modelarts.bm.910.arm.public.8\",\"value\":\"Ascend : 8 * Ascend 910 CPU:192 核 2048GiB\"}," + | |||||
| "{\"code\":\"modelarts.bm.910.arm.public.4\",\"value\":\"Ascend : 4 * Ascend 910 CPU:96 核 1024GiB\"}," + | |||||
| "{\"code\":\"modelarts.bm.910.arm.public.1\",\"value\":\"Ascend : 1 * Ascend 910 CPU:24 核 256GiB\"}" + | |||||
| "]}" | |||||
| // FlavorInfos = "{\"flavor\":[{\"code\":\"modelarts.bm.910.arm.public.2\",\"value\":\"Ascend : 2 * Ascend 910 CPU:48 核 512GiB\"}," + | |||||
| // "{\"code\":\"modelarts.bm.910.arm.public.8\",\"value\":\"Ascend : 8 * Ascend 910 CPU:192 核 2048GiB\"}," + | |||||
| // "{\"code\":\"modelarts.bm.910.arm.public.4\",\"value\":\"Ascend : 4 * Ascend 910 CPU:96 核 1024GiB\"}," + | |||||
| // "{\"code\":\"modelarts.bm.910.arm.public.1\",\"value\":\"Ascend : 1 * Ascend 910 CPU:24 核 256GiB\"}" + | |||||
| // "]}" | |||||
| CodePath = "/code/" | CodePath = "/code/" | ||||
| OutputPath = "/output/" | OutputPath = "/output/" | ||||
| LogPath = "/log/" | LogPath = "/log/" | ||||
| @@ -1,15 +1,16 @@ | |||||
| package modelarts | package modelarts | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "crypto/tls" | "crypto/tls" | ||||
| "encoding/json" | "encoding/json" | ||||
| "fmt" | "fmt" | ||||
| "github.com/go-resty/resty/v2" | |||||
| "net/http" | "net/http" | ||||
| "strconv" | "strconv" | ||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "github.com/go-resty/resty/v2" | |||||
| ) | ) | ||||
| var ( | var ( | ||||
| @@ -91,7 +92,7 @@ func getToken() error { | |||||
| return nil | return nil | ||||
| } | } | ||||
| func createNotebook(createJobParams models.CreateNotebookParams) (*models.CreateNotebookResult, error) { | |||||
| func CreateJob(createJobParams models.CreateNotebookParams) (*models.CreateNotebookResult, error) { | |||||
| checkSetting() | checkSetting() | ||||
| client := getRestyClient() | client := getRestyClient() | ||||
| var result models.CreateNotebookResult | var result models.CreateNotebookResult | ||||
| @@ -252,6 +253,45 @@ sendjob: | |||||
| return &result, nil | return &result, nil | ||||
| } | } | ||||
| func DelJob(jobID string) (*models.NotebookDelResult, error) { | |||||
| checkSetting() | |||||
| client := getRestyClient() | |||||
| var result models.NotebookDelResult | |||||
| retry := 0 | |||||
| sendjob: | |||||
| res, err := client.R(). | |||||
| SetHeader("Content-Type", "application/json"). | |||||
| SetAuthToken(TOKEN). | |||||
| SetResult(&result). | |||||
| Delete(HOST + "/v1/" + setting.ProjectID + urlNotebook + "/" + jobID) | |||||
| if err != nil { | |||||
| return &result, fmt.Errorf("resty DelJob: %v", err) | |||||
| } | |||||
| if res.StatusCode() == http.StatusUnauthorized && retry < 1 { | |||||
| retry++ | |||||
| _ = getToken() | |||||
| goto sendjob | |||||
| } | |||||
| var response models.NotebookResult | |||||
| err = json.Unmarshal(res.Body(), &response) | |||||
| if err != nil { | |||||
| log.Error("json.Unmarshal failed: %s", err.Error()) | |||||
| return &result, fmt.Errorf("son.Unmarshal failed: %s", err.Error()) | |||||
| } | |||||
| if len(response.ErrorCode) != 0 { | |||||
| log.Error("DelJob failed(%s): %s", response.ErrorCode, response.ErrorMsg) | |||||
| return &result, fmt.Errorf("DelJob failed(%s): %s", response.ErrorCode, response.ErrorMsg) | |||||
| } | |||||
| return &result, nil | |||||
| } | |||||
| func GetJobToken(jobID string) (*models.NotebookGetJobTokenResult, error) { | func GetJobToken(jobID string) (*models.NotebookGetJobTokenResult, error) { | ||||
| checkSetting() | checkSetting() | ||||
| client := getRestyClient() | client := getRestyClient() | ||||
| @@ -468,11 +468,8 @@ var ( | |||||
| Bucket string | Bucket string | ||||
| Location string | Location string | ||||
| BasePath string | BasePath string | ||||
| <<<<<<< HEAD | |||||
| CodePathPrefix string | |||||
| ======= | |||||
| CodePathPrefix string | |||||
| UserBasePath string | UserBasePath string | ||||
| >>>>>>> origin/develop | |||||
| //modelarts config | //modelarts config | ||||
| ModelArtsHost string | ModelArtsHost string | ||||
| @@ -482,14 +479,11 @@ var ( | |||||
| ModelArtsUsername string | ModelArtsUsername string | ||||
| ModelArtsPassword string | ModelArtsPassword string | ||||
| ModelArtsDomain string | ModelArtsDomain string | ||||
| <<<<<<< HEAD | |||||
| AllowedOrg string | |||||
| ======= | |||||
| AllowedOrg string | |||||
| ProfileID string | ProfileID string | ||||
| PoolInfos string | PoolInfos string | ||||
| Flavor string | Flavor string | ||||
| FlavorInfos string | FlavorInfos string | ||||
| >>>>>>> origin/develop | |||||
| ) | ) | ||||
| // DateLang transforms standard language locale name to corresponding value in datetime plugin. | // DateLang transforms standard language locale name to corresponding value in datetime plugin. | ||||
| @@ -1195,11 +1189,8 @@ func NewContext() { | |||||
| Bucket = sec.Key("BUCKET").MustString("testopendata") | Bucket = sec.Key("BUCKET").MustString("testopendata") | ||||
| Location = sec.Key("LOCATION").MustString("cn-south-222") | Location = sec.Key("LOCATION").MustString("cn-south-222") | ||||
| BasePath = sec.Key("BASE_PATH").MustString("attachment/") | BasePath = sec.Key("BASE_PATH").MustString("attachment/") | ||||
| <<<<<<< HEAD | |||||
| CodePathPrefix = sec.Key("CODE_PATH_PREFIX").MustString("code/") | CodePathPrefix = sec.Key("CODE_PATH_PREFIX").MustString("code/") | ||||
| ======= | |||||
| UserBasePath = sec.Key("BASE_PATH_USER").MustString("users/") | UserBasePath = sec.Key("BASE_PATH_USER").MustString("users/") | ||||
| >>>>>>> origin/develop | |||||
| sec = Cfg.Section("modelarts") | sec = Cfg.Section("modelarts") | ||||
| ModelArtsHost = sec.Key("ENDPOINT").MustString("112.95.163.80") | ModelArtsHost = sec.Key("ENDPOINT").MustString("112.95.163.80") | ||||
| @@ -1209,14 +1200,11 @@ func NewContext() { | |||||
| ModelArtsUsername = sec.Key("USERNAME").MustString("") | ModelArtsUsername = sec.Key("USERNAME").MustString("") | ||||
| ModelArtsPassword = sec.Key("PASSWORD").MustString("") | ModelArtsPassword = sec.Key("PASSWORD").MustString("") | ||||
| ModelArtsDomain = sec.Key("DOMAIN").MustString("cn-south-222") | ModelArtsDomain = sec.Key("DOMAIN").MustString("cn-south-222") | ||||
| <<<<<<< HEAD | |||||
| AllowedOrg = sec.Key("ORGANIZATION").MustString("") | AllowedOrg = sec.Key("ORGANIZATION").MustString("") | ||||
| ======= | |||||
| ProfileID = sec.Key("PROFILE_ID").MustString("") | ProfileID = sec.Key("PROFILE_ID").MustString("") | ||||
| PoolInfos = sec.Key("POOL_INFOS").MustString("") | PoolInfos = sec.Key("POOL_INFOS").MustString("") | ||||
| Flavor = sec.Key("FLAVOR").MustString("") | Flavor = sec.Key("FLAVOR").MustString("") | ||||
| FlavorInfos = sec.Key("FLAVOR_INFOS").MustString("") | FlavorInfos = sec.Key("FLAVOR_INFOS").MustString("") | ||||
| >>>>>>> origin/develop | |||||
| } | } | ||||
| func loadInternalToken(sec *ini.Section) string { | func loadInternalToken(sec *ini.Section) string { | ||||
| @@ -12,8 +12,6 @@ import ( | |||||
| "strings" | "strings" | ||||
| "time" | "time" | ||||
| "code.gitea.io/gitea/modules/modelarts" | |||||
| "code.gitea.io/gitea/modules/git" | "code.gitea.io/gitea/modules/git" | ||||
| "code.gitea.io/gitea/modules/modelarts" | "code.gitea.io/gitea/modules/modelarts" | ||||
| "code.gitea.io/gitea/modules/obs" | "code.gitea.io/gitea/modules/obs" | ||||
| @@ -29,10 +27,15 @@ import ( | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| // tplModelArtsNotebookIndex base.TplName = "repo/modelarts/notebook/index" | |||||
| tplModelArtsNotebookIndex base.TplName = "repo/modelarts/notebook/index" | tplModelArtsNotebookIndex base.TplName = "repo/modelarts/notebook/index" | ||||
| tplModelArtsNotebookNew base.TplName = "repo/modelarts/notebook/new" | tplModelArtsNotebookNew base.TplName = "repo/modelarts/notebook/new" | ||||
| tplModelArtsNotebookShow base.TplName = "repo/modelarts/notebook/show" | tplModelArtsNotebookShow base.TplName = "repo/modelarts/notebook/show" | ||||
| tplModelArtsIndex base.TplName = "repo/modelarts/index" | |||||
| tplModelArtsNew base.TplName = "repo/modelarts/new" | |||||
| tplModelArtsShow base.TplName = "repo/modelarts/show" | |||||
| tplModelArtsTrainJobIndex base.TplName = "repo/modelarts/trainjob/index" | tplModelArtsTrainJobIndex base.TplName = "repo/modelarts/trainjob/index" | ||||
| tplModelArtsTrainJobNew base.TplName = "repo/modelarts/trainjob/new" | tplModelArtsTrainJobNew base.TplName = "repo/modelarts/trainjob/new" | ||||
| tplModelArtsTrainJobShow base.TplName = "repo/modelarts/trainjob/show" | tplModelArtsTrainJobShow base.TplName = "repo/modelarts/trainjob/show" | ||||
| @@ -46,6 +49,224 @@ func MustEnableModelArts(ctx *context.Context) { | |||||
| } | } | ||||
| } | } | ||||
| func ModelArtsIndex(ctx *context.Context) { | |||||
| MustEnableModelArts(ctx) | |||||
| repo := ctx.Repo.Repository | |||||
| page := ctx.QueryInt("page") | |||||
| if page <= 0 { | |||||
| page = 1 | |||||
| } | |||||
| ciTasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{ | |||||
| ListOptions: models.ListOptions{ | |||||
| Page: page, | |||||
| PageSize: setting.UI.IssuePagingNum, | |||||
| }, | |||||
| RepoID: repo.ID, | |||||
| Type: models.TypeCloudBrainTwo, | |||||
| }) | |||||
| if err != nil { | |||||
| ctx.ServerError("Cloudbrain", err) | |||||
| return | |||||
| } | |||||
| for i, task := range ciTasks { | |||||
| if task.Status == string(models.JobRunning) { | |||||
| ciTasks[i].CanDebug = true | |||||
| } else { | |||||
| ciTasks[i].CanDebug = false | |||||
| } | |||||
| } | |||||
| pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5) | |||||
| pager.SetDefaultParams(ctx) | |||||
| ctx.Data["Page"] = pager | |||||
| ctx.Data["PageIsCloudBrain"] = true | |||||
| ctx.Data["Tasks"] = ciTasks | |||||
| ctx.HTML(200, tplModelArtsIndex) | |||||
| } | |||||
| func ModelArtsNew(ctx *context.Context) { | |||||
| ctx.Data["PageIsCloudBrain"] = true | |||||
| t := time.Now() | |||||
| var jobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["job_name"] = jobName | |||||
| attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID) | |||||
| if err != nil { | |||||
| ctx.ServerError("GetAllUserAttachments failed:", err) | |||||
| return | |||||
| } | |||||
| ctx.Data["attachments"] = attachs | |||||
| ctx.Data["dataset_path"] = modelarts.DataSetMountPath | |||||
| ctx.Data["env"] = modelarts.NotebookEnv | |||||
| ctx.Data["notebook_type"] = modelarts.NotebookType | |||||
| if modelarts.FlavorInfos == nil { | |||||
| json.Unmarshal([]byte(setting.FlavorInfos), &modelarts.FlavorInfos) | |||||
| } | |||||
| ctx.Data["flavors"] = modelarts.FlavorInfos.FlavorInfo | |||||
| ctx.HTML(200, tplModelArtsNew) | |||||
| } | |||||
| func ModelArtsCreate(ctx *context.Context, form auth.CreateModelArtsForm) { | |||||
| ctx.Data["PageIsCloudBrain"] = true | |||||
| jobName := form.JobName | |||||
| uuid := form.Attachment | |||||
| description := form.Description | |||||
| //repo := ctx.Repo.Repository | |||||
| err := modelarts.GenerateTask(ctx, jobName, uuid, description) | |||||
| if err != nil { | |||||
| ctx.RenderWithErr(err.Error(), tplModelArtsNew, &form) | |||||
| return | |||||
| } | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts") | |||||
| } | |||||
| func ModelArtsShow(ctx *context.Context) { | |||||
| ctx.Data["PageIsCloudBrain"] = true | |||||
| var jobID = ctx.Params(":jobid") | |||||
| task, err := models.GetCloudbrainByJobID(jobID) | |||||
| if err != nil { | |||||
| ctx.Data["error"] = err.Error() | |||||
| ctx.RenderWithErr(err.Error(), tplModelArtsIndex, nil) | |||||
| return | |||||
| } | |||||
| result, err := modelarts.GetJob(jobID) | |||||
| if err != nil { | |||||
| ctx.Data["error"] = err.Error() | |||||
| ctx.RenderWithErr(err.Error(), tplModelArtsIndex, nil) | |||||
| return | |||||
| } | |||||
| if result != nil { | |||||
| task.Status = result.Status | |||||
| err = models.UpdateJob(task) | |||||
| if err != nil { | |||||
| ctx.Data["error"] = err.Error() | |||||
| ctx.RenderWithErr(err.Error(), tplModelArtsIndex, nil) | |||||
| return | |||||
| } | |||||
| createTime, _ := com.StrTo(result.CreationTimestamp).Int64() | |||||
| result.CreateTime = time.Unix(int64(createTime/1000), 0).Format("2006-01-02 15:04:05") | |||||
| endTime, _ := com.StrTo(result.LatestUpdateTimestamp).Int64() | |||||
| result.LatestUpdateTime = time.Unix(int64(endTime/1000), 0).Format("2006-01-02 15:04:05") | |||||
| result.QueuingInfo.BeginTime = time.Unix(int64(result.QueuingInfo.BeginTimestamp/1000), 0).Format("2006-01-02 15:04:05") | |||||
| result.QueuingInfo.EndTime = time.Unix(int64(result.QueuingInfo.EndTimestamp/1000), 0).Format("2006-01-02 15:04:05") | |||||
| } | |||||
| ctx.Data["task"] = task | |||||
| ctx.Data["jobID"] = jobID | |||||
| ctx.Data["result"] = result | |||||
| ctx.HTML(200, tplModelArtsShow) | |||||
| } | |||||
| func ModelArtsDebug(ctx *context.Context) { | |||||
| var jobID = ctx.Params(":jobid") | |||||
| _, err := models.GetCloudbrainByJobID(jobID) | |||||
| if err != nil { | |||||
| ctx.ServerError("GetCloudbrainByJobID failed", err) | |||||
| return | |||||
| } | |||||
| result, err := modelarts.GetJob(jobID) | |||||
| if err != nil { | |||||
| ctx.RenderWithErr(err.Error(), tplModelArtsIndex, nil) | |||||
| return | |||||
| } | |||||
| res, err := modelarts.GetJobToken(jobID) | |||||
| if err != nil { | |||||
| ctx.RenderWithErr(err.Error(), tplModelArtsIndex, nil) | |||||
| return | |||||
| } | |||||
| urls := strings.Split(result.Spec.Annotations.Url, "/") | |||||
| urlPrefix := result.Spec.Annotations.TargetDomain | |||||
| for i, url := range urls { | |||||
| if i > 2 { | |||||
| urlPrefix += "/" + url | |||||
| } | |||||
| } | |||||
| //urlPrefix := result.Spec.Annotations.TargetDomain + "/modelarts/internal/hub/notebook/user/" + task.JobID | |||||
| log.Info(urlPrefix) | |||||
| debugUrl := urlPrefix + "?token=" + res.Token | |||||
| ctx.Redirect(debugUrl) | |||||
| } | |||||
| func ModelArtsStop(ctx *context.Context) { | |||||
| var jobID = ctx.Params(":jobid") | |||||
| log.Info(jobID) | |||||
| task, err := models.GetCloudbrainByJobID(jobID) | |||||
| if err != nil { | |||||
| ctx.ServerError("GetCloudbrainByJobID failed", err) | |||||
| return | |||||
| } | |||||
| if task.Status != string(models.JobRunning) { | |||||
| log.Error("the job(%s) is not running", task.JobName) | |||||
| ctx.ServerError("the job is not running", errors.New("the job is not running")) | |||||
| return | |||||
| } | |||||
| param := models.NotebookAction{ | |||||
| Action: models.ActionStop, | |||||
| } | |||||
| res, err := modelarts.StopJob(jobID, param) | |||||
| if err != nil { | |||||
| log.Error("StopJob(%s) failed:%v", task.JobName, err.Error()) | |||||
| ctx.ServerError("StopJob failed", err) | |||||
| return | |||||
| } | |||||
| task.Status = res.CurrentStatus | |||||
| err = models.UpdateJob(task) | |||||
| if err != nil { | |||||
| ctx.ServerError("UpdateJob failed", err) | |||||
| return | |||||
| } | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts") | |||||
| } | |||||
| func ModelArtsDel(ctx *context.Context) { | |||||
| var jobID = ctx.Params(":jobid") | |||||
| task, err := models.GetCloudbrainByJobID(jobID) | |||||
| if err != nil { | |||||
| ctx.ServerError("GetCloudbrainByJobID failed", err) | |||||
| return | |||||
| } | |||||
| if task.Status != string(models.JobStopped) { | |||||
| log.Error("the job(%s) has not been stopped", task.JobName) | |||||
| ctx.ServerError("the job has not been stopped", errors.New("the job has not been stopped")) | |||||
| return | |||||
| } | |||||
| _, err = modelarts.DelJob(jobID) | |||||
| if err != nil { | |||||
| log.Error("DelJob(%s) failed:%v", task.JobName, err.Error()) | |||||
| ctx.ServerError("DelJob failed", err) | |||||
| return | |||||
| } | |||||
| err = models.DeleteJob(task) | |||||
| if err != nil { | |||||
| ctx.ServerError("DeleteJob failed", err) | |||||
| return | |||||
| } | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts") | |||||
| } | |||||
| func NotebookIndex(ctx *context.Context) { | func NotebookIndex(ctx *context.Context) { | ||||
| MustEnableModelArts(ctx) | MustEnableModelArts(ctx) | ||||
| repo := ctx.Repo.Repository | repo := ctx.Repo.Repository | ||||
| @@ -348,7 +569,7 @@ func TrainJobNew(ctx *context.Context) { | |||||
| ctx.Data["engine_versions"] = versionInfos.Version | ctx.Data["engine_versions"] = versionInfos.Version | ||||
| var flavorInfos modelarts.Flavor | var flavorInfos modelarts.Flavor | ||||
| if err = json.Unmarshal([]byte(modelarts.FlavorInfos), &flavorInfos); err != nil { | |||||
| if err = json.Unmarshal([]byte(setting.FlavorInfos), &flavorInfos); err != nil { | |||||
| ctx.ServerError("json.Unmarshal failed:", err) | ctx.ServerError("json.Unmarshal failed:", err) | ||||
| return | return | ||||
| } | } | ||||
| @@ -6,13 +6,14 @@ package routes | |||||
| import ( | import ( | ||||
| "bytes" | "bytes" | ||||
| "code.gitea.io/gitea/routers/operation" | |||||
| "encoding/gob" | "encoding/gob" | ||||
| "net/http" | "net/http" | ||||
| "path" | "path" | ||||
| "text/template" | "text/template" | ||||
| "time" | "time" | ||||
| "code.gitea.io/gitea/routers/operation" | |||||
| "code.gitea.io/gitea/routers/secure" | "code.gitea.io/gitea/routers/secure" | ||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| @@ -958,6 +959,16 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| }, context.RepoRef()) | }, context.RepoRef()) | ||||
| m.Group("/modelarts", func() { | m.Group("/modelarts", func() { | ||||
| m.Get("", reqRepoCloudBrainReader, repo.ModelArtsIndex) | |||||
| m.Group("/:jobid", func() { | |||||
| m.Get("", reqRepoCloudBrainReader, repo.ModelArtsShow) | |||||
| m.Get("/debug", reqRepoCloudBrainReader, repo.ModelArtsDebug) | |||||
| m.Post("/stop", reqRepoCloudBrainWriter, repo.ModelArtsStop) | |||||
| m.Post("/del", reqRepoCloudBrainWriter, repo.ModelArtsDel) | |||||
| }) | |||||
| m.Get("/create", reqRepoCloudBrainWriter, repo.ModelArtsNew) | |||||
| m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsForm{}), repo.ModelArtsCreate) | |||||
| m.Group("/notebook", func() { | m.Group("/notebook", func() { | ||||
| m.Get("", reqRepoCloudBrainReader, repo.NotebookIndex) | m.Get("", reqRepoCloudBrainReader, repo.NotebookIndex) | ||||
| m.Group("/:jobid", func() { | m.Group("/:jobid", func() { | ||||
| @@ -214,6 +214,11 @@ | |||||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | ||||
| <a class="ui green button" href="{{.RepoLink}}/modelarts/create">{{.i18n.Tr "repo.cloudbrain.new"}}</a> {{end}} | <a class="ui green button" href="{{.RepoLink}}/modelarts/create">{{.i18n.Tr "repo.cloudbrain.new"}}</a> {{end}} | ||||
| </div> | </div> | ||||
| <div class="column right aligned"> | |||||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||||
| <a class="ui blue button" href="{{.RepoLink}}/modelarts/train-job/create">{{.i18n.Tr "repo.cloudbrain.new"}}</a> {{end}} | |||||
| </div> | |||||
| </div> | </div> | ||||
| <p>使用鹏城云脑计算资源进行调试,云脑1提供CPU / GPU资源,云脑2提供Ascend NPU资源;调试使用的数据集也需要上传到对应的环境。</p> | <p>使用鹏城云脑计算资源进行调试,云脑1提供CPU / GPU资源,云脑2提供Ascend NPU资源;调试使用的数据集也需要上传到对应的环境。</p> | ||||