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 33 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
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  1. package repo
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "io"
  6. "net/http"
  7. "os"
  8. "path"
  9. "strconv"
  10. "strings"
  11. "time"
  12. "code.gitea.io/gitea/models"
  13. "code.gitea.io/gitea/modules/auth"
  14. "code.gitea.io/gitea/modules/base"
  15. "code.gitea.io/gitea/modules/context"
  16. "code.gitea.io/gitea/modules/git"
  17. "code.gitea.io/gitea/modules/log"
  18. "code.gitea.io/gitea/modules/modelarts"
  19. "code.gitea.io/gitea/modules/obs"
  20. "code.gitea.io/gitea/modules/setting"
  21. "code.gitea.io/gitea/modules/storage"
  22. "github.com/unknwon/com"
  23. )
  24. const (
  25. // tplModelArtsNotebookIndex base.TplName = "repo/modelarts/notebook/index"
  26. tplModelArtsNotebookIndex base.TplName = "repo/modelarts/notebook/index"
  27. tplModelArtsNotebookNew base.TplName = "repo/modelarts/notebook/new"
  28. tplModelArtsNotebookShow base.TplName = "repo/modelarts/notebook/show"
  29. tplModelArtsIndex base.TplName = "repo/modelarts/index"
  30. tplModelArtsNew base.TplName = "repo/modelarts/new"
  31. tplModelArtsShow base.TplName = "repo/modelarts/show"
  32. tplModelArtsTrainJobIndex base.TplName = "repo/modelarts/trainjob/index"
  33. tplModelArtsTrainJobNew base.TplName = "repo/modelarts/trainjob/new"
  34. tplModelArtsTrainJobShow base.TplName = "repo/modelarts/trainjob/show"
  35. tplModelArtsTrainJobShowModels base.TplName = "repo/modelarts/trainjob/models/index"
  36. )
  37. // MustEnableDataset check if repository enable internal cb
  38. func MustEnableModelArts(ctx *context.Context) {
  39. if !ctx.Repo.CanRead(models.UnitTypeCloudBrain) {
  40. ctx.NotFound("MustEnableCloudbrain", nil)
  41. return
  42. }
  43. }
  44. func ModelArtsIndex(ctx *context.Context) {
  45. MustEnableModelArts(ctx)
  46. repo := ctx.Repo.Repository
  47. page := ctx.QueryInt("page")
  48. if page <= 0 {
  49. page = 1
  50. }
  51. ciTasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{
  52. ListOptions: models.ListOptions{
  53. Page: page,
  54. PageSize: setting.UI.IssuePagingNum,
  55. },
  56. RepoID: repo.ID,
  57. Type: models.TypeCloudBrainTwo,
  58. })
  59. if err != nil {
  60. ctx.ServerError("Cloudbrain", err)
  61. return
  62. }
  63. for i, task := range ciTasks {
  64. if task.Status == string(models.JobRunning) {
  65. ciTasks[i].CanDebug = true
  66. } else {
  67. ciTasks[i].CanDebug = false
  68. }
  69. ciTasks[i].CanDel = models.CanDelJob(ctx.IsSigned, ctx.User, task)
  70. }
  71. pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)
  72. pager.SetDefaultParams(ctx)
  73. ctx.Data["Page"] = pager
  74. ctx.Data["PageIsCloudBrain"] = true
  75. ctx.Data["Tasks"] = ciTasks
  76. ctx.HTML(200, tplModelArtsIndex)
  77. }
  78. func ModelArtsNew(ctx *context.Context) {
  79. ctx.Data["PageIsCloudBrain"] = true
  80. t := time.Now()
  81. var jobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
  82. ctx.Data["job_name"] = jobName
  83. attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
  84. if err != nil {
  85. ctx.ServerError("GetAllUserAttachments failed:", err)
  86. return
  87. }
  88. ctx.Data["attachments"] = attachs
  89. ctx.Data["dataset_path"] = modelarts.DataSetMountPath
  90. ctx.Data["env"] = modelarts.NotebookEnv
  91. ctx.Data["notebook_type"] = modelarts.NotebookType
  92. if modelarts.FlavorInfos == nil {
  93. json.Unmarshal([]byte(setting.FlavorInfos), &modelarts.FlavorInfos)
  94. }
  95. ctx.Data["flavors"] = modelarts.FlavorInfos.FlavorInfo
  96. ctx.HTML(200, tplModelArtsNew)
  97. }
  98. func ModelArtsCreate(ctx *context.Context, form auth.CreateModelArtsForm) {
  99. ctx.Data["PageIsCloudBrain"] = true
  100. jobName := form.JobName
  101. uuid := form.Attachment
  102. description := form.Description
  103. //repo := ctx.Repo.Repository
  104. if !jobNamePattern.MatchString(jobName) {
  105. ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplModelArtsNew, &form)
  106. return
  107. }
  108. err := modelarts.GenerateTask(ctx, jobName, uuid, description)
  109. if err != nil {
  110. ctx.RenderWithErr(err.Error(), tplModelArtsNew, &form)
  111. return
  112. }
  113. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts")
  114. }
  115. func ModelArtsShow(ctx *context.Context) {
  116. ctx.Data["PageIsCloudBrain"] = true
  117. var jobID = ctx.Params(":jobid")
  118. task, err := models.GetCloudbrainByJobID(jobID)
  119. if err != nil {
  120. ctx.Data["error"] = err.Error()
  121. ctx.RenderWithErr(err.Error(), tplModelArtsIndex, nil)
  122. return
  123. }
  124. result, err := modelarts.GetJob(jobID)
  125. if err != nil {
  126. ctx.Data["error"] = err.Error()
  127. ctx.RenderWithErr(err.Error(), tplModelArtsIndex, nil)
  128. return
  129. }
  130. if result != nil {
  131. task.Status = result.Status
  132. err = models.UpdateJob(task)
  133. if err != nil {
  134. ctx.Data["error"] = err.Error()
  135. ctx.RenderWithErr(err.Error(), tplModelArtsIndex, nil)
  136. return
  137. }
  138. createTime, _ := com.StrTo(result.CreationTimestamp).Int64()
  139. result.CreateTime = time.Unix(int64(createTime/1000), 0).Format("2006-01-02 15:04:05")
  140. endTime, _ := com.StrTo(result.LatestUpdateTimestamp).Int64()
  141. result.LatestUpdateTime = time.Unix(int64(endTime/1000), 0).Format("2006-01-02 15:04:05")
  142. result.QueuingInfo.BeginTime = time.Unix(int64(result.QueuingInfo.BeginTimestamp/1000), 0).Format("2006-01-02 15:04:05")
  143. result.QueuingInfo.EndTime = time.Unix(int64(result.QueuingInfo.EndTimestamp/1000), 0).Format("2006-01-02 15:04:05")
  144. }
  145. ctx.Data["task"] = task
  146. ctx.Data["jobID"] = jobID
  147. ctx.Data["result"] = result
  148. ctx.HTML(200, tplModelArtsShow)
  149. }
  150. func ModelArtsDebug(ctx *context.Context) {
  151. var jobID = ctx.Params(":jobid")
  152. _, err := models.GetCloudbrainByJobID(jobID)
  153. if err != nil {
  154. ctx.ServerError("GetCloudbrainByJobID failed", err)
  155. return
  156. }
  157. result, err := modelarts.GetJob(jobID)
  158. if err != nil {
  159. ctx.RenderWithErr(err.Error(), tplModelArtsIndex, nil)
  160. return
  161. }
  162. res, err := modelarts.GetJobToken(jobID)
  163. if err != nil {
  164. ctx.RenderWithErr(err.Error(), tplModelArtsIndex, nil)
  165. return
  166. }
  167. urls := strings.Split(result.Spec.Annotations.Url, "/")
  168. urlPrefix := result.Spec.Annotations.TargetDomain
  169. for i, url := range urls {
  170. if i > 2 {
  171. urlPrefix += "/" + url
  172. }
  173. }
  174. //urlPrefix := result.Spec.Annotations.TargetDomain + "/modelarts/internal/hub/notebook/user/" + task.JobID
  175. log.Info(urlPrefix)
  176. debugUrl := urlPrefix + "?token=" + res.Token
  177. ctx.Redirect(debugUrl)
  178. }
  179. func ModelArtsStop(ctx *context.Context) {
  180. var jobID = ctx.Params(":jobid")
  181. log.Info(jobID)
  182. task, err := models.GetCloudbrainByJobID(jobID)
  183. if err != nil {
  184. ctx.ServerError("GetCloudbrainByJobID failed", err)
  185. return
  186. }
  187. if task.Status != string(models.JobRunning) {
  188. log.Error("the job(%s) is not running", task.JobName)
  189. ctx.ServerError("the job is not running", errors.New("the job is not running"))
  190. return
  191. }
  192. param := models.NotebookAction{
  193. Action: models.ActionStop,
  194. }
  195. res, err := modelarts.StopJob(jobID, param)
  196. if err != nil {
  197. log.Error("StopJob(%s) failed:%v", task.JobName, err.Error())
  198. ctx.ServerError("StopJob failed", err)
  199. return
  200. }
  201. task.Status = res.CurrentStatus
  202. err = models.UpdateJob(task)
  203. if err != nil {
  204. ctx.ServerError("UpdateJob failed", err)
  205. return
  206. }
  207. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts")
  208. }
  209. func ModelArtsDel(ctx *context.Context) {
  210. var jobID = ctx.Params(":jobid")
  211. task, err := models.GetCloudbrainByJobID(jobID)
  212. if err != nil {
  213. ctx.ServerError("GetCloudbrainByJobID failed", err)
  214. return
  215. }
  216. if task.Status != string(models.ModelArtsCreateFailed) && task.Status != string(models.ModelArtsStartFailed) && task.Status != string(models.ModelArtsStopped) {
  217. log.Error("the job(%s) has not been stopped", task.JobName)
  218. ctx.ServerError("the job has not been stopped", errors.New("the job has not been stopped"))
  219. return
  220. }
  221. _, err = modelarts.DelJob(jobID)
  222. if err != nil {
  223. log.Error("DelJob(%s) failed:%v", task.JobName, err.Error())
  224. ctx.ServerError("DelJob failed", err)
  225. return
  226. }
  227. err = models.DeleteJob(task)
  228. if err != nil {
  229. ctx.ServerError("DeleteJob failed", err)
  230. return
  231. }
  232. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts")
  233. }
  234. func NotebookIndex(ctx *context.Context) {
  235. MustEnableModelArts(ctx)
  236. repo := ctx.Repo.Repository
  237. page := ctx.QueryInt("page")
  238. if page <= 0 {
  239. page = 1
  240. }
  241. ciTasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{
  242. ListOptions: models.ListOptions{
  243. Page: page,
  244. PageSize: setting.UI.IssuePagingNum,
  245. },
  246. RepoID: repo.ID,
  247. Type: models.TypeCloudBrainNotebook,
  248. })
  249. if err != nil {
  250. ctx.ServerError("Cloudbrain", err)
  251. return
  252. }
  253. for i, task := range ciTasks {
  254. if task.Status == string(models.JobRunning) {
  255. ciTasks[i].CanDebug = true
  256. } else {
  257. ciTasks[i].CanDebug = false
  258. }
  259. }
  260. pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)
  261. pager.SetDefaultParams(ctx)
  262. ctx.Data["Page"] = pager
  263. ctx.Data["PageIsCloudBrain"] = true
  264. ctx.Data["Tasks"] = ciTasks
  265. ctx.HTML(200, tplModelArtsNotebookIndex)
  266. }
  267. func NotebookNew(ctx *context.Context) {
  268. ctx.Data["PageIsCloudBrain"] = true
  269. t := time.Now()
  270. var jobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
  271. ctx.Data["job_name"] = jobName
  272. attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
  273. if err != nil {
  274. ctx.ServerError("GetAllUserAttachments failed:", err)
  275. return
  276. }
  277. ctx.Data["attachments"] = attachs
  278. ctx.Data["dataset_path"] = modelarts.DataSetMountPath
  279. ctx.Data["env"] = modelarts.NotebookEnv
  280. ctx.Data["notebook_type"] = modelarts.NotebookType
  281. if modelarts.FlavorInfos == nil {
  282. json.Unmarshal([]byte(setting.FlavorInfos), &modelarts.FlavorInfos)
  283. }
  284. ctx.Data["flavors"] = modelarts.FlavorInfos.FlavorInfo
  285. ctx.HTML(200, tplModelArtsNotebookNew)
  286. }
  287. func NotebookCreate(ctx *context.Context, form auth.CreateModelArtsNotebookForm) {
  288. ctx.Data["PageIsNotebook"] = true
  289. jobName := form.JobName
  290. uuid := form.Attachment
  291. description := form.Description
  292. err := modelarts.GenerateTask(ctx, jobName, uuid, description)
  293. if err != nil {
  294. ctx.RenderWithErr(err.Error(), tplModelArtsNotebookNew, &form)
  295. return
  296. }
  297. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/notebook")
  298. }
  299. func NotebookShow(ctx *context.Context) {
  300. ctx.Data["PageIsCloudBrain"] = true
  301. var jobID = ctx.Params(":jobid")
  302. task, err := models.GetCloudbrainByJobID(jobID)
  303. if err != nil {
  304. ctx.Data["error"] = err.Error()
  305. ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil)
  306. return
  307. }
  308. result, err := modelarts.GetJob(jobID)
  309. if err != nil {
  310. ctx.Data["error"] = err.Error()
  311. ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil)
  312. return
  313. }
  314. if result != nil {
  315. task.Status = result.Status
  316. err = models.UpdateJob(task)
  317. if err != nil {
  318. ctx.Data["error"] = err.Error()
  319. ctx.RenderWithErr(err.Error(), tplModelArtsNotebookShow, nil)
  320. return
  321. }
  322. createTime, _ := com.StrTo(result.CreationTimestamp).Int64()
  323. result.CreateTime = time.Unix(int64(createTime/1000), 0).Format("2006-01-02 15:04:05")
  324. endTime, _ := com.StrTo(result.LatestUpdateTimestamp).Int64()
  325. result.LatestUpdateTime = time.Unix(int64(endTime/1000), 0).Format("2006-01-02 15:04:05")
  326. result.QueuingInfo.BeginTime = time.Unix(int64(result.QueuingInfo.BeginTimestamp/1000), 0).Format("2006-01-02 15:04:05")
  327. result.QueuingInfo.EndTime = time.Unix(int64(result.QueuingInfo.EndTimestamp/1000), 0).Format("2006-01-02 15:04:05")
  328. }
  329. ctx.Data["task"] = task
  330. ctx.Data["jobID"] = jobID
  331. ctx.Data["result"] = result
  332. ctx.HTML(200, tplModelArtsNotebookShow)
  333. }
  334. func NotebookDebug(ctx *context.Context) {
  335. var jobID = ctx.Params(":jobid")
  336. _, err := models.GetCloudbrainByJobID(jobID)
  337. if err != nil {
  338. ctx.ServerError("GetCloudbrainByJobID failed", err)
  339. return
  340. }
  341. result, err := modelarts.GetJob(jobID)
  342. if err != nil {
  343. ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil)
  344. return
  345. }
  346. res, err := modelarts.GetJobToken(jobID)
  347. if err != nil {
  348. ctx.RenderWithErr(err.Error(), tplModelArtsNotebookIndex, nil)
  349. return
  350. }
  351. urls := strings.Split(result.Spec.Annotations.Url, "/")
  352. urlPrefix := result.Spec.Annotations.TargetDomain
  353. for i, url := range urls {
  354. if i > 2 {
  355. urlPrefix += "/" + url
  356. }
  357. }
  358. debugUrl := urlPrefix + "?token=" + res.Token
  359. ctx.Redirect(debugUrl)
  360. }
  361. func NotebookStop(ctx *context.Context) {
  362. var jobID = ctx.Params(":jobid")
  363. log.Info(jobID)
  364. task, err := models.GetCloudbrainByJobID(jobID)
  365. if err != nil {
  366. ctx.ServerError("GetCloudbrainByJobID failed", err)
  367. return
  368. }
  369. if task.Status != string(models.JobRunning) {
  370. log.Error("the job(%s) is not running", task.JobName)
  371. ctx.ServerError("the job is not running", errors.New("the job is not running"))
  372. return
  373. }
  374. param := models.NotebookAction{
  375. Action: models.ActionStop,
  376. }
  377. res, err := modelarts.StopJob(jobID, param)
  378. if err != nil {
  379. log.Error("StopJob(%s) failed:%v", task.JobName, err.Error())
  380. ctx.ServerError("StopJob failed", err)
  381. return
  382. }
  383. task.Status = res.CurrentStatus
  384. err = models.UpdateJob(task)
  385. if err != nil {
  386. ctx.ServerError("UpdateJob failed", err)
  387. return
  388. }
  389. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/notebook")
  390. }
  391. func NotebookDel(ctx *context.Context) {
  392. var jobID = ctx.Params(":jobid")
  393. task, err := models.GetCloudbrainByJobID(jobID)
  394. if err != nil {
  395. ctx.ServerError("GetCloudbrainByJobID failed", err)
  396. return
  397. }
  398. if task.Status != string(models.JobStopped) {
  399. log.Error("the job(%s) has not been stopped", task.JobName)
  400. ctx.ServerError("the job has not been stopped", errors.New("the job has not been stopped"))
  401. return
  402. }
  403. _, err = modelarts.DelNotebook(jobID)
  404. if err != nil {
  405. log.Error("DelJob(%s) failed:%v", task.JobName, err.Error())
  406. ctx.ServerError("DelJob failed", err)
  407. return
  408. }
  409. err = models.DeleteJob(task)
  410. if err != nil {
  411. ctx.ServerError("DeleteJob failed", err)
  412. return
  413. }
  414. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/notebook")
  415. }
  416. func TrainJobIndex(ctx *context.Context) {
  417. MustEnableModelArts(ctx)
  418. //can, err := canUserCreateTrainJob(ctx.User.ID)
  419. //if err != nil {
  420. // ctx.ServerError("canUserCreateTrainJob", err)
  421. // return
  422. //}
  423. //
  424. //ctx.Data["CanCreate"] = can
  425. repo := ctx.Repo.Repository
  426. page := ctx.QueryInt("page")
  427. if page <= 0 {
  428. page = 1
  429. }
  430. tasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{
  431. ListOptions: models.ListOptions{
  432. Page: page,
  433. PageSize: setting.UI.IssuePagingNum,
  434. },
  435. RepoID: repo.ID,
  436. Type: models.TypeCloudBrainTrainJob,
  437. })
  438. if err != nil {
  439. ctx.ServerError("Cloudbrain", err)
  440. return
  441. }
  442. pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)
  443. pager.SetDefaultParams(ctx)
  444. ctx.Data["Page"] = pager
  445. ctx.Data["PageIsCloudBrain"] = true
  446. ctx.Data["Tasks"] = tasks
  447. ctx.HTML(200, tplModelArtsTrainJobIndex)
  448. }
  449. func TrainJobNew(ctx *context.Context) {
  450. err := trainJobNewDataPrepare(ctx)
  451. if err != nil {
  452. ctx.ServerError("get new train-job info failed", err)
  453. return
  454. }
  455. ctx.HTML(200, tplModelArtsTrainJobNew)
  456. }
  457. func trainJobNewDataPrepare(ctx *context.Context) error {
  458. ctx.Data["PageIsCloudBrain"] = true
  459. //can, err := canUserCreateTrainJob(ctx.User.ID)
  460. //if err != nil {
  461. // ctx.ServerError("canUserCreateTrainJob", err)
  462. // return
  463. //}
  464. //
  465. //if !can {
  466. // log.Error("the user can not create train-job")
  467. // ctx.ServerError("the user can not create train-job", fmt.Errorf("the user can not create train-job"))
  468. // return
  469. //}
  470. t := time.Now()
  471. var jobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:]
  472. ctx.Data["job_name"] = jobName
  473. attachs, err := models.GetModelArtsUserAttachments(ctx.User.ID)
  474. if err != nil {
  475. ctx.ServerError("GetAllUserAttachments failed:", err)
  476. return err
  477. }
  478. ctx.Data["attachments"] = attachs
  479. var resourcePools modelarts.ResourcePool
  480. if err = json.Unmarshal([]byte(setting.ResourcePools), &resourcePools); err != nil {
  481. ctx.ServerError("json.Unmarshal failed:", err)
  482. return err
  483. }
  484. ctx.Data["resource_pools"] = resourcePools.Info
  485. var engines modelarts.Engine
  486. if err = json.Unmarshal([]byte(setting.Engines), &engines); err != nil {
  487. ctx.ServerError("json.Unmarshal failed:", err)
  488. return err
  489. }
  490. ctx.Data["engines"] = engines.Info
  491. var versionInfos modelarts.VersionInfo
  492. if err = json.Unmarshal([]byte(setting.EngineVersions), &versionInfos); err != nil {
  493. ctx.ServerError("json.Unmarshal failed:", err)
  494. return err
  495. }
  496. ctx.Data["engine_versions"] = versionInfos.Version
  497. var flavorInfos modelarts.Flavor
  498. if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil {
  499. ctx.ServerError("json.Unmarshal failed:", err)
  500. return err
  501. }
  502. ctx.Data["flavor_infos"] = flavorInfos.Info
  503. outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath
  504. ctx.Data["train_url"] = outputObsPath
  505. configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom)
  506. if err != nil {
  507. ctx.ServerError("getConfigList failed:", err)
  508. return err
  509. }
  510. ctx.Data["config_list"] = configList.ParaConfigs
  511. return nil
  512. }
  513. func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) {
  514. ctx.Data["PageIsTrainJob"] = true
  515. jobName := form.JobName
  516. uuid := form.Attachment
  517. description := form.Description
  518. workServerNumber := form.WorkServerNumber
  519. engineID := form.EngineID
  520. bootFile := form.BootFile
  521. flavorCode := form.Flavor
  522. params := form.Params
  523. poolID := form.PoolID
  524. isSaveParam := form.IsSaveParam
  525. repo := ctx.Repo.Repository
  526. codeLocalPath := setting.JobPath + jobName + modelarts.CodePath
  527. codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath
  528. outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath
  529. logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath
  530. dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + "/"
  531. //can, err := canUserCreateTrainJob(ctx.User.ID)
  532. //if err != nil {
  533. // ctx.ServerError("canUserCreateTrainJob", err)
  534. // return
  535. //}
  536. //
  537. //if !can {
  538. // log.Error("the user can not create train-job")
  539. // ctx.RenderWithErr("the user can not create train-job", tplModelArtsTrainJobNew, &form)
  540. // return
  541. //}
  542. //param check
  543. if err := paramCheckCreateTrainJob(form); err != nil {
  544. log.Error("paramCheckCreateTrainJob failed:(%v)", err)
  545. trainJobNewDataPrepare(ctx)
  546. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form)
  547. return
  548. }
  549. if err := git.Clone(repo.RepoPath(), codeLocalPath, git.CloneRepoOptions{}); err != nil {
  550. log.Error("创建任务失败,任务名称已存在!: %s (%v)", repo.FullName(), err)
  551. trainJobNewDataPrepare(ctx)
  552. // ctx.RenderWithErr("Failed to clone repository", tplModelArtsTrainJobNew, &form)
  553. ctx.RenderWithErr("创建任务失败,任务名称已存在!", tplModelArtsTrainJobNew, &form)
  554. return
  555. }
  556. //todo: upload code (send to file_server todo this work?)
  557. if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.OutputPath); err != nil {
  558. log.Error("Failed to obsMkdir_output: %s (%v)", repo.FullName(), err)
  559. trainJobNewDataPrepare(ctx)
  560. ctx.RenderWithErr("Failed to obsMkdir_output", tplModelArtsTrainJobNew, &form)
  561. return
  562. }
  563. if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.LogPath); err != nil {
  564. log.Error("Failed to obsMkdir_log: %s (%v)", repo.FullName(), err)
  565. trainJobNewDataPrepare(ctx)
  566. ctx.RenderWithErr("Failed to obsMkdir_log", tplModelArtsTrainJobNew, &form)
  567. return
  568. }
  569. if err := uploadCodeToObs(codeLocalPath, jobName, ""); err != nil {
  570. log.Error("Failed to uploadCodeToObs: %s (%v)", repo.FullName(), err)
  571. trainJobNewDataPrepare(ctx)
  572. ctx.RenderWithErr("Failed to uploadCodeToObs", tplModelArtsTrainJobNew, &form)
  573. return
  574. }
  575. //todo: del local code?
  576. var parameters models.Parameters
  577. param := make([]models.Parameter, 0)
  578. param = append(param, models.Parameter{
  579. Label: modelarts.TrainUrl,
  580. Value: outputObsPath,
  581. }, models.Parameter{
  582. Label: modelarts.DataUrl,
  583. Value: dataPath,
  584. })
  585. if len(params) != 0 {
  586. err := json.Unmarshal([]byte(params), &parameters)
  587. if err != nil {
  588. log.Error("Failed to Unmarshal params: %s (%v)", params, err)
  589. trainJobNewDataPrepare(ctx)
  590. ctx.RenderWithErr("运行参数错误", tplModelArtsTrainJobNew, &form)
  591. return
  592. }
  593. for _, parameter := range parameters.Parameter {
  594. if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl {
  595. param = append(param, models.Parameter{
  596. Label: parameter.Label,
  597. Value: parameter.Value,
  598. })
  599. }
  600. }
  601. }
  602. //save param config
  603. if isSaveParam == "on" {
  604. if form.ParameterTemplateName == "" {
  605. log.Error("ParameterTemplateName is empty")
  606. trainJobNewDataPrepare(ctx)
  607. ctx.RenderWithErr("保存作业参数时,作业参数名称不能为空", tplModelArtsTrainJobNew, &form)
  608. return
  609. }
  610. _, err := modelarts.CreateTrainJobConfig(models.CreateConfigParams{
  611. ConfigName: form.ParameterTemplateName,
  612. Description: form.PrameterDescription,
  613. DataUrl: dataPath,
  614. AppUrl: codeObsPath,
  615. BootFileUrl: codeObsPath + bootFile,
  616. TrainUrl: outputObsPath,
  617. Flavor: models.Flavor{
  618. Code: flavorCode,
  619. },
  620. WorkServerNum: workServerNumber,
  621. EngineID: int64(engineID),
  622. LogUrl: logObsPath,
  623. PoolID: poolID,
  624. Parameter: param,
  625. })
  626. if err != nil {
  627. log.Error("Failed to CreateTrainJobConfig: %v", err)
  628. trainJobNewDataPrepare(ctx)
  629. ctx.RenderWithErr("保存作业参数失败:"+err.Error(), tplModelArtsTrainJobNew, &form)
  630. return
  631. }
  632. }
  633. req := &modelarts.GenerateTrainJobReq{
  634. JobName: jobName,
  635. DataUrl: dataPath,
  636. Description: description,
  637. CodeObsPath: codeObsPath,
  638. BootFile: codeObsPath + bootFile,
  639. TrainUrl: outputObsPath,
  640. FlavorCode: flavorCode,
  641. WorkServerNumber: workServerNumber,
  642. EngineID: int64(engineID),
  643. LogUrl: logObsPath,
  644. PoolID: poolID,
  645. Uuid: uuid,
  646. Parameters: param,
  647. }
  648. err := modelarts.GenerateTrainJob(ctx, req)
  649. if err != nil {
  650. log.Error("GenerateTrainJob failed:%v", err.Error())
  651. trainJobNewDataPrepare(ctx)
  652. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form)
  653. return
  654. }
  655. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job")
  656. }
  657. // readDir reads the directory named by dirname and returns
  658. // a list of directory entries sorted by filename.
  659. func readDir(dirname string) ([]os.FileInfo, error) {
  660. f, err := os.Open(dirname)
  661. if err != nil {
  662. return nil, err
  663. }
  664. list, err := f.Readdir(100)
  665. f.Close()
  666. if err != nil {
  667. //todo: can not upload empty folder
  668. if err == io.EOF {
  669. return nil, nil
  670. }
  671. return nil, err
  672. }
  673. //sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
  674. return list, nil
  675. }
  676. func uploadCodeToObs(codePath, jobName, parentDir string) error {
  677. files, err := readDir(codePath)
  678. if err != nil {
  679. log.Error("readDir(%s) failed: %s", codePath, err.Error())
  680. return err
  681. }
  682. for _, file := range files {
  683. if file.IsDir() {
  684. input := &obs.PutObjectInput{}
  685. input.Bucket = setting.Bucket
  686. input.Key = parentDir + file.Name() + "/"
  687. _, err = storage.ObsCli.PutObject(input)
  688. if err != nil {
  689. log.Error("PutObject(%s) failed: %s", input.Key, err.Error())
  690. return err
  691. }
  692. if err = uploadCodeToObs(codePath+file.Name()+"/", jobName, parentDir+file.Name()+"/"); err != nil {
  693. log.Error("uploadCodeToObs(%s) failed: %s", file.Name(), err.Error())
  694. return err
  695. }
  696. } else {
  697. input := &obs.PutFileInput{}
  698. input.Bucket = setting.Bucket
  699. input.Key = setting.CodePathPrefix + jobName + "/code/" + parentDir + file.Name()
  700. input.SourceFile = codePath + file.Name()
  701. _, err = storage.ObsCli.PutFile(input)
  702. if err != nil {
  703. log.Error("PutFile(%s) failed: %s", input.SourceFile, err.Error())
  704. return err
  705. }
  706. }
  707. }
  708. return nil
  709. }
  710. func obsMkdir(dir string) error {
  711. input := &obs.PutObjectInput{}
  712. input.Bucket = setting.Bucket
  713. input.Key = dir
  714. _, err := storage.ObsCli.PutObject(input)
  715. if err != nil {
  716. log.Error("PutObject(%s) failed: %s", input.Key, err.Error())
  717. return err
  718. }
  719. return nil
  720. }
  721. func paramCheckCreateTrainJob(form auth.CreateModelArtsTrainJobForm) error {
  722. if !strings.HasSuffix(form.BootFile, ".py") {
  723. log.Error("the boot file(%s) must be a python file", form.BootFile)
  724. return errors.New("启动文件必须是python文件")
  725. }
  726. if form.WorkServerNumber > 25 || form.WorkServerNumber < 1 {
  727. log.Error("the WorkServerNumber(%d) must be in (1,25)", form.WorkServerNumber)
  728. return errors.New("计算节点数必须在1-25之间")
  729. }
  730. return nil
  731. }
  732. func TrainJobShow(ctx *context.Context) {
  733. ctx.Data["PageIsCloudBrain"] = true
  734. var jobID = ctx.Params(":jobid")
  735. task, err := models.GetCloudbrainByJobID(jobID)
  736. if err != nil {
  737. log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error())
  738. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  739. return
  740. }
  741. // attach, err := models.GetAttachmentByUUID(task.Uuid)
  742. // if err != nil {
  743. // log.Error("GetAttachmentByUUID(%s) failed:%v", jobID, err.Error())
  744. // ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  745. // return
  746. // }
  747. result, err := modelarts.GetTrainJob(jobID, strconv.FormatInt(task.VersionID, 10))
  748. if err != nil {
  749. log.Error("GetJob(%s) failed:%v", jobID, err.Error())
  750. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  751. return
  752. }
  753. if result != nil {
  754. result.CreateTime = time.Unix(int64(result.LongCreateTime/1000), 0).Format("2006-01-02 15:04:05")
  755. if result.Duration != 0 {
  756. result.TrainJobDuration = addZero(result.Duration/3600000) + ":" + addZero(result.Duration%3600000/60000) + ":" + addZero(result.Duration%60000/1000)
  757. } else {
  758. result.TrainJobDuration = "00:00:00"
  759. }
  760. result.Status = modelarts.TransTrainJobStatus(result.IntStatus)
  761. err = models.SetTrainJobStatusByJobID(jobID, result.Status, result.Duration, string(result.TrainJobDuration))
  762. if err != nil {
  763. ctx.ServerError("UpdateJob failed", err)
  764. return
  765. }
  766. result.DatasetName = task.DatasetName
  767. }
  768. resultLogFile, resultLog, err := trainJobGetLog(jobID)
  769. if err != nil {
  770. log.Error("trainJobGetLog(%s) failed:%v", jobID, err.Error())
  771. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  772. return
  773. }
  774. ctx.Data["log_file_name"] = resultLogFile.LogFileList[0]
  775. ctx.Data["log"] = resultLog
  776. ctx.Data["task"] = task
  777. ctx.Data["jobID"] = jobID
  778. ctx.Data["result"] = result
  779. ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow)
  780. }
  781. func addZero(t int64) (m string) {
  782. if t < 10 {
  783. m = "0" + strconv.FormatInt(t, 10)
  784. return m
  785. } else {
  786. return strconv.FormatInt(t, 10)
  787. }
  788. }
  789. func TrainJobGetLog(ctx *context.Context) {
  790. ctx.Data["PageIsTrainJob"] = true
  791. var jobID = ctx.Params(":jobid")
  792. var logFileName = ctx.Query("file_name")
  793. var baseLine = ctx.Query("base_line")
  794. var order = ctx.Query("order")
  795. if order != modelarts.OrderDesc && order != modelarts.OrderAsc {
  796. log.Error("order(%s) check failed", order)
  797. ctx.HTML(http.StatusBadRequest, tplModelArtsTrainJobShow)
  798. return
  799. }
  800. task, err := models.GetCloudbrainByJobID(jobID)
  801. if err != nil {
  802. log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error())
  803. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  804. return
  805. }
  806. result, err := modelarts.GetTrainJobLog(jobID, strconv.FormatInt(task.VersionID, 10), baseLine, logFileName, order, modelarts.Lines)
  807. if err != nil {
  808. log.Error("GetTrainJobLog(%s) failed:%v", jobID, err.Error())
  809. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  810. return
  811. }
  812. ctx.Data["log"] = result
  813. //ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow)
  814. }
  815. func trainJobGetLog(jobID string) (*models.GetTrainJobLogFileNamesResult, *models.GetTrainJobLogResult, error) {
  816. task, err := models.GetCloudbrainByJobID(jobID)
  817. if err != nil {
  818. log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error())
  819. return nil, nil, err
  820. }
  821. resultLogFile, err := modelarts.GetTrainJobLogFileNames(jobID, strconv.FormatInt(task.VersionID, 10))
  822. if err != nil {
  823. log.Error("GetTrainJobLogFileNames(%s) failed:%v", jobID, err.Error())
  824. return nil, nil, err
  825. }
  826. result, err := modelarts.GetTrainJobLog(jobID, strconv.FormatInt(task.VersionID, 10), "", resultLogFile.LogFileList[0], modelarts.OrderDesc, modelarts.Lines)
  827. if err != nil {
  828. log.Error("GetTrainJobLog(%s) failed:%v", jobID, err.Error())
  829. return nil, nil, err
  830. }
  831. return resultLogFile, result, err
  832. }
  833. func TrainJobDel(ctx *context.Context) {
  834. var jobID = ctx.Params(":jobid")
  835. task, err := models.GetCloudbrainByJobID(jobID)
  836. if err != nil {
  837. log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error())
  838. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  839. return
  840. }
  841. _, err = modelarts.DelTrainJob(jobID)
  842. if err != nil {
  843. log.Error("DelTrainJob(%s) failed:%v", task.JobName, err.Error())
  844. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  845. return
  846. }
  847. err = models.DeleteJob(task)
  848. if err != nil {
  849. ctx.ServerError("DeleteJob failed", err)
  850. return
  851. }
  852. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job")
  853. }
  854. func TrainJobStop(ctx *context.Context) {
  855. var jobID = ctx.Params(":jobid")
  856. task, err := models.GetCloudbrainByJobID(jobID)
  857. if err != nil {
  858. log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error())
  859. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  860. return
  861. }
  862. _, err = modelarts.StopTrainJob(jobID, strconv.FormatInt(task.VersionID, 10))
  863. if err != nil {
  864. log.Error("StopTrainJob(%s) failed:%v", task.JobName, err.Error())
  865. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  866. return
  867. }
  868. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job")
  869. }
  870. func canUserCreateTrainJob(uid int64) (bool, error) {
  871. org, err := models.GetOrgByName(setting.AllowedOrg)
  872. if err != nil {
  873. log.Error("get allowed org failed: ", setting.AllowedOrg)
  874. return false, err
  875. }
  876. return org.IsOrgMember(uid)
  877. }
  878. func TrainJobGetConfigList(ctx *context.Context) {
  879. ctx.Data["PageIsTrainJob"] = true
  880. var jobID = ctx.Params(":jobid")
  881. var logFileName = ctx.Query("file_name")
  882. var baseLine = ctx.Query("base_line")
  883. var order = ctx.Query("order")
  884. if order != modelarts.OrderDesc && order != modelarts.OrderAsc {
  885. log.Error("order(%s) check failed", order)
  886. ctx.HTML(http.StatusBadRequest, tplModelArtsTrainJobShow)
  887. return
  888. }
  889. task, err := models.GetCloudbrainByJobID(jobID)
  890. if err != nil {
  891. log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error())
  892. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  893. return
  894. }
  895. result, err := modelarts.GetTrainJobLog(jobID, strconv.FormatInt(task.VersionID, 10), baseLine, logFileName, order, modelarts.Lines)
  896. if err != nil {
  897. log.Error("GetTrainJobLog(%s) failed:%v", jobID, err.Error())
  898. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  899. return
  900. }
  901. ctx.Data["log"] = result
  902. //ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow)
  903. }
  904. func getConfigList(perPage, page int, sortBy, order, searchContent, configType string) (*models.GetConfigListResult, error) {
  905. var result models.GetConfigListResult
  906. list, err := modelarts.GetConfigList(perPage, page, sortBy, order, searchContent, configType)
  907. if err != nil {
  908. log.Error("GetConfigList failed:", err)
  909. return &result, err
  910. }
  911. for _, config := range list.ParaConfigs {
  912. paraConfig, err := modelarts.GetParaConfig(config.ConfigName, configType)
  913. if err != nil {
  914. log.Error("GetParaConfig failed:", err)
  915. return &result, err
  916. }
  917. config.Result = paraConfig
  918. }
  919. return list, nil
  920. }
  921. func TrainJobShowModels(ctx *context.Context) {
  922. ctx.Data["PageIsCloudBrain"] = true
  923. jobID := ctx.Params(":jobid")
  924. parentDir := ctx.Query("parentDir")
  925. dirArray := strings.Split(parentDir, "/")
  926. task, err := models.GetCloudbrainByJobID(jobID)
  927. if err != nil {
  928. log.Error("no such job!", ctx.Data["msgID"])
  929. ctx.ServerError("no such job:", err)
  930. return
  931. }
  932. models, err := storage.GetObsListObject(task.JobName, parentDir)
  933. if err != nil {
  934. log.Info("get TrainJobListModel failed:", err)
  935. ctx.ServerError("GetObsListObject:", err)
  936. return
  937. }
  938. ctx.Data["Path"] = dirArray
  939. ctx.Data["Dirs"] = models
  940. ctx.Data["task"] = task
  941. ctx.Data["JobID"] = jobID
  942. ctx.HTML(200, tplModelArtsTrainJobShowModels)
  943. }
  944. func TrainJobDownloadModel(ctx *context.Context) {
  945. parentDir := ctx.Query("parentDir")
  946. fileName := ctx.Query("fileName")
  947. jobName := ctx.Query("jobName")
  948. url, err := storage.GetObsCreateSignedUrl(jobName, parentDir, fileName)
  949. if err != nil {
  950. log.Error("GetObsCreateSignedUrl failed: %v", err.Error(), ctx.Data["msgID"])
  951. ctx.ServerError("GetObsCreateSignedUrl", err)
  952. return
  953. }
  954. http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently)
  955. }