You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

modelarts.go 65 kB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034
  1. package repo
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "io"
  6. "io/ioutil"
  7. "net/http"
  8. "os"
  9. "path"
  10. "strconv"
  11. "strings"
  12. "time"
  13. "code.gitea.io/gitea/modules/cloudbrain"
  14. "code.gitea.io/gitea/models"
  15. "code.gitea.io/gitea/modules/auth"
  16. "code.gitea.io/gitea/modules/base"
  17. "code.gitea.io/gitea/modules/context"
  18. "code.gitea.io/gitea/modules/git"
  19. "code.gitea.io/gitea/modules/log"
  20. "code.gitea.io/gitea/modules/modelarts"
  21. "code.gitea.io/gitea/modules/obs"
  22. "code.gitea.io/gitea/modules/setting"
  23. "code.gitea.io/gitea/modules/storage"
  24. "github.com/unknwon/com"
  25. )
  26. const (
  27. tplDebugJobIndex base.TplName = "repo/debugjob/index"
  28. tplModelArtsNotebookIndex base.TplName = "repo/modelarts/notebook/index"
  29. tplModelArtsNotebookNew base.TplName = "repo/modelarts/notebook/new"
  30. tplModelArtsNotebookShow base.TplName = "repo/modelarts/notebook/show"
  31. tplModelArtsTrainJobIndex base.TplName = "repo/modelarts/trainjob/index"
  32. tplModelArtsTrainJobNew base.TplName = "repo/modelarts/trainjob/new"
  33. tplModelArtsTrainJobShow base.TplName = "repo/modelarts/trainjob/show"
  34. tplModelArtsTrainJobVersionNew base.TplName = "repo/modelarts/trainjob/version_new"
  35. tplModelArtsInferenceJobIndex base.TplName = "repo/modelarts/inferencejob/index"
  36. tplModelArtsInferenceJobNew base.TplName = "repo/modelarts/inferencejob/new"
  37. tplModelArtsInferenceJobShow base.TplName = "repo/modelarts/inferencejob/show"
  38. )
  39. func DebugJobIndex(ctx *context.Context) {
  40. debugListType := ctx.Query("debugListType")
  41. ctx.Data["ListType"] = debugListType
  42. MustEnableCloudbrain(ctx)
  43. repo := ctx.Repo.Repository
  44. page := ctx.QueryInt("page")
  45. if page <= 0 {
  46. page = 1
  47. }
  48. debugType := modelarts.DebugType
  49. jobType := string(models.JobTypeDebug)
  50. if debugListType == modelarts.GPUResource {
  51. debugType = models.TypeCloudBrainOne
  52. jobType = ""
  53. }
  54. if debugListType == modelarts.NPUResource {
  55. debugType = models.TypeCloudBrainTwo
  56. }
  57. ciTasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{
  58. ListOptions: models.ListOptions{
  59. Page: page,
  60. PageSize: setting.UI.IssuePagingNum,
  61. },
  62. RepoID: repo.ID,
  63. Type: debugType,
  64. JobType: jobType,
  65. })
  66. if err != nil {
  67. ctx.ServerError("Get debugjob faild:", err)
  68. return
  69. }
  70. for i, task := range ciTasks {
  71. ciTasks[i].CanDebug = cloudbrain.CanCreateOrDebugJob(ctx)
  72. ciTasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)
  73. if task.Cloudbrain.Type == models.TypeCloudBrainOne {
  74. ciTasks[i].Cloudbrain.ComputeResource = modelarts.GPUResource
  75. } else if task.Cloudbrain.Type == models.TypeCloudBrainTwo {
  76. ciTasks[i].Cloudbrain.ComputeResource = modelarts.NPUResource
  77. }
  78. }
  79. pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)
  80. //pager.SetDefaultParams(ctx)
  81. pager.AddParam(ctx, "debugListType", "ListType")
  82. ctx.Data["Page"] = pager
  83. ctx.Data["PageIsCloudBrain"] = true
  84. ctx.Data["Tasks"] = ciTasks
  85. ctx.Data["CanCreate"] = cloudbrain.CanCreateOrDebugJob(ctx)
  86. ctx.Data["RepoIsEmpty"] = repo.IsEmpty
  87. ctx.HTML(200, tplDebugJobIndex)
  88. }
  89. // MustEnableDataset check if repository enable internal cb
  90. func MustEnableModelArts(ctx *context.Context) {
  91. if !ctx.Repo.CanRead(models.UnitTypeCloudBrain) {
  92. ctx.NotFound("MustEnableCloudbrain", nil)
  93. return
  94. }
  95. }
  96. func NotebookNew(ctx *context.Context) {
  97. ctx.Data["PageIsCloudBrain"] = true
  98. t := time.Now()
  99. var jobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
  100. ctx.Data["job_name"] = jobName
  101. attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
  102. if err != nil {
  103. ctx.ServerError("GetAllUserAttachments failed:", err)
  104. return
  105. }
  106. ctx.Data["attachments"] = attachs
  107. ctx.Data["dataset_path"] = modelarts.DataSetMountPath
  108. ctx.Data["env"] = modelarts.NotebookEnv
  109. ctx.Data["notebook_type"] = modelarts.NotebookType
  110. if modelarts.FlavorInfos == nil {
  111. json.Unmarshal([]byte(setting.FlavorInfos), &modelarts.FlavorInfos)
  112. }
  113. ctx.Data["flavors"] = modelarts.FlavorInfos.FlavorInfo
  114. ctx.HTML(200, tplModelArtsNotebookNew)
  115. }
  116. func NotebookCreate(ctx *context.Context, form auth.CreateModelArtsNotebookForm) {
  117. ctx.Data["PageIsNotebook"] = true
  118. jobName := form.JobName
  119. uuid := form.Attachment
  120. description := form.Description
  121. flavor := form.Flavor
  122. count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID)
  123. if err != nil {
  124. log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"])
  125. cloudBrainNewDataPrepare(ctx)
  126. ctx.RenderWithErr("system error", tplModelArtsNotebookNew, &form)
  127. return
  128. } else {
  129. if count >= 1 {
  130. log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
  131. cloudBrainNewDataPrepare(ctx)
  132. ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplModelArtsNotebookNew, &form)
  133. return
  134. }
  135. }
  136. err = modelarts.GenerateTask(ctx, jobName, uuid, description, flavor)
  137. if err != nil {
  138. ctx.RenderWithErr(err.Error(), tplModelArtsNotebookNew, &form)
  139. return
  140. }
  141. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")
  142. }
  143. func NotebookShow(ctx *context.Context) {
  144. ctx.Data["PageIsCloudBrain"] = true
  145. var jobID = ctx.Params(":jobid")
  146. task, err := models.GetCloudbrainByJobID(jobID)
  147. if err != nil {
  148. ctx.Data["error"] = err.Error()
  149. ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil)
  150. return
  151. }
  152. result, err := modelarts.GetJob(jobID)
  153. if err != nil {
  154. ctx.Data["error"] = err.Error()
  155. ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil)
  156. return
  157. }
  158. if result != nil {
  159. task.Status = result.Status
  160. err = models.UpdateJob(task)
  161. if err != nil {
  162. ctx.Data["error"] = err.Error()
  163. ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil)
  164. return
  165. }
  166. createTime, _ := com.StrTo(result.CreationTimestamp).Int64()
  167. result.CreateTime = time.Unix(int64(createTime/1000), 0).Format("2006-01-02 15:04:05")
  168. endTime, _ := com.StrTo(result.LatestUpdateTimestamp).Int64()
  169. result.LatestUpdateTime = time.Unix(int64(endTime/1000), 0).Format("2006-01-02 15:04:05")
  170. result.QueuingInfo.BeginTime = time.Unix(int64(result.QueuingInfo.BeginTimestamp/1000), 0).Format("2006-01-02 15:04:05")
  171. result.QueuingInfo.EndTime = time.Unix(int64(result.QueuingInfo.EndTimestamp/1000), 0).Format("2006-01-02 15:04:05")
  172. }
  173. ctx.Data["task"] = task
  174. ctx.Data["jobID"] = jobID
  175. ctx.Data["result"] = result
  176. ctx.HTML(200, tplModelArtsNotebookShow)
  177. }
  178. func NotebookDebug(ctx *context.Context) {
  179. var jobID = ctx.Params(":jobid")
  180. _, err := models.GetCloudbrainByJobID(jobID)
  181. if err != nil {
  182. ctx.ServerError("GetCloudbrainByJobID failed", err)
  183. return
  184. }
  185. result, err := modelarts.GetJob(jobID)
  186. if err != nil {
  187. ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil)
  188. return
  189. }
  190. res, err := modelarts.GetJobToken(jobID)
  191. if err != nil {
  192. ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil)
  193. return
  194. }
  195. urls := strings.Split(result.Spec.Annotations.Url, "/")
  196. urlPrefix := result.Spec.Annotations.TargetDomain
  197. for i, url := range urls {
  198. if i > 2 {
  199. urlPrefix += "/" + url
  200. }
  201. }
  202. debugUrl := urlPrefix + "?token=" + res.Token
  203. ctx.Redirect(debugUrl)
  204. }
  205. func NotebookManage(ctx *context.Context) {
  206. var jobID = ctx.Params(":jobid")
  207. var action = ctx.Params(":action")
  208. var resultCode = "0"
  209. var errorMsg = ""
  210. var status = ""
  211. for {
  212. task, err := models.GetCloudbrainByJobID(jobID)
  213. if err != nil {
  214. log.Error("GetCloudbrainByJobID failed:%v", err, ctx.Data["MsgID"])
  215. resultCode = "-1"
  216. errorMsg = "system error"
  217. break
  218. }
  219. if action == models.ActionStop {
  220. if task.Status != string(models.ModelArtsRunning) {
  221. log.Error("the job(%s) is not running", task.JobName, ctx.Data["MsgID"])
  222. resultCode = "-1"
  223. errorMsg = "the job is not running"
  224. break
  225. }
  226. } else if action == models.ActionRestart {
  227. if task.Status != string(models.ModelArtsStopped) && task.Status != string(models.ModelArtsStartFailed) && task.Status != string(models.ModelArtsCreateFailed) {
  228. log.Error("the job(%s) is not stopped", task.JobName, ctx.Data["MsgID"])
  229. resultCode = "-1"
  230. errorMsg = "the job is not stopped"
  231. break
  232. }
  233. count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID)
  234. if err != nil {
  235. log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"])
  236. resultCode = "-1"
  237. errorMsg = "system error"
  238. break
  239. } else {
  240. if count >= 1 {
  241. log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
  242. resultCode = "-1"
  243. errorMsg = "you have already a running or waiting task, can not create more"
  244. break
  245. }
  246. }
  247. action = models.ActionStart
  248. } else {
  249. log.Error("the action(%s) is illegal", action, ctx.Data["MsgID"])
  250. resultCode = "-1"
  251. errorMsg = "非法操作"
  252. break
  253. }
  254. param := models.NotebookAction{
  255. Action: action,
  256. }
  257. res, err := modelarts.ManageNotebook(jobID, param)
  258. if err != nil {
  259. log.Error("ManageNotebook(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"])
  260. resultCode = "-1"
  261. errorMsg = "启动失败"
  262. break
  263. }
  264. task.Status = res.CurrentStatus
  265. err = models.UpdateJob(task)
  266. if err != nil {
  267. log.Error("UpdateJob(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"])
  268. resultCode = "-1"
  269. errorMsg = "system error"
  270. break
  271. }
  272. status = task.Status
  273. break
  274. }
  275. ctx.JSON(200, map[string]string{
  276. "result_code": resultCode,
  277. "error_msg": errorMsg,
  278. "status": status,
  279. "job_id": jobID,
  280. })
  281. }
  282. func NotebookDel(ctx *context.Context) {
  283. var jobID = ctx.Params(":jobid")
  284. task, err := models.GetCloudbrainByJobID(jobID)
  285. if err != nil {
  286. ctx.ServerError("GetCloudbrainByJobID failed", err)
  287. return
  288. }
  289. if task.Status != string(models.ModelArtsCreateFailed) && task.Status != string(models.ModelArtsStartFailed) && task.Status != string(models.ModelArtsStopped){
  290. log.Error("the job(%s) has not been stopped", task.JobName)
  291. ctx.ServerError("the job has not been stopped", errors.New("the job has not been stopped"))
  292. return
  293. }
  294. _, err = modelarts.DelNotebook(jobID)
  295. if err != nil {
  296. log.Error("DelJob(%s) failed:%v", task.JobName, err.Error())
  297. ctx.ServerError("DelJob failed", err)
  298. return
  299. }
  300. err = models.DeleteJob(task)
  301. if err != nil {
  302. ctx.ServerError("DeleteJob failed", err)
  303. return
  304. }
  305. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob")
  306. }
  307. func TrainJobIndex(ctx *context.Context) {
  308. MustEnableModelArts(ctx)
  309. repo := ctx.Repo.Repository
  310. page := ctx.QueryInt("page")
  311. if page <= 0 {
  312. page = 1
  313. }
  314. tasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{
  315. ListOptions: models.ListOptions{
  316. Page: page,
  317. PageSize: setting.UI.IssuePagingNum,
  318. },
  319. RepoID: repo.ID,
  320. Type: models.TypeCloudBrainTwo,
  321. JobType: string(models.JobTypeTrain),
  322. IsLatestVersion: modelarts.IsLatestVersion,
  323. })
  324. if err != nil {
  325. ctx.ServerError("Cloudbrain", err)
  326. return
  327. }
  328. for i, task := range tasks {
  329. tasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)
  330. tasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain)
  331. tasks[i].ComputeResource = modelarts.NPUResource
  332. }
  333. pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)
  334. pager.SetDefaultParams(ctx)
  335. ctx.Data["Page"] = pager
  336. ctx.Data["PageIsCloudBrain"] = true
  337. ctx.Data["Tasks"] = tasks
  338. ctx.Data["CanCreate"] = cloudbrain.CanCreateOrDebugJob(ctx)
  339. ctx.Data["RepoIsEmpty"] = repo.IsEmpty
  340. ctx.HTML(200, tplModelArtsTrainJobIndex)
  341. }
  342. func TrainJobNew(ctx *context.Context) {
  343. err := trainJobNewDataPrepare(ctx)
  344. if err != nil {
  345. ctx.ServerError("get new train-job info failed", err)
  346. return
  347. }
  348. ctx.HTML(200, tplModelArtsTrainJobNew)
  349. }
  350. func trainJobNewDataPrepare(ctx *context.Context) error {
  351. ctx.Data["PageIsCloudBrain"] = true
  352. //can, err := canUserCreateTrainJob(ctx.User.ID)
  353. //if err != nil {
  354. // ctx.ServerError("canUserCreateTrainJob", err)
  355. // return
  356. //}
  357. //
  358. //if !can {
  359. // log.Error("the user can not create train-job")
  360. // ctx.ServerError("the user can not create train-job", fmt.Errorf("the user can not create train-job"))
  361. // return
  362. //}
  363. t := time.Now()
  364. var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
  365. ctx.Data["job_name"] = jobName
  366. attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
  367. if err != nil {
  368. ctx.ServerError("GetAllUserAttachments failed:", err)
  369. return err
  370. }
  371. ctx.Data["attachments"] = attachs
  372. var resourcePools modelarts.ResourcePool
  373. if err = json.Unmarshal([]byte(setting.ResourcePools), &resourcePools); err != nil {
  374. ctx.ServerError("json.Unmarshal failed:", err)
  375. return err
  376. }
  377. ctx.Data["resource_pools"] = resourcePools.Info
  378. var engines modelarts.Engine
  379. if err = json.Unmarshal([]byte(setting.Engines), &engines); err != nil {
  380. ctx.ServerError("json.Unmarshal failed:", err)
  381. return err
  382. }
  383. ctx.Data["engines"] = engines.Info
  384. var versionInfos modelarts.VersionInfo
  385. if err = json.Unmarshal([]byte(setting.EngineVersions), &versionInfos); err != nil {
  386. ctx.ServerError("json.Unmarshal failed:", err)
  387. return err
  388. }
  389. ctx.Data["engine_versions"] = versionInfos.Version
  390. var flavorInfos modelarts.Flavor
  391. if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil {
  392. ctx.ServerError("json.Unmarshal failed:", err)
  393. return err
  394. }
  395. ctx.Data["flavor_infos"] = flavorInfos.Info
  396. outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath
  397. ctx.Data["train_url"] = outputObsPath
  398. ctx.Data["params"] = ""
  399. ctx.Data["branchName"] = ctx.Repo.BranchName
  400. configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom)
  401. if err != nil {
  402. ctx.ServerError("getConfigList failed:", err)
  403. return err
  404. }
  405. ctx.Data["config_list"] = configList.ParaConfigs
  406. return nil
  407. }
  408. func trainJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) error {
  409. ctx.Data["PageIsCloudBrain"] = true
  410. //can, err := canUserCreateTrainJob(ctx.User.ID)
  411. //if err != nil {
  412. // ctx.ServerError("canUserCreateTrainJob", err)
  413. // return
  414. //}
  415. //
  416. //if !can {
  417. // log.Error("the user can not create train-job")
  418. // ctx.ServerError("the user can not create train-job", fmt.Errorf("the user can not create train-job"))
  419. // return
  420. //}
  421. t := time.Now()
  422. var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
  423. ctx.Data["job_name"] = jobName
  424. attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
  425. if err != nil {
  426. ctx.ServerError("GetAllUserAttachments failed:", err)
  427. return err
  428. }
  429. ctx.Data["attachments"] = attachs
  430. var resourcePools modelarts.ResourcePool
  431. if err = json.Unmarshal([]byte(setting.ResourcePools), &resourcePools); err != nil {
  432. ctx.ServerError("json.Unmarshal failed:", err)
  433. return err
  434. }
  435. ctx.Data["resource_pools"] = resourcePools.Info
  436. var engines modelarts.Engine
  437. if err = json.Unmarshal([]byte(setting.Engines), &engines); err != nil {
  438. ctx.ServerError("json.Unmarshal failed:", err)
  439. return err
  440. }
  441. ctx.Data["engines"] = engines.Info
  442. var versionInfos modelarts.VersionInfo
  443. if err = json.Unmarshal([]byte(setting.EngineVersions), &versionInfos); err != nil {
  444. ctx.ServerError("json.Unmarshal failed:", err)
  445. return err
  446. }
  447. ctx.Data["engine_versions"] = versionInfos.Version
  448. var flavorInfos modelarts.Flavor
  449. if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil {
  450. ctx.ServerError("json.Unmarshal failed:", err)
  451. return err
  452. }
  453. ctx.Data["flavor_infos"] = flavorInfos.Info
  454. outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath
  455. ctx.Data["train_url"] = outputObsPath
  456. configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom)
  457. if err != nil {
  458. ctx.ServerError("getConfigList failed:", err)
  459. return err
  460. }
  461. var Parameters modelarts.Parameters
  462. if err = json.Unmarshal([]byte(form.Params), &Parameters); err != nil {
  463. ctx.ServerError("json.Unmarshal failed:", err)
  464. return err
  465. }
  466. ctx.Data["params"] = Parameters.Parameter
  467. ctx.Data["config_list"] = configList.ParaConfigs
  468. ctx.Data["bootFile"] = form.BootFile
  469. ctx.Data["uuid"] = form.Attachment
  470. ctx.Data["branch_name"] = form.BranchName
  471. return nil
  472. }
  473. func TrainJobNewVersion(ctx *context.Context) {
  474. err := trainJobNewVersionDataPrepare(ctx)
  475. if err != nil {
  476. ctx.ServerError("get new train-job info failed", err)
  477. return
  478. }
  479. ctx.HTML(200, tplModelArtsTrainJobVersionNew)
  480. }
  481. func trainJobNewVersionDataPrepare(ctx *context.Context) error {
  482. ctx.Data["PageIsCloudBrain"] = true
  483. var jobID = ctx.Params(":jobid")
  484. var versionName = ctx.Query("version_name")
  485. // canNewJob, err := canUserCreateTrainJobVersion(ctx, jobID, versionName)
  486. // if err != nil {
  487. // ctx.ServerError("canNewJob can info failed", err)
  488. // return err
  489. // }
  490. task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, versionName)
  491. if err != nil {
  492. log.Error("GetCloudbrainByJobIDAndVersionName(%s) failed:%v", jobID, err.Error())
  493. return err
  494. }
  495. t := time.Now()
  496. var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
  497. ctx.Data["job_name"] = task.JobName
  498. attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
  499. if err != nil {
  500. ctx.ServerError("GetAllUserAttachments failed:", err)
  501. return err
  502. }
  503. ctx.Data["attachments"] = attachs
  504. var resourcePools modelarts.ResourcePool
  505. if err = json.Unmarshal([]byte(setting.ResourcePools), &resourcePools); err != nil {
  506. ctx.ServerError("json.Unmarshal failed:", err)
  507. return err
  508. }
  509. ctx.Data["resource_pools"] = resourcePools.Info
  510. var engines modelarts.Engine
  511. if err = json.Unmarshal([]byte(setting.Engines), &engines); err != nil {
  512. ctx.ServerError("json.Unmarshal failed:", err)
  513. return err
  514. }
  515. ctx.Data["engines"] = engines.Info
  516. var versionInfos modelarts.VersionInfo
  517. if err = json.Unmarshal([]byte(setting.EngineVersions), &versionInfos); err != nil {
  518. ctx.ServerError("json.Unmarshal failed:", err)
  519. return err
  520. }
  521. ctx.Data["engine_versions"] = versionInfos.Version
  522. var flavorInfos modelarts.Flavor
  523. if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil {
  524. ctx.ServerError("json.Unmarshal failed:", err)
  525. return err
  526. }
  527. ctx.Data["flavor_infos"] = flavorInfos.Info
  528. var Parameters modelarts.Parameters
  529. if err = json.Unmarshal([]byte(task.Parameters), &Parameters); err != nil {
  530. ctx.ServerError("json.Unmarshal failed:", err)
  531. return err
  532. }
  533. ctx.Data["params"] = Parameters.Parameter
  534. outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath
  535. ctx.Data["train_url"] = outputObsPath
  536. branches, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
  537. if err != nil {
  538. ctx.ServerError("GetBranches error:", err)
  539. return err
  540. }
  541. ctx.Data["branches"] = branches
  542. ctx.Data["branch_name"] = task.BranchName
  543. ctx.Data["description"] = task.Description
  544. ctx.Data["boot_file"] = task.BootFile
  545. ctx.Data["dataset_name"] = task.DatasetName
  546. ctx.Data["work_server_number"] = task.WorkServerNumber
  547. ctx.Data["flavor_name"] = task.FlavorName
  548. ctx.Data["engine_name"] = task.EngineName
  549. ctx.Data["uuid"] = task.Uuid
  550. ctx.Data["flavor_code"] = task.FlavorCode
  551. ctx.Data["engine_id"] = task.EngineID
  552. configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom)
  553. if err != nil {
  554. ctx.ServerError("getConfigList failed:", err)
  555. return err
  556. }
  557. ctx.Data["config_list"] = configList.ParaConfigs
  558. return nil
  559. }
  560. func versionErrorDataPrepare(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) error {
  561. ctx.Data["PageIsCloudBrain"] = true
  562. var jobID = ctx.Params(":jobid")
  563. // var versionName = ctx.Params(":version-name")
  564. var versionName = ctx.Query("version_name")
  565. task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, versionName)
  566. if err != nil {
  567. log.Error("GetCloudbrainByJobIDAndVersionName(%s) failed:%v", jobID, err.Error())
  568. return err
  569. }
  570. t := time.Now()
  571. var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
  572. ctx.Data["job_name"] = task.JobName
  573. attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
  574. if err != nil {
  575. ctx.ServerError("GetAllUserAttachments failed:", err)
  576. return err
  577. }
  578. ctx.Data["attachments"] = attachs
  579. var resourcePools modelarts.ResourcePool
  580. if err = json.Unmarshal([]byte(setting.ResourcePools), &resourcePools); err != nil {
  581. ctx.ServerError("json.Unmarshal failed:", err)
  582. return err
  583. }
  584. ctx.Data["resource_pools"] = resourcePools.Info
  585. var engines modelarts.Engine
  586. if err = json.Unmarshal([]byte(setting.Engines), &engines); err != nil {
  587. ctx.ServerError("json.Unmarshal failed:", err)
  588. return err
  589. }
  590. ctx.Data["engines"] = engines.Info
  591. var versionInfos modelarts.VersionInfo
  592. if err = json.Unmarshal([]byte(setting.EngineVersions), &versionInfos); err != nil {
  593. ctx.ServerError("json.Unmarshal failed:", err)
  594. return err
  595. }
  596. ctx.Data["engine_versions"] = versionInfos.Version
  597. var flavorInfos modelarts.Flavor
  598. if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil {
  599. ctx.ServerError("json.Unmarshal failed:", err)
  600. return err
  601. }
  602. ctx.Data["flavor_infos"] = flavorInfos.Info
  603. var Parameters modelarts.Parameters
  604. if err = json.Unmarshal([]byte(form.Params), &Parameters); err != nil {
  605. ctx.ServerError("json.Unmarshal failed:", err)
  606. return err
  607. }
  608. ctx.Data["params"] = Parameters.Parameter
  609. outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath
  610. ctx.Data["train_url"] = outputObsPath
  611. branches, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
  612. if err != nil {
  613. ctx.ServerError("GetBranches error:", err)
  614. return err
  615. }
  616. ctx.Data["branches"] = branches
  617. ctx.Data["description"] = form.Description
  618. ctx.Data["dataset_name"] = task.DatasetName
  619. ctx.Data["work_server_number"] = form.WorkServerNumber
  620. ctx.Data["flavor_name"] = form.FlavorName
  621. ctx.Data["engine_name"] = form.EngineName
  622. ctx.Data["flavor_code"] = task.FlavorCode
  623. ctx.Data["engine_id"] = task.EngineID
  624. ctx.Data["version_name"] = form.VersionName
  625. ctx.Data["bootFile"] = form.BootFile
  626. ctx.Data["uuid"] = form.Attachment
  627. ctx.Data["branch_name"] = form.BranchName
  628. configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom)
  629. if err != nil {
  630. ctx.ServerError("getConfigList failed:", err)
  631. return err
  632. }
  633. ctx.Data["config_list"] = configList.ParaConfigs
  634. return nil
  635. }
  636. func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) {
  637. ctx.Data["PageIsTrainJob"] = true
  638. VersionOutputPath := modelarts.GetVersionOutputPathByTotalVersionCount(modelarts.TotalVersionCount)
  639. jobName := form.JobName
  640. uuid := form.Attachment
  641. description := form.Description
  642. workServerNumber := form.WorkServerNumber
  643. engineID := form.EngineID
  644. bootFile := form.BootFile
  645. flavorCode := form.Flavor
  646. params := form.Params
  647. poolID := form.PoolID
  648. isSaveParam := form.IsSaveParam
  649. repo := ctx.Repo.Repository
  650. codeLocalPath := setting.JobPath + jobName + modelarts.CodePath
  651. codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath
  652. outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath + VersionOutputPath + "/"
  653. logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath + VersionOutputPath + "/"
  654. dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + uuid + "/"
  655. branch_name := form.BranchName
  656. isLatestVersion := modelarts.IsLatestVersion
  657. FlavorName := form.FlavorName
  658. VersionCount := modelarts.VersionCount
  659. EngineName := form.EngineName
  660. count, err := models.GetCloudbrainTrainJobCountByUserID(ctx.User.ID)
  661. if err != nil {
  662. log.Error("GetCloudbrainTrainJobCountByUserID failed:%v", err, ctx.Data["MsgID"])
  663. trainJobErrorNewDataPrepare(ctx, form)
  664. ctx.RenderWithErr("system error", tplModelArtsTrainJobNew, &form)
  665. return
  666. } else {
  667. if count >= 1 {
  668. log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
  669. trainJobErrorNewDataPrepare(ctx, form)
  670. ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplModelArtsTrainJobNew, &form)
  671. return
  672. }
  673. }
  674. if err := paramCheckCreateTrainJob(form); err != nil {
  675. log.Error("paramCheckCreateTrainJob failed:(%v)", err)
  676. trainJobErrorNewDataPrepare(ctx, form)
  677. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form)
  678. return
  679. }
  680. // attach, err := models.GetAttachmentByUUID(uuid)
  681. // if err != nil {
  682. // log.Error("GetAttachmentByUUID(%s) failed:%v", uuid, err.Error())
  683. // return
  684. // }
  685. //todo: del the codeLocalPath
  686. _, err = ioutil.ReadDir(codeLocalPath)
  687. if err == nil {
  688. os.RemoveAll(codeLocalPath)
  689. } else {
  690. log.Error("创建任务失败,原代码还未删除,请重试!: %s (%v)", repo.FullName(), err)
  691. versionErrorDataPrepare(ctx, form)
  692. ctx.RenderWithErr("创建任务失败,原代码还未删除,请重试!", tplModelArtsTrainJobVersionNew, &form)
  693. return
  694. }
  695. // os.RemoveAll(codeLocalPath)
  696. gitRepo, _ := git.OpenRepository(repo.RepoPath())
  697. commitID, _ := gitRepo.GetBranchCommitID(branch_name)
  698. if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{
  699. Branch: branch_name,
  700. }); err != nil {
  701. log.Error("创建任务失败,服务器超时!: %s (%v)", repo.FullName(), err)
  702. trainJobErrorNewDataPrepare(ctx, form)
  703. ctx.RenderWithErr("创建任务失败,服务器超时!", tplModelArtsTrainJobNew, &form)
  704. return
  705. }
  706. //todo: upload code (send to file_server todo this work?)
  707. if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.OutputPath + VersionOutputPath + "/"); err != nil {
  708. log.Error("Failed to obsMkdir_output: %s (%v)", repo.FullName(), err)
  709. trainJobErrorNewDataPrepare(ctx, form)
  710. ctx.RenderWithErr("Failed to obsMkdir_output", tplModelArtsTrainJobNew, &form)
  711. return
  712. }
  713. if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.LogPath + VersionOutputPath + "/"); err != nil {
  714. log.Error("Failed to obsMkdir_log: %s (%v)", repo.FullName(), err)
  715. trainJobErrorNewDataPrepare(ctx, form)
  716. ctx.RenderWithErr("Failed to obsMkdir_log", tplModelArtsTrainJobNew, &form)
  717. return
  718. }
  719. // parentDir := VersionOutputPath + "/"
  720. if err := uploadCodeToObs(codeLocalPath, jobName, ""); err != nil {
  721. // if err := uploadCodeToObs(codeLocalPath, jobName, parentDir); err != nil {
  722. log.Error("Failed to uploadCodeToObs: %s (%v)", repo.FullName(), err)
  723. trainJobErrorNewDataPrepare(ctx, form)
  724. ctx.RenderWithErr("Failed to uploadCodeToObs", tplModelArtsTrainJobNew, &form)
  725. return
  726. }
  727. //todo: del local code?
  728. var parameters models.Parameters
  729. param := make([]models.Parameter, 0)
  730. param = append(param, models.Parameter{
  731. Label: modelarts.TrainUrl,
  732. Value: outputObsPath,
  733. }, models.Parameter{
  734. Label: modelarts.DataUrl,
  735. Value: dataPath,
  736. })
  737. if len(params) != 0 {
  738. err := json.Unmarshal([]byte(params), &parameters)
  739. if err != nil {
  740. log.Error("Failed to Unmarshal params: %s (%v)", params, err)
  741. trainJobErrorNewDataPrepare(ctx, form)
  742. ctx.RenderWithErr("运行参数错误", tplModelArtsTrainJobNew, &form)
  743. return
  744. }
  745. for _, parameter := range parameters.Parameter {
  746. if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl {
  747. param = append(param, models.Parameter{
  748. Label: parameter.Label,
  749. Value: parameter.Value,
  750. })
  751. }
  752. }
  753. }
  754. //save param config
  755. if isSaveParam == "on" {
  756. if form.ParameterTemplateName == "" {
  757. log.Error("ParameterTemplateName is empty")
  758. trainJobNewDataPrepare(ctx)
  759. ctx.RenderWithErr("保存作业参数时,作业参数名称不能为空", tplModelArtsTrainJobNew, &form)
  760. return
  761. }
  762. _, err := modelarts.CreateTrainJobConfig(models.CreateConfigParams{
  763. ConfigName: form.ParameterTemplateName,
  764. Description: form.PrameterDescription,
  765. DataUrl: dataPath,
  766. AppUrl: codeObsPath,
  767. BootFileUrl: codeObsPath + bootFile,
  768. TrainUrl: outputObsPath,
  769. Flavor: models.Flavor{
  770. Code: flavorCode,
  771. },
  772. WorkServerNum: workServerNumber,
  773. EngineID: int64(engineID),
  774. LogUrl: logObsPath,
  775. PoolID: poolID,
  776. Parameter: param,
  777. })
  778. if err != nil {
  779. log.Error("Failed to CreateTrainJobConfig: %v", err)
  780. trainJobErrorNewDataPrepare(ctx, form)
  781. ctx.RenderWithErr("保存作业参数失败:"+err.Error(), tplModelArtsTrainJobNew, &form)
  782. return
  783. }
  784. }
  785. req := &modelarts.GenerateTrainJobReq{
  786. JobName: jobName,
  787. DataUrl: dataPath,
  788. Description: description,
  789. CodeObsPath: codeObsPath,
  790. BootFileUrl: codeObsPath + bootFile,
  791. BootFile: bootFile,
  792. TrainUrl: outputObsPath,
  793. FlavorCode: flavorCode,
  794. WorkServerNumber: workServerNumber,
  795. EngineID: int64(engineID),
  796. LogUrl: logObsPath,
  797. PoolID: poolID,
  798. Uuid: uuid,
  799. Parameters: parameters.Parameter,
  800. CommitID: commitID,
  801. IsLatestVersion: isLatestVersion,
  802. BranchName: branch_name,
  803. Params: form.Params,
  804. FlavorName: FlavorName,
  805. EngineName: EngineName,
  806. VersionCount: VersionCount,
  807. TotalVersionCount: modelarts.TotalVersionCount,
  808. }
  809. //将params转换Parameters.Parameter,出错时返回给前端
  810. var Parameters modelarts.Parameters
  811. if err := json.Unmarshal([]byte(params), &Parameters); err != nil {
  812. ctx.ServerError("json.Unmarshal failed:", err)
  813. return
  814. }
  815. err = modelarts.GenerateTrainJob(ctx, req)
  816. if err != nil {
  817. log.Error("GenerateTrainJob failed:%v", err.Error())
  818. trainJobErrorNewDataPrepare(ctx, form)
  819. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form)
  820. return
  821. }
  822. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job")
  823. }
  824. func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) {
  825. ctx.Data["PageIsTrainJob"] = true
  826. var jobID = ctx.Params(":jobid")
  827. count, err := models.GetCloudbrainTrainJobCountByUserID(ctx.User.ID)
  828. if err != nil {
  829. log.Error("GetCloudbrainTrainJobCountByUserID failed:%v", err, ctx.Data["MsgID"])
  830. versionErrorDataPrepare(ctx, form)
  831. ctx.RenderWithErr("system error", tplModelArtsTrainJobVersionNew, &form)
  832. return
  833. } else {
  834. if count >= 1 {
  835. log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
  836. versionErrorDataPrepare(ctx, form)
  837. ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplModelArtsTrainJobVersionNew, &form)
  838. return
  839. }
  840. }
  841. latestTask, err := models.GetCloudbrainByJobIDAndIsLatestVersion(jobID, modelarts.IsLatestVersion)
  842. if err != nil {
  843. ctx.ServerError("GetCloudbrainByJobIDAndIsLatestVersion faild:", err)
  844. return
  845. }
  846. VersionOutputPath := modelarts.GetVersionOutputPathByTotalVersionCount(latestTask.TotalVersionCount + 1)
  847. jobName := form.JobName
  848. uuid := form.Attachment
  849. description := form.Description
  850. workServerNumber := form.WorkServerNumber
  851. engineID := form.EngineID
  852. bootFile := form.BootFile
  853. flavorCode := form.Flavor
  854. params := form.Params
  855. poolID := form.PoolID
  856. isSaveParam := form.IsSaveParam
  857. repo := ctx.Repo.Repository
  858. codeLocalPath := setting.JobPath + jobName + modelarts.CodePath
  859. codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath + VersionOutputPath + "/"
  860. outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath + VersionOutputPath + "/"
  861. logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath + VersionOutputPath + "/"
  862. dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + uuid + "/"
  863. branch_name := form.BranchName
  864. PreVersionName := form.VersionName
  865. FlavorName := form.FlavorName
  866. EngineName := form.EngineName
  867. isLatestVersion := modelarts.IsLatestVersion
  868. //判断权限
  869. canNewJob, _ := canUserCreateTrainJobVersion(ctx, latestTask.UserID)
  870. if !canNewJob {
  871. ctx.RenderWithErr("user cann't new trainjob", tplModelArtsTrainJobVersionNew, &form)
  872. return
  873. }
  874. if err := paramCheckCreateTrainJob(form); err != nil {
  875. log.Error("paramCheckCreateTrainJob failed:(%v)", err)
  876. versionErrorDataPrepare(ctx, form)
  877. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobVersionNew, &form)
  878. return
  879. }
  880. // attach, err := models.GetAttachmentByUUID(uuid)
  881. // if err != nil {
  882. // log.Error("GetAttachmentByUUID(%s) failed:%v", uuid, err.Error())
  883. // return
  884. // }
  885. //todo: del the codeLocalPath
  886. _, err = ioutil.ReadDir(codeLocalPath)
  887. if err == nil {
  888. os.RemoveAll(codeLocalPath)
  889. } else {
  890. log.Error("创建任务失败,原代码还未删除,请重试!: %s (%v)", repo.FullName(), err)
  891. versionErrorDataPrepare(ctx, form)
  892. ctx.RenderWithErr("创建任务失败,原代码还未删除,请重试!", tplModelArtsTrainJobVersionNew, &form)
  893. return
  894. }
  895. // os.RemoveAll(codeLocalPath)
  896. gitRepo, _ := git.OpenRepository(repo.RepoPath())
  897. commitID, _ := gitRepo.GetBranchCommitID(branch_name)
  898. if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{
  899. Branch: branch_name,
  900. }); err != nil {
  901. log.Error("创建任务失败,任务名称已存在!: %s (%v)", repo.FullName(), err)
  902. versionErrorDataPrepare(ctx, form)
  903. ctx.RenderWithErr("创建任务失败,任务名称已存在!", tplModelArtsTrainJobVersionNew, &form)
  904. return
  905. }
  906. //todo: upload code (send to file_server todo this work?)
  907. if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.OutputPath + VersionOutputPath + "/"); err != nil {
  908. log.Error("Failed to obsMkdir_output: %s (%v)", repo.FullName(), err)
  909. versionErrorDataPrepare(ctx, form)
  910. ctx.RenderWithErr("Failed to obsMkdir_output", tplModelArtsTrainJobVersionNew, &form)
  911. return
  912. }
  913. if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.LogPath + VersionOutputPath + "/"); err != nil {
  914. log.Error("Failed to obsMkdir_log: %s (%v)", repo.FullName(), err)
  915. versionErrorDataPrepare(ctx, form)
  916. ctx.RenderWithErr("Failed to obsMkdir_log", tplModelArtsTrainJobVersionNew, &form)
  917. return
  918. }
  919. parentDir := VersionOutputPath + "/"
  920. // parentDir := ""
  921. // if err := uploadCodeToObs(codeLocalPath, jobName, ""); err != nil {
  922. if err := uploadCodeToObs(codeLocalPath, jobName, parentDir); err != nil {
  923. log.Error("Failed to uploadCodeToObs: %s (%v)", repo.FullName(), err)
  924. versionErrorDataPrepare(ctx, form)
  925. ctx.RenderWithErr("Failed to uploadCodeToObs", tplModelArtsTrainJobVersionNew, &form)
  926. return
  927. }
  928. //todo: del local code?
  929. var parameters models.Parameters
  930. param := make([]models.Parameter, 0)
  931. param = append(param, models.Parameter{
  932. Label: modelarts.TrainUrl,
  933. Value: outputObsPath,
  934. }, models.Parameter{
  935. Label: modelarts.DataUrl,
  936. Value: dataPath,
  937. })
  938. if len(params) != 0 {
  939. err := json.Unmarshal([]byte(params), &parameters)
  940. if err != nil {
  941. log.Error("Failed to Unmarshal params: %s (%v)", params, err)
  942. versionErrorDataPrepare(ctx, form)
  943. ctx.RenderWithErr("运行参数错误", tplModelArtsTrainJobVersionNew, &form)
  944. return
  945. }
  946. for _, parameter := range parameters.Parameter {
  947. if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl {
  948. param = append(param, models.Parameter{
  949. Label: parameter.Label,
  950. Value: parameter.Value,
  951. })
  952. }
  953. }
  954. }
  955. //save param config
  956. if isSaveParam == "on" {
  957. if form.ParameterTemplateName == "" {
  958. log.Error("ParameterTemplateName is empty")
  959. versionErrorDataPrepare(ctx, form)
  960. ctx.RenderWithErr("保存作业参数时,作业参数名称不能为空", tplModelArtsTrainJobVersionNew, &form)
  961. return
  962. }
  963. _, err := modelarts.CreateTrainJobConfig(models.CreateConfigParams{
  964. ConfigName: form.ParameterTemplateName,
  965. Description: form.PrameterDescription,
  966. DataUrl: dataPath,
  967. AppUrl: codeObsPath,
  968. BootFileUrl: codeObsPath + bootFile,
  969. TrainUrl: outputObsPath,
  970. Flavor: models.Flavor{
  971. Code: flavorCode,
  972. },
  973. WorkServerNum: workServerNumber,
  974. EngineID: int64(engineID),
  975. LogUrl: logObsPath,
  976. PoolID: poolID,
  977. Parameter: parameters.Parameter,
  978. })
  979. if err != nil {
  980. log.Error("Failed to CreateTrainJobConfig: %v", err)
  981. versionErrorDataPrepare(ctx, form)
  982. ctx.RenderWithErr("保存作业参数失败:"+err.Error(), tplModelArtsTrainJobVersionNew, &form)
  983. return
  984. }
  985. }
  986. if err != nil {
  987. log.Error("getFlavorNameByEngineID(%s) failed:%v", engineID, err.Error())
  988. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobVersionNew, &form)
  989. return
  990. }
  991. task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, PreVersionName)
  992. if err != nil {
  993. log.Error("GetCloudbrainByJobIDAndVersionName(%s) failed:%v", jobID, err.Error())
  994. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobVersionNew, &form)
  995. return
  996. }
  997. req := &modelarts.GenerateTrainJobReq{
  998. JobName: task.JobName,
  999. DataUrl: dataPath,
  1000. Description: description,
  1001. CodeObsPath: codeObsPath,
  1002. BootFileUrl: codeObsPath + bootFile,
  1003. BootFile: bootFile,
  1004. TrainUrl: outputObsPath,
  1005. FlavorCode: flavorCode,
  1006. WorkServerNumber: workServerNumber,
  1007. IsLatestVersion: isLatestVersion,
  1008. EngineID: int64(engineID),
  1009. LogUrl: logObsPath,
  1010. PoolID: poolID,
  1011. Uuid: uuid,
  1012. Params: form.Params,
  1013. Parameters: parameters.Parameter,
  1014. PreVersionId: task.VersionID,
  1015. CommitID: commitID,
  1016. BranchName: branch_name,
  1017. FlavorName: FlavorName,
  1018. EngineName: EngineName,
  1019. PreVersionName: PreVersionName,
  1020. TotalVersionCount: latestTask.TotalVersionCount + 1,
  1021. }
  1022. err = modelarts.GenerateTrainJobVersion(ctx, req, jobID)
  1023. if err != nil {
  1024. log.Error("GenerateTrainJob failed:%v", err.Error())
  1025. versionErrorDataPrepare(ctx, form)
  1026. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobVersionNew, &form)
  1027. return
  1028. }
  1029. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job/" + jobID)
  1030. // ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow)
  1031. }
  1032. // readDir reads the directory named by dirname and returns
  1033. // a list of directory entries sorted by filename.
  1034. func readDir(dirname string) ([]os.FileInfo, error) {
  1035. f, err := os.Open(dirname)
  1036. if err != nil {
  1037. return nil, err
  1038. }
  1039. list, err := f.Readdir(100)
  1040. f.Close()
  1041. if err != nil {
  1042. //todo: can not upload empty folder
  1043. if err == io.EOF {
  1044. return nil, nil
  1045. }
  1046. return nil, err
  1047. }
  1048. //sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
  1049. return list, nil
  1050. }
  1051. func uploadCodeToObs(codePath, jobName, parentDir string) error {
  1052. files, err := readDir(codePath)
  1053. if err != nil {
  1054. log.Error("readDir(%s) failed: %s", codePath, err.Error())
  1055. return err
  1056. }
  1057. for _, file := range files {
  1058. if file.IsDir() {
  1059. input := &obs.PutObjectInput{}
  1060. input.Bucket = setting.Bucket
  1061. input.Key = parentDir + file.Name() + "/"
  1062. _, err = storage.ObsCli.PutObject(input)
  1063. if err != nil {
  1064. log.Error("PutObject(%s) failed: %s", input.Key, err.Error())
  1065. return err
  1066. }
  1067. if err = uploadCodeToObs(codePath+file.Name()+"/", jobName, parentDir+file.Name()+"/"); err != nil {
  1068. log.Error("uploadCodeToObs(%s) failed: %s", file.Name(), err.Error())
  1069. return err
  1070. }
  1071. } else {
  1072. input := &obs.PutFileInput{}
  1073. input.Bucket = setting.Bucket
  1074. input.Key = setting.CodePathPrefix + jobName + "/code/" + parentDir + file.Name()
  1075. input.SourceFile = codePath + file.Name()
  1076. _, err = storage.ObsCli.PutFile(input)
  1077. if err != nil {
  1078. log.Error("PutFile(%s) failed: %s", input.SourceFile, err.Error())
  1079. return err
  1080. }
  1081. }
  1082. }
  1083. return nil
  1084. }
  1085. func obsMkdir(dir string) error {
  1086. input := &obs.PutObjectInput{}
  1087. input.Bucket = setting.Bucket
  1088. input.Key = dir
  1089. _, err := storage.ObsCli.PutObject(input)
  1090. if err != nil {
  1091. log.Error("PutObject(%s) failed: %s", input.Key, err.Error())
  1092. return err
  1093. }
  1094. return nil
  1095. }
  1096. func paramCheckCreateTrainJob(form auth.CreateModelArtsTrainJobForm) error {
  1097. if !strings.HasSuffix(form.BootFile, ".py") {
  1098. log.Error("the boot file(%s) must be a python file", form.BootFile)
  1099. return errors.New("启动文件必须是python文件")
  1100. }
  1101. if form.WorkServerNumber > 25 || form.WorkServerNumber < 1 {
  1102. log.Error("the WorkServerNumber(%d) must be in (1,25)", form.WorkServerNumber)
  1103. return errors.New("计算节点数必须在1-25之间")
  1104. }
  1105. return nil
  1106. }
  1107. func paramCheckCreateInferenceJob(form auth.CreateModelArtsInferenceJobForm) error {
  1108. if !strings.HasSuffix(form.BootFile, ".py") {
  1109. log.Error("the boot file(%s) must be a python file", form.BootFile)
  1110. return errors.New("启动文件必须是python文件")
  1111. }
  1112. if form.WorkServerNumber > 25 || form.WorkServerNumber < 1 {
  1113. log.Error("the WorkServerNumber(%d) must be in (1,25)", form.WorkServerNumber)
  1114. return errors.New("计算节点数必须在1-25之间")
  1115. }
  1116. return nil
  1117. }
  1118. func TrainJobShow(ctx *context.Context) {
  1119. ctx.Data["PageIsCloudBrain"] = true
  1120. var jobID = ctx.Params(":jobid")
  1121. repo := ctx.Repo.Repository
  1122. page := ctx.QueryInt("page")
  1123. if page <= 0 {
  1124. page = 1
  1125. }
  1126. VersionListTasks, VersionListCount, err := models.CloudbrainsVersionList(&models.CloudbrainsOptions{
  1127. ListOptions: models.ListOptions{
  1128. Page: page,
  1129. PageSize: setting.UI.IssuePagingNum,
  1130. },
  1131. RepoID: repo.ID,
  1132. Type: models.TypeCloudBrainTwo,
  1133. JobType: string(models.JobTypeTrain),
  1134. JobID: jobID,
  1135. })
  1136. if err != nil {
  1137. log.Error("GetVersionListTasks(%s) failed:%v", jobID, err.Error())
  1138. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  1139. return
  1140. }
  1141. //设置权限
  1142. canNewJob, err := canUserCreateTrainJobVersion(ctx, VersionListTasks[0].UserID)
  1143. if err != nil {
  1144. ctx.ServerError("canNewJob failed", err)
  1145. return
  1146. }
  1147. ctx.Data["canNewJob"] = canNewJob
  1148. //将运行参数转化为epoch_size = 3, device_target = Ascend的格式
  1149. for i, _ := range VersionListTasks {
  1150. var parameters models.Parameters
  1151. err := json.Unmarshal([]byte(VersionListTasks[i].Parameters), &parameters)
  1152. if err != nil {
  1153. log.Error("Failed to Unmarshal Parameters: %s (%v)", VersionListTasks[i].Parameters, err)
  1154. trainJobNewDataPrepare(ctx)
  1155. return
  1156. }
  1157. if len(parameters.Parameter) > 0 {
  1158. paramTemp := ""
  1159. for _, Parameter := range parameters.Parameter {
  1160. param := Parameter.Label + " = " + Parameter.Value + "; "
  1161. paramTemp = paramTemp + param
  1162. }
  1163. VersionListTasks[i].Parameters = paramTemp[:len(paramTemp)-2]
  1164. } else {
  1165. VersionListTasks[i].Parameters = ""
  1166. }
  1167. }
  1168. pager := context.NewPagination(VersionListCount, setting.UI.IssuePagingNum, page, 5)
  1169. pager.SetDefaultParams(ctx)
  1170. ctx.Data["Page"] = pager
  1171. ctx.Data["jobID"] = jobID
  1172. ctx.Data["jobName"] = VersionListTasks[0].JobName
  1173. ctx.Data["version_list_task"] = VersionListTasks
  1174. ctx.Data["version_list_count"] = VersionListCount
  1175. ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow)
  1176. }
  1177. func TrainJobGetLog(ctx *context.Context) {
  1178. ctx.Data["PageIsTrainJob"] = true
  1179. var jobID = ctx.Params(":jobid")
  1180. var logFileName = ctx.Query("file_name")
  1181. var baseLine = ctx.Query("base_line")
  1182. var order = ctx.Query("order")
  1183. if order != modelarts.OrderDesc && order != modelarts.OrderAsc {
  1184. log.Error("order(%s) check failed", order)
  1185. ctx.HTML(http.StatusBadRequest, tplModelArtsTrainJobShow)
  1186. return
  1187. }
  1188. task, err := models.GetCloudbrainByJobID(jobID)
  1189. if err != nil {
  1190. log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error())
  1191. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  1192. return
  1193. }
  1194. result, err := modelarts.GetTrainJobLog(jobID, strconv.FormatInt(task.VersionID, 10), baseLine, logFileName, order, modelarts.Lines)
  1195. if err != nil {
  1196. log.Error("GetTrainJobLog(%s) failed:%v", jobID, err.Error())
  1197. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  1198. return
  1199. }
  1200. ctx.Data["log"] = result
  1201. //ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow)
  1202. }
  1203. func trainJobGetLog(jobID string) (*models.GetTrainJobLogFileNamesResult, *models.GetTrainJobLogResult, error) {
  1204. task, err := models.GetCloudbrainByJobID(jobID)
  1205. if err != nil {
  1206. log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error())
  1207. return nil, nil, err
  1208. }
  1209. resultLogFile, err := modelarts.GetTrainJobLogFileNames(jobID, strconv.FormatInt(task.VersionID, 10))
  1210. if err != nil {
  1211. log.Error("GetTrainJobLogFileNames(%s) failed:%v", jobID, err.Error())
  1212. return nil, nil, err
  1213. }
  1214. result, err := modelarts.GetTrainJobLog(jobID, strconv.FormatInt(task.VersionID, 10), "", resultLogFile.LogFileList[0], modelarts.OrderDesc, modelarts.Lines)
  1215. if err != nil {
  1216. log.Error("GetTrainJobLog(%s) failed:%v", jobID, err.Error())
  1217. return nil, nil, err
  1218. }
  1219. return resultLogFile, result, err
  1220. }
  1221. func TrainJobDel(ctx *context.Context) {
  1222. var jobID = ctx.Params(":jobid")
  1223. repo := ctx.Repo.Repository
  1224. VersionListTasks, _, err := models.CloudbrainsVersionList(&models.CloudbrainsOptions{
  1225. RepoID: repo.ID,
  1226. Type: models.TypeCloudBrainTwo,
  1227. JobType: string(models.JobTypeTrain),
  1228. JobID: jobID,
  1229. })
  1230. if err != nil {
  1231. ctx.ServerError("get VersionListTasks failed", err)
  1232. return
  1233. }
  1234. //删除modelarts上的任务记录
  1235. _, err = modelarts.DelTrainJob(jobID)
  1236. if err != nil {
  1237. log.Error("DelTrainJob(%s) failed:%v", jobID, err.Error())
  1238. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  1239. return
  1240. }
  1241. //删除数据库Cloudbrain表的记录
  1242. for _, task := range VersionListTasks {
  1243. err = models.DeleteJob(&task.Cloudbrain)
  1244. if err != nil {
  1245. ctx.ServerError("DeleteJob failed", err)
  1246. return
  1247. }
  1248. }
  1249. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job")
  1250. }
  1251. func TrainJobStop(ctx *context.Context) {
  1252. var jobID = ctx.Params(":jobid")
  1253. task, err := models.GetCloudbrainByJobID(jobID)
  1254. if err != nil {
  1255. log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error())
  1256. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  1257. return
  1258. }
  1259. _, err = modelarts.StopTrainJob(jobID, strconv.FormatInt(task.VersionID, 10))
  1260. if err != nil {
  1261. log.Error("StopTrainJob(%s) failed:%v", task.JobName, err.Error())
  1262. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  1263. return
  1264. }
  1265. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job")
  1266. }
  1267. func canUserCreateTrainJob(uid int64) (bool, error) {
  1268. org, err := models.GetOrgByName(setting.AllowedOrg)
  1269. if err != nil {
  1270. log.Error("get allowed org failed: ", setting.AllowedOrg)
  1271. return false, err
  1272. }
  1273. return org.IsOrgMember(uid)
  1274. }
  1275. func canUserCreateTrainJobVersion(ctx *context.Context, userID int64) (bool, error) {
  1276. if ctx == nil || ctx.User == nil {
  1277. log.Error("user unlogin!")
  1278. return false, nil
  1279. }
  1280. if userID == ctx.User.ID || ctx.User.IsAdmin {
  1281. return true, nil
  1282. } else {
  1283. log.Error("Only user itself and admin can new trainjob!")
  1284. return false, nil
  1285. }
  1286. }
  1287. func TrainJobGetConfigList(ctx *context.Context) {
  1288. ctx.Data["PageIsTrainJob"] = true
  1289. var jobID = ctx.Params(":jobid")
  1290. var logFileName = ctx.Query("file_name")
  1291. var baseLine = ctx.Query("base_line")
  1292. var order = ctx.Query("order")
  1293. if order != modelarts.OrderDesc && order != modelarts.OrderAsc {
  1294. log.Error("order(%s) check failed", order)
  1295. ctx.HTML(http.StatusBadRequest, tplModelArtsTrainJobShow)
  1296. return
  1297. }
  1298. task, err := models.GetCloudbrainByJobID(jobID)
  1299. if err != nil {
  1300. log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error())
  1301. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  1302. return
  1303. }
  1304. result, err := modelarts.GetTrainJobLog(jobID, strconv.FormatInt(task.VersionID, 10), baseLine, logFileName, order, modelarts.Lines)
  1305. if err != nil {
  1306. log.Error("GetTrainJobLog(%s) failed:%v", jobID, err.Error())
  1307. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  1308. return
  1309. }
  1310. ctx.Data["log"] = result
  1311. //ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow)
  1312. }
  1313. func getConfigList(perPage, page int, sortBy, order, searchContent, configType string) (*models.GetConfigListResult, error) {
  1314. var result models.GetConfigListResult
  1315. list, err := modelarts.GetConfigList(perPage, page, sortBy, order, searchContent, configType)
  1316. if err != nil {
  1317. log.Error("GetConfigList failed:", err)
  1318. return &result, err
  1319. }
  1320. for _, config := range list.ParaConfigs {
  1321. paraConfig, err := modelarts.GetParaConfig(config.ConfigName, configType)
  1322. if err != nil {
  1323. log.Error("GetParaConfig failed:", err)
  1324. return &result, err
  1325. }
  1326. config.Result = paraConfig
  1327. }
  1328. return list, nil
  1329. }
  1330. func ModelDownload(ctx *context.Context) {
  1331. var (
  1332. err error
  1333. )
  1334. var jobID = ctx.Params(":jobid")
  1335. versionName := ctx.Query("version_name")
  1336. parentDir := ctx.Query("parent_dir")
  1337. fileName := ctx.Query("file_name")
  1338. log.Info("DownloadSingleModelFile start.")
  1339. task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, versionName)
  1340. if err != nil {
  1341. log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error())
  1342. return
  1343. }
  1344. path := strings.TrimPrefix(path.Join(setting.TrainJobModelPath, task.JobName, setting.OutPutPath, versionName, parentDir, fileName), "/")
  1345. log.Info("Download path is:%s", path)
  1346. url, err := storage.GetObsCreateSignedUrlByBucketAndKey(setting.Bucket, path)
  1347. if err != nil {
  1348. log.Error("GetObsCreateSignedUrl failed: %v", err.Error(), ctx.Data["msgID"])
  1349. ctx.ServerError("GetObsCreateSignedUrl", err)
  1350. return
  1351. }
  1352. http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently)
  1353. }
  1354. func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInferenceJobForm) {
  1355. ctx.Data["PageIsTrainJob"] = true
  1356. jobName := form.JobName
  1357. uuid := form.Attachment
  1358. description := form.Description
  1359. workServerNumber := form.WorkServerNumber
  1360. engineID := form.EngineID
  1361. bootFile := form.BootFile
  1362. flavorCode := form.Flavor
  1363. params := form.Params
  1364. poolID := form.PoolID
  1365. repo := ctx.Repo.Repository
  1366. codeLocalPath := setting.JobPath + jobName + modelarts.CodePath
  1367. codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath
  1368. resultObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.ResultPath
  1369. logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath
  1370. dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + uuid + "/"
  1371. branch_name := form.BranchName
  1372. FlavorName := form.FlavorName
  1373. EngineName := form.EngineName
  1374. trainUrl := form.TrainUrl
  1375. ckptName := form.CkptName
  1376. count, err := models.GetCloudbrainTrainJobCountByUserID(ctx.User.ID)
  1377. if err != nil {
  1378. log.Error("GetCloudbrainTrainJobCountByUserID failed:%v", err, ctx.Data["MsgID"])
  1379. inferenceJobErrorNewDataPrepare(ctx, form)
  1380. ctx.RenderWithErr("system error", tplModelArtsInferenceJobNew, &form)
  1381. return
  1382. } else {
  1383. if count >= 1 {
  1384. log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
  1385. inferenceJobErrorNewDataPrepare(ctx, form)
  1386. ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplModelArtsInferenceJobNew, &form)
  1387. return
  1388. }
  1389. }
  1390. if err := paramCheckCreateInferenceJob(form); err != nil {
  1391. log.Error("paramCheckCreateInferenceJob failed:(%v)", err)
  1392. inferenceJobErrorNewDataPrepare(ctx, form)
  1393. ctx.RenderWithErr(err.Error(), tplModelArtsInferenceJobNew, &form)
  1394. return
  1395. }
  1396. //todo: del the codeLocalPath
  1397. _, err = ioutil.ReadDir(codeLocalPath)
  1398. if err == nil {
  1399. os.RemoveAll(codeLocalPath)
  1400. } else {
  1401. log.Error("创建任务失败,原代码还未删除,请重试!: %s (%v)", repo.FullName(), err)
  1402. inferenceJobErrorNewDataPrepare(ctx, form)
  1403. ctx.RenderWithErr("创建任务失败,原代码还未删除,请重试!", tplModelArtsInferenceJobNew, &form)
  1404. return
  1405. }
  1406. // os.RemoveAll(codeLocalPath)
  1407. gitRepo, _ := git.OpenRepository(repo.RepoPath())
  1408. commitID, _ := gitRepo.GetBranchCommitID(branch_name)
  1409. if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{
  1410. Branch: branch_name,
  1411. }); err != nil {
  1412. log.Error("创建任务失败,服务器超时!: %s (%v)", repo.FullName(), err)
  1413. inferenceJobErrorNewDataPrepare(ctx, form)
  1414. ctx.RenderWithErr("创建任务失败,服务器超时!", tplModelArtsInferenceJobNew, &form)
  1415. return
  1416. }
  1417. //todo: upload code (send to file_server todo this work?)
  1418. if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.ResultPath); err != nil {
  1419. log.Error("Failed to obsMkdir_result: %s (%v)", repo.FullName(), err)
  1420. inferenceJobErrorNewDataPrepare(ctx, form)
  1421. ctx.RenderWithErr("Failed to obsMkdir_result", tplModelArtsInferenceJobNew, &form)
  1422. return
  1423. }
  1424. if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.LogPath); err != nil {
  1425. log.Error("Failed to obsMkdir_log: %s (%v)", repo.FullName(), err)
  1426. inferenceJobErrorNewDataPrepare(ctx, form)
  1427. ctx.RenderWithErr("Failed to obsMkdir_log", tplModelArtsInferenceJobNew, &form)
  1428. return
  1429. }
  1430. // parentDir := VersionOutputPath + "/"
  1431. if err := uploadCodeToObs(codeLocalPath, jobName, ""); err != nil {
  1432. // if err := uploadCodeToObs(codeLocalPath, jobName, parentDir); err != nil {
  1433. log.Error("Failed to uploadCodeToObs: %s (%v)", repo.FullName(), err)
  1434. inferenceJobErrorNewDataPrepare(ctx, form)
  1435. ctx.RenderWithErr("Failed to uploadCodeToObs", tplModelArtsInferenceJobNew, &form)
  1436. return
  1437. }
  1438. //todo: del local code?
  1439. var parameters models.Parameters
  1440. param := make([]models.Parameter, 0)
  1441. param = append(param, models.Parameter{
  1442. Label: modelarts.ResultUrl,
  1443. Value: "s3:/" + resultObsPath,
  1444. }, models.Parameter{
  1445. Label: modelarts.CkptName,
  1446. Value: ckptName,
  1447. })
  1448. if len(params) != 0 {
  1449. err := json.Unmarshal([]byte(params), &parameters)
  1450. if err != nil {
  1451. log.Error("Failed to Unmarshal params: %s (%v)", params, err)
  1452. inferenceJobErrorNewDataPrepare(ctx, form)
  1453. ctx.RenderWithErr("运行参数错误", tplModelArtsInferenceJobNew, &form)
  1454. return
  1455. }
  1456. for _, parameter := range parameters.Parameter {
  1457. if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl {
  1458. param = append(param, models.Parameter{
  1459. Label: parameter.Label,
  1460. Value: parameter.Value,
  1461. })
  1462. }
  1463. }
  1464. }
  1465. req := &modelarts.GenerateInferenceJobReq{
  1466. JobName: jobName,
  1467. DataUrl: dataPath,
  1468. Description: description,
  1469. CodeObsPath: codeObsPath,
  1470. BootFileUrl: codeObsPath + bootFile,
  1471. BootFile: bootFile,
  1472. TrainUrl: trainUrl,
  1473. FlavorCode: flavorCode,
  1474. WorkServerNumber: workServerNumber,
  1475. EngineID: int64(engineID),
  1476. LogUrl: logObsPath,
  1477. PoolID: poolID,
  1478. Uuid: uuid,
  1479. Parameters: param, //modelarts训练时用到
  1480. CommitID: commitID,
  1481. BranchName: branch_name,
  1482. Params: form.Params,
  1483. FlavorName: FlavorName,
  1484. EngineName: EngineName,
  1485. }
  1486. //将params转换Parameters.Parameter,出错时返回给前端
  1487. var Parameters modelarts.Parameters
  1488. if err := json.Unmarshal([]byte(params), &Parameters); err != nil {
  1489. ctx.ServerError("json.Unmarshal failed:", err)
  1490. return
  1491. }
  1492. err = modelarts.GenerateInferenceJob(ctx, req)
  1493. if err != nil {
  1494. log.Error("GenerateTrainJob failed:%v", err.Error())
  1495. inferenceJobErrorNewDataPrepare(ctx, form)
  1496. ctx.RenderWithErr(err.Error(), tplModelArtsInferenceJobNew, &form)
  1497. return
  1498. }
  1499. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/inference-job")
  1500. }
  1501. func InferenceJobIndex(ctx *context.Context) {
  1502. MustEnableModelArts(ctx)
  1503. repo := ctx.Repo.Repository
  1504. page := ctx.QueryInt("page")
  1505. if page <= 0 {
  1506. page = 1
  1507. }
  1508. tasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{
  1509. ListOptions: models.ListOptions{
  1510. Page: page,
  1511. PageSize: setting.UI.IssuePagingNum,
  1512. },
  1513. RepoID: repo.ID,
  1514. Type: models.TypeCloudBrainTwo,
  1515. JobType: string(models.JobTypeTrain),
  1516. IsLatestVersion: modelarts.IsLatestVersion,
  1517. })
  1518. if err != nil {
  1519. ctx.ServerError("Cloudbrain", err)
  1520. return
  1521. }
  1522. for i, task := range tasks {
  1523. tasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)
  1524. tasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain)
  1525. }
  1526. pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)
  1527. pager.SetDefaultParams(ctx)
  1528. ctx.Data["Page"] = pager
  1529. ctx.Data["PageIsCloudBrain"] = true
  1530. ctx.Data["Tasks"] = tasks
  1531. ctx.Data["CanCreate"] = cloudbrain.CanCreateOrDebugJob(ctx)
  1532. ctx.Data["RepoIsEmpty"] = repo.IsEmpty
  1533. ctx.HTML(200, tplModelArtsInferenceJobIndex)
  1534. }
  1535. func InferenceJobNew(ctx *context.Context) {
  1536. err := inferenceJobNewDataPrepare(ctx)
  1537. if err != nil {
  1538. ctx.ServerError("get new inference-job info failed", err)
  1539. return
  1540. }
  1541. ctx.HTML(200, tplModelArtsInferenceJobNew)
  1542. }
  1543. func inferenceJobNewDataPrepare(ctx *context.Context) error {
  1544. ctx.Data["PageIsCloudBrain"] = true
  1545. t := time.Now()
  1546. var jobName = "inference" + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
  1547. ctx.Data["job_name"] = jobName
  1548. attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
  1549. if err != nil {
  1550. ctx.ServerError("GetAllUserAttachments failed:", err)
  1551. return err
  1552. }
  1553. ctx.Data["attachments"] = attachs
  1554. var resourcePools modelarts.ResourcePool
  1555. if err = json.Unmarshal([]byte(setting.ResourcePools), &resourcePools); err != nil {
  1556. ctx.ServerError("json.Unmarshal failed:", err)
  1557. return err
  1558. }
  1559. ctx.Data["resource_pools"] = resourcePools.Info
  1560. var engines modelarts.Engine
  1561. if err = json.Unmarshal([]byte(setting.Engines), &engines); err != nil {
  1562. ctx.ServerError("json.Unmarshal failed:", err)
  1563. return err
  1564. }
  1565. ctx.Data["engines"] = engines.Info
  1566. var versionInfos modelarts.VersionInfo
  1567. if err = json.Unmarshal([]byte(setting.EngineVersions), &versionInfos); err != nil {
  1568. ctx.ServerError("json.Unmarshal failed:", err)
  1569. return err
  1570. }
  1571. ctx.Data["engine_versions"] = versionInfos.Version
  1572. var flavorInfos modelarts.Flavor
  1573. if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil {
  1574. ctx.ServerError("json.Unmarshal failed:", err)
  1575. return err
  1576. }
  1577. ctx.Data["flavor_infos"] = flavorInfos.Info
  1578. resultObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.ResultPath
  1579. ctx.Data["result_url"] = resultObsPath
  1580. ctx.Data["params"] = ""
  1581. ctx.Data["branchName"] = ctx.Repo.BranchName
  1582. configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom)
  1583. if err != nil {
  1584. ctx.ServerError("getConfigList failed:", err)
  1585. return err
  1586. }
  1587. ctx.Data["config_list"] = configList.ParaConfigs
  1588. return nil
  1589. }
  1590. func inferenceJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModelArtsInferenceJobForm) error {
  1591. ctx.Data["PageIsCloudBrain"] = true
  1592. t := time.Now()
  1593. var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
  1594. ctx.Data["job_name"] = jobName
  1595. attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
  1596. if err != nil {
  1597. ctx.ServerError("GetAllUserAttachments failed:", err)
  1598. return err
  1599. }
  1600. ctx.Data["attachments"] = attachs
  1601. var resourcePools modelarts.ResourcePool
  1602. if err = json.Unmarshal([]byte(setting.ResourcePools), &resourcePools); err != nil {
  1603. ctx.ServerError("json.Unmarshal failed:", err)
  1604. return err
  1605. }
  1606. ctx.Data["resource_pools"] = resourcePools.Info
  1607. var engines modelarts.Engine
  1608. if err = json.Unmarshal([]byte(setting.Engines), &engines); err != nil {
  1609. ctx.ServerError("json.Unmarshal failed:", err)
  1610. return err
  1611. }
  1612. ctx.Data["engines"] = engines.Info
  1613. var versionInfos modelarts.VersionInfo
  1614. if err = json.Unmarshal([]byte(setting.EngineVersions), &versionInfos); err != nil {
  1615. ctx.ServerError("json.Unmarshal failed:", err)
  1616. return err
  1617. }
  1618. ctx.Data["engine_versions"] = versionInfos.Version
  1619. var flavorInfos modelarts.Flavor
  1620. if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil {
  1621. ctx.ServerError("json.Unmarshal failed:", err)
  1622. return err
  1623. }
  1624. ctx.Data["flavor_infos"] = flavorInfos.Info
  1625. outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath
  1626. ctx.Data["train_url"] = outputObsPath
  1627. configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom)
  1628. if err != nil {
  1629. ctx.ServerError("getConfigList failed:", err)
  1630. return err
  1631. }
  1632. var Parameters modelarts.Parameters
  1633. if err = json.Unmarshal([]byte(form.Params), &Parameters); err != nil {
  1634. ctx.ServerError("json.Unmarshal failed:", err)
  1635. return err
  1636. }
  1637. ctx.Data["params"] = Parameters.Parameter
  1638. ctx.Data["config_list"] = configList.ParaConfigs
  1639. ctx.Data["bootFile"] = form.BootFile
  1640. ctx.Data["uuid"] = form.Attachment
  1641. ctx.Data["branch_name"] = form.BranchName
  1642. return nil
  1643. }
  1644. func InferenceJobShow(ctx *context.Context) {
  1645. ctx.Data["PageIsCloudBrain"] = true
  1646. var jobID = ctx.Params(":jobid")
  1647. repo := ctx.Repo.Repository
  1648. page := ctx.QueryInt("page")
  1649. if page <= 0 {
  1650. page = 1
  1651. }
  1652. VersionListTasks, VersionListCount, err := models.CloudbrainsVersionList(&models.CloudbrainsOptions{
  1653. ListOptions: models.ListOptions{
  1654. Page: page,
  1655. PageSize: setting.UI.IssuePagingNum,
  1656. },
  1657. RepoID: repo.ID,
  1658. Type: models.TypeCloudBrainTwo,
  1659. JobType: string(models.JobTypeTrain),
  1660. JobID: jobID,
  1661. })
  1662. if err != nil {
  1663. log.Error("GetVersionListTasks(%s) failed:%v", jobID, err.Error())
  1664. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  1665. return
  1666. }
  1667. //设置权限
  1668. canNewJob, err := canUserCreateTrainJobVersion(ctx, VersionListTasks[0].UserID)
  1669. if err != nil {
  1670. ctx.ServerError("canNewJob failed", err)
  1671. return
  1672. }
  1673. ctx.Data["canNewJob"] = canNewJob
  1674. //将运行参数转化为epoch_size = 3, device_target = Ascend的格式
  1675. for i, _ := range VersionListTasks {
  1676. var parameters models.Parameters
  1677. err := json.Unmarshal([]byte(VersionListTasks[i].Parameters), &parameters)
  1678. if err != nil {
  1679. log.Error("Failed to Unmarshal Parameters: %s (%v)", VersionListTasks[i].Parameters, err)
  1680. trainJobNewDataPrepare(ctx)
  1681. return
  1682. }
  1683. if len(parameters.Parameter) > 0 {
  1684. paramTemp := ""
  1685. for _, Parameter := range parameters.Parameter {
  1686. param := Parameter.Label + " = " + Parameter.Value + "; "
  1687. paramTemp = paramTemp + param
  1688. }
  1689. VersionListTasks[i].Parameters = paramTemp[:len(paramTemp)-2]
  1690. } else {
  1691. VersionListTasks[i].Parameters = ""
  1692. }
  1693. }
  1694. pager := context.NewPagination(VersionListCount, setting.UI.IssuePagingNum, page, 5)
  1695. pager.SetDefaultParams(ctx)
  1696. ctx.Data["Page"] = pager
  1697. ctx.Data["jobID"] = jobID
  1698. ctx.Data["jobName"] = VersionListTasks[0].JobName
  1699. ctx.Data["version_list_task"] = VersionListTasks
  1700. ctx.Data["version_list_count"] = VersionListCount
  1701. ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow)
  1702. }
  1703. func InferenceJobStop(ctx *context.Context) {
  1704. var jobID = ctx.Params(":jobid")
  1705. task, err := models.GetCloudbrainByJobID(jobID)
  1706. if err != nil {
  1707. log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error())
  1708. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  1709. return
  1710. }
  1711. _, err = modelarts.StopTrainJob(jobID, strconv.FormatInt(task.VersionID, 10))
  1712. if err != nil {
  1713. log.Error("StopTrainJob(%s) failed:%v", task.JobName, err.Error())
  1714. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  1715. return
  1716. }
  1717. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job")
  1718. }
  1719. func InferenceJobDel(ctx *context.Context) {
  1720. var jobID = ctx.Params(":jobid")
  1721. repo := ctx.Repo.Repository
  1722. VersionListTasks, _, err := models.CloudbrainsVersionList(&models.CloudbrainsOptions{
  1723. RepoID: repo.ID,
  1724. Type: models.TypeCloudBrainTwo,
  1725. JobType: string(models.JobTypeTrain),
  1726. JobID: jobID,
  1727. })
  1728. if err != nil {
  1729. ctx.ServerError("get VersionListTasks failed", err)
  1730. return
  1731. }
  1732. //删除modelarts上的任务记录
  1733. _, err = modelarts.DelTrainJob(jobID)
  1734. if err != nil {
  1735. log.Error("DelTrainJob(%s) failed:%v", jobID, err.Error())
  1736. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  1737. return
  1738. }
  1739. //删除数据库Cloudbrain表的记录
  1740. for _, task := range VersionListTasks {
  1741. err = models.DeleteJob(&task.Cloudbrain)
  1742. if err != nil {
  1743. ctx.ServerError("DeleteJob failed", err)
  1744. return
  1745. }
  1746. }
  1747. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job")
  1748. }
  1749. func ResultDownload(ctx *context.Context) {
  1750. var (
  1751. err error
  1752. )
  1753. var jobID = ctx.Params(":jobid")
  1754. versionName := ctx.Query("version_name")
  1755. parentDir := ctx.Query("parent_dir")
  1756. fileName := ctx.Query("file_name")
  1757. log.Info("DownloadSingleModelFile start.")
  1758. task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, versionName)
  1759. if err != nil {
  1760. log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error())
  1761. return
  1762. }
  1763. path := strings.TrimPrefix(path.Join(setting.TrainJobModelPath, task.JobName, setting.OutPutPath, versionName, parentDir, fileName), "/")
  1764. log.Info("Download path is:%s", path)
  1765. url, err := storage.GetObsCreateSignedUrlByBucketAndKey(setting.Bucket, path)
  1766. if err != nil {
  1767. log.Error("GetObsCreateSignedUrl failed: %v", err.Error(), ctx.Data["msgID"])
  1768. ctx.ServerError("GetObsCreateSignedUrl", err)
  1769. return
  1770. }
  1771. http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently)
  1772. }