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 32 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
4 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119
  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("Failed to clone repository: %s (%v)", repo.FullName(), err)
  551. trainJobNewDataPrepare(ctx)
  552. ctx.RenderWithErr("Failed to clone repository", tplModelArtsTrainJobNew, &form)
  553. return
  554. }
  555. //todo: upload code (send to file_server todo this work?)
  556. if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.OutputPath); err != nil {
  557. log.Error("Failed to obsMkdir_output: %s (%v)", repo.FullName(), err)
  558. trainJobNewDataPrepare(ctx)
  559. ctx.RenderWithErr("Failed to obsMkdir_output", tplModelArtsTrainJobNew, &form)
  560. return
  561. }
  562. if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.LogPath); err != nil {
  563. log.Error("Failed to obsMkdir_log: %s (%v)", repo.FullName(), err)
  564. trainJobNewDataPrepare(ctx)
  565. ctx.RenderWithErr("Failed to obsMkdir_log", tplModelArtsTrainJobNew, &form)
  566. return
  567. }
  568. if err := uploadCodeToObs(codeLocalPath, jobName, ""); err != nil {
  569. log.Error("Failed to uploadCodeToObs: %s (%v)", repo.FullName(), err)
  570. trainJobNewDataPrepare(ctx)
  571. ctx.RenderWithErr("Failed to uploadCodeToObs", tplModelArtsTrainJobNew, &form)
  572. return
  573. }
  574. //todo: del local code?
  575. var parameters models.Parameters
  576. param := make([]models.Parameter, 0)
  577. param = append(param, models.Parameter{
  578. Label: modelarts.TrainUrl,
  579. Value: outputObsPath,
  580. }, models.Parameter{
  581. Label: modelarts.DataUrl,
  582. Value: dataPath,
  583. })
  584. if len(params) != 0 {
  585. err := json.Unmarshal([]byte(params), &parameters)
  586. if err != nil {
  587. log.Error("Failed to Unmarshal params: %s (%v)", params, err)
  588. trainJobNewDataPrepare(ctx)
  589. ctx.RenderWithErr("运行参数错误", tplModelArtsTrainJobNew, &form)
  590. return
  591. }
  592. for _, parameter := range parameters.Parameter {
  593. if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl {
  594. param = append(param, models.Parameter{
  595. Label: parameter.Label,
  596. Value: parameter.Value,
  597. })
  598. }
  599. }
  600. }
  601. //save param config
  602. if isSaveParam == "on" {
  603. if form.ParameterTemplateName == "" {
  604. log.Error("ParameterTemplateName is empty")
  605. trainJobNewDataPrepare(ctx)
  606. ctx.RenderWithErr("保存作业参数时,作业参数名称不能为空", tplModelArtsTrainJobNew, &form)
  607. return
  608. }
  609. _, err := modelarts.CreateTrainJobConfig(models.CreateConfigParams{
  610. ConfigName: form.ParameterTemplateName,
  611. Description: form.PrameterDescription,
  612. DataUrl: dataPath,
  613. AppUrl: codeObsPath,
  614. BootFileUrl: codeObsPath + bootFile,
  615. TrainUrl: outputObsPath,
  616. Flavor: models.Flavor{
  617. Code: flavorCode,
  618. },
  619. WorkServerNum: workServerNumber,
  620. EngineID: int64(engineID),
  621. LogUrl: logObsPath,
  622. PoolID: poolID,
  623. Parameter: param,
  624. })
  625. if err != nil {
  626. log.Error("Failed to CreateTrainJobConfig: %v", err)
  627. trainJobNewDataPrepare(ctx)
  628. ctx.RenderWithErr("保存作业参数失败:"+err.Error(), tplModelArtsTrainJobNew, &form)
  629. return
  630. }
  631. }
  632. req := &modelarts.GenerateTrainJobReq{
  633. JobName: jobName,
  634. DataUrl: dataPath,
  635. Description: description,
  636. CodeObsPath: codeObsPath,
  637. BootFile: codeObsPath + bootFile,
  638. TrainUrl: outputObsPath,
  639. FlavorCode: flavorCode,
  640. WorkServerNumber: workServerNumber,
  641. EngineID: int64(engineID),
  642. LogUrl: logObsPath,
  643. PoolID: poolID,
  644. Uuid: uuid,
  645. Parameters: param,
  646. }
  647. err := modelarts.GenerateTrainJob(ctx, req)
  648. if err != nil {
  649. log.Error("GenerateTrainJob failed:%v", err.Error())
  650. trainJobNewDataPrepare(ctx)
  651. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form)
  652. return
  653. }
  654. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job")
  655. }
  656. // readDir reads the directory named by dirname and returns
  657. // a list of directory entries sorted by filename.
  658. func readDir(dirname string) ([]os.FileInfo, error) {
  659. f, err := os.Open(dirname)
  660. if err != nil {
  661. return nil, err
  662. }
  663. list, err := f.Readdir(100)
  664. f.Close()
  665. if err != nil {
  666. //todo: can not upload empty folder
  667. if err == io.EOF {
  668. return nil, nil
  669. }
  670. return nil, err
  671. }
  672. //sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
  673. return list, nil
  674. }
  675. func uploadCodeToObs(codePath, jobName, parentDir string) error {
  676. files, err := readDir(codePath)
  677. if err != nil {
  678. log.Error("readDir(%s) failed: %s", codePath, err.Error())
  679. return err
  680. }
  681. for _, file := range files {
  682. if file.IsDir() {
  683. input := &obs.PutObjectInput{}
  684. input.Bucket = setting.Bucket
  685. input.Key = parentDir + file.Name() + "/"
  686. _, err = storage.ObsCli.PutObject(input)
  687. if err != nil {
  688. log.Error("PutObject(%s) failed: %s", input.Key, err.Error())
  689. return err
  690. }
  691. if err = uploadCodeToObs(codePath+file.Name()+"/", jobName, parentDir+file.Name()+"/"); err != nil {
  692. log.Error("uploadCodeToObs(%s) failed: %s", file.Name(), err.Error())
  693. return err
  694. }
  695. } else {
  696. input := &obs.PutFileInput{}
  697. input.Bucket = setting.Bucket
  698. input.Key = setting.CodePathPrefix + jobName + "/code/" + parentDir + file.Name()
  699. input.SourceFile = codePath + file.Name()
  700. _, err = storage.ObsCli.PutFile(input)
  701. if err != nil {
  702. log.Error("PutFile(%s) failed: %s", input.SourceFile, err.Error())
  703. return err
  704. }
  705. }
  706. }
  707. return nil
  708. }
  709. func obsMkdir(dir string) error {
  710. input := &obs.PutObjectInput{}
  711. input.Bucket = setting.Bucket
  712. input.Key = dir
  713. _, err := storage.ObsCli.PutObject(input)
  714. if err != nil {
  715. log.Error("PutObject(%s) failed: %s", input.Key, err.Error())
  716. return err
  717. }
  718. return nil
  719. }
  720. func paramCheckCreateTrainJob(form auth.CreateModelArtsTrainJobForm) error {
  721. if !strings.HasSuffix(form.BootFile, ".py") {
  722. log.Error("the boot file(%s) must be a python file", form.BootFile)
  723. return errors.New("启动文件必须是python文件")
  724. }
  725. if form.WorkServerNumber > 25 || form.WorkServerNumber < 1 {
  726. log.Error("the WorkServerNumber(%d) must be in (1,25)", form.WorkServerNumber)
  727. return errors.New("计算节点数必须在1-25之间")
  728. }
  729. return nil
  730. }
  731. func TrainJobShow(ctx *context.Context) {
  732. ctx.Data["PageIsCloudBrain"] = true
  733. var jobID = ctx.Params(":jobid")
  734. task, err := models.GetCloudbrainByJobID(jobID)
  735. if err != nil {
  736. log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error())
  737. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  738. return
  739. }
  740. attach, err := models.GetAttachmentByUUID(task.Uuid)
  741. if err != nil {
  742. log.Error("GetAttachmentByUUID(%s) failed:%v", jobID, err.Error())
  743. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  744. return
  745. }
  746. result, err := modelarts.GetTrainJob(jobID, strconv.FormatInt(task.VersionID, 10))
  747. if err != nil {
  748. log.Error("GetJob(%s) failed:%v", jobID, err.Error())
  749. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  750. return
  751. }
  752. if result != nil {
  753. result.CreateTime = time.Unix(int64(result.LongCreateTime/1000), 0).Format("2006-01-02 15:04:05")
  754. if result.Duration != 0 {
  755. result.TrainJobDuration = addZero(result.Duration/3600000) + ":" + addZero(result.Duration%3600000/60000) + ":" + addZero(result.Duration%60000/1000)
  756. } else {
  757. result.TrainJobDuration = "00:00:00"
  758. }
  759. result.Status = modelarts.TransTrainJobStatus(result.IntStatus)
  760. err = models.SetTrainJobStatusByJobID(jobID, result.Status, result.Duration, string(result.TrainJobDuration))
  761. if err != nil {
  762. ctx.ServerError("UpdateJob failed", err)
  763. return
  764. }
  765. result.DatasetName = attach.Name
  766. }
  767. resultLogFile, resultLog, err := trainJobGetLog(jobID)
  768. if err != nil {
  769. log.Error("trainJobGetLog(%s) failed:%v", jobID, err.Error())
  770. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  771. return
  772. }
  773. ctx.Data["log_file_name"] = resultLogFile.LogFileList[0]
  774. ctx.Data["log"] = resultLog
  775. ctx.Data["task"] = task
  776. ctx.Data["jobID"] = jobID
  777. ctx.Data["result"] = result
  778. ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow)
  779. }
  780. func addZero(t int64) (m string) {
  781. if t < 10 {
  782. m = "0" + strconv.FormatInt(t, 10)
  783. return m
  784. } else {
  785. return strconv.FormatInt(t, 10)
  786. }
  787. }
  788. func TrainJobGetLog(ctx *context.Context) {
  789. ctx.Data["PageIsTrainJob"] = true
  790. var jobID = ctx.Params(":jobid")
  791. var logFileName = ctx.Query("file_name")
  792. var baseLine = ctx.Query("base_line")
  793. var order = ctx.Query("order")
  794. if order != modelarts.OrderDesc && order != modelarts.OrderAsc {
  795. log.Error("order(%s) check failed", order)
  796. ctx.HTML(http.StatusBadRequest, tplModelArtsTrainJobShow)
  797. return
  798. }
  799. task, err := models.GetCloudbrainByJobID(jobID)
  800. if err != nil {
  801. log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error())
  802. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  803. return
  804. }
  805. result, err := modelarts.GetTrainJobLog(jobID, strconv.FormatInt(task.VersionID, 10), baseLine, logFileName, order, modelarts.Lines)
  806. if err != nil {
  807. log.Error("GetTrainJobLog(%s) failed:%v", jobID, err.Error())
  808. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  809. return
  810. }
  811. ctx.Data["log"] = result
  812. //ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow)
  813. }
  814. func trainJobGetLog(jobID string) (*models.GetTrainJobLogFileNamesResult, *models.GetTrainJobLogResult, error) {
  815. task, err := models.GetCloudbrainByJobID(jobID)
  816. if err != nil {
  817. log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error())
  818. return nil, nil, err
  819. }
  820. resultLogFile, err := modelarts.GetTrainJobLogFileNames(jobID, strconv.FormatInt(task.VersionID, 10))
  821. if err != nil {
  822. log.Error("GetTrainJobLogFileNames(%s) failed:%v", jobID, err.Error())
  823. return nil, nil, err
  824. }
  825. result, err := modelarts.GetTrainJobLog(jobID, strconv.FormatInt(task.VersionID, 10), "", resultLogFile.LogFileList[0], modelarts.OrderDesc, modelarts.Lines)
  826. if err != nil {
  827. log.Error("GetTrainJobLog(%s) failed:%v", jobID, err.Error())
  828. return nil, nil, err
  829. }
  830. return resultLogFile, result, err
  831. }
  832. func TrainJobDel(ctx *context.Context) {
  833. var jobID = ctx.Params(":jobid")
  834. task, err := models.GetCloudbrainByJobID(jobID)
  835. if err != nil {
  836. log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error())
  837. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  838. return
  839. }
  840. _, err = modelarts.DelTrainJob(jobID)
  841. if err != nil {
  842. log.Error("DelTrainJob(%s) failed:%v", task.JobName, err.Error())
  843. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  844. return
  845. }
  846. err = models.DeleteJob(task)
  847. if err != nil {
  848. ctx.ServerError("DeleteJob failed", err)
  849. return
  850. }
  851. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job")
  852. }
  853. func TrainJobStop(ctx *context.Context) {
  854. var jobID = ctx.Params(":jobid")
  855. task, err := models.GetCloudbrainByJobID(jobID)
  856. if err != nil {
  857. log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error())
  858. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  859. return
  860. }
  861. _, err = modelarts.StopTrainJob(jobID, strconv.FormatInt(task.VersionID, 10))
  862. if err != nil {
  863. log.Error("StopTrainJob(%s) failed:%v", task.JobName, err.Error())
  864. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobIndex, nil)
  865. return
  866. }
  867. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job")
  868. }
  869. func canUserCreateTrainJob(uid int64) (bool, error) {
  870. org, err := models.GetOrgByName(setting.AllowedOrg)
  871. if err != nil {
  872. log.Error("get allowed org failed: ", setting.AllowedOrg)
  873. return false, err
  874. }
  875. return org.IsOrgMember(uid)
  876. }
  877. func TrainJobGetConfigList(ctx *context.Context) {
  878. ctx.Data["PageIsTrainJob"] = true
  879. var jobID = ctx.Params(":jobid")
  880. var logFileName = ctx.Query("file_name")
  881. var baseLine = ctx.Query("base_line")
  882. var order = ctx.Query("order")
  883. if order != modelarts.OrderDesc && order != modelarts.OrderAsc {
  884. log.Error("order(%s) check failed", order)
  885. ctx.HTML(http.StatusBadRequest, tplModelArtsTrainJobShow)
  886. return
  887. }
  888. task, err := models.GetCloudbrainByJobID(jobID)
  889. if err != nil {
  890. log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error())
  891. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  892. return
  893. }
  894. result, err := modelarts.GetTrainJobLog(jobID, strconv.FormatInt(task.VersionID, 10), baseLine, logFileName, order, modelarts.Lines)
  895. if err != nil {
  896. log.Error("GetTrainJobLog(%s) failed:%v", jobID, err.Error())
  897. ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil)
  898. return
  899. }
  900. ctx.Data["log"] = result
  901. //ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow)
  902. }
  903. func getConfigList(perPage, page int, sortBy, order, searchContent, configType string) (*models.GetConfigListResult, error) {
  904. var result models.GetConfigListResult
  905. list, err := modelarts.GetConfigList(perPage, page, sortBy, order, searchContent, configType)
  906. if err != nil {
  907. log.Error("GetConfigList failed:", err)
  908. return &result, err
  909. }
  910. for _, config := range list.ParaConfigs {
  911. paraConfig, err := modelarts.GetParaConfig(config.ConfigName, configType)
  912. if err != nil {
  913. log.Error("GetParaConfig failed:", err)
  914. return &result, err
  915. }
  916. config.Result = paraConfig
  917. }
  918. return list, nil
  919. }
  920. func TrainJobShowModels(ctx *context.Context) {
  921. ctx.Data["PageIsCloudBrain"] = true
  922. jobID := ctx.Params(":jobid")
  923. parentDir := ctx.Query("parentDir")
  924. dirArray := strings.Split(parentDir, "/")
  925. task, err := models.GetCloudbrainByJobID(jobID)
  926. if err != nil {
  927. log.Error("no such job!", ctx.Data["msgID"])
  928. ctx.ServerError("no such job:", err)
  929. return
  930. }
  931. models, err := storage.GetObsListObject(task.JobName, parentDir)
  932. if err != nil {
  933. log.Info("get TrainJobListModel failed:", err)
  934. ctx.ServerError("GetObsListObject:", err)
  935. return
  936. }
  937. ctx.Data["Path"] = dirArray
  938. ctx.Data["Dirs"] = models
  939. ctx.Data["task"] = task
  940. ctx.Data["JobID"] = jobID
  941. ctx.HTML(200, tplModelArtsTrainJobShowModels)
  942. }
  943. func TrainJobDownloadModel(ctx *context.Context) {
  944. parentDir := ctx.Query("parentDir")
  945. fileName := ctx.Query("fileName")
  946. jobName := ctx.Query("jobName")
  947. url, err := storage.GetObsCreateSignedUrl(jobName, parentDir, fileName)
  948. if err != nil {
  949. log.Error("GetObsCreateSignedUrl failed: %v", err.Error(), ctx.Data["msgID"])
  950. ctx.ServerError("GetObsCreateSignedUrl", err)
  951. return
  952. }
  953. http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently)
  954. }