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.

cloudbrain.go 10 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. package models
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "time"
  7. "xorm.io/xorm"
  8. "code.gitea.io/gitea/modules/setting"
  9. "code.gitea.io/gitea/modules/timeutil"
  10. "xorm.io/builder"
  11. )
  12. type CloudbrainStatus string
  13. const (
  14. JobWaiting CloudbrainStatus = "WAITING"
  15. JobStopped CloudbrainStatus = "STOPPED"
  16. JobSucceeded CloudbrainStatus = "SUCCEEDED"
  17. JobFailed CloudbrainStatus = "FAILED"
  18. JobRunning CloudbrainStatus = "RUNNING"
  19. )
  20. type Cloudbrain struct {
  21. ID int64 `xorm:"pk autoincr"`
  22. JobID string `xorm:"INDEX NOT NULL"`
  23. JobName string `xorm:"INDEX"`
  24. Status string `xorm:"INDEX"`
  25. UserID int64 `xorm:"INDEX"`
  26. RepoID int64 `xorm:"INDEX"`
  27. SubTaskName string `xorm:"INDEX"`
  28. ContainerID string
  29. ContainerIp string
  30. CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
  31. UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
  32. CanDebug bool `xorm:"-"`
  33. User *User `xorm:"-"`
  34. Repo *Repository `xorm:"-"`
  35. }
  36. type CloudBrainLoginResult struct {
  37. Code string
  38. Msg string
  39. Payload map[string]interface{}
  40. }
  41. type TaskRole struct {
  42. Name string `json:"name"`
  43. TaskNumber int8 `json:"taskNumber"`
  44. MinSucceededTaskCount int8 `json:"minSucceededTaskCount"`
  45. MinFailedTaskCount int8 `json:"minFailedTaskCount"`
  46. CPUNumber int8 `json:"cpuNumber"`
  47. GPUNumber int8 `json:"gpuNumber"`
  48. MemoryMB int `json:"memoryMB"`
  49. ShmMB int `json:"shmMB"`
  50. Command string `json:"command"`
  51. NeedIBDevice bool `json:"needIBDevice"`
  52. IsMainRole bool `json:"isMainRole"`
  53. UseNNI bool `json:"useNNI"`
  54. }
  55. type StHostPath struct {
  56. Path string `json:"path"`
  57. MountPath string `json:"mountPath"`
  58. ReadOnly bool `json:"readOnly"`
  59. }
  60. type Volume struct {
  61. HostPath StHostPath `json:"hostPath"`
  62. }
  63. type CreateJobParams struct {
  64. JobName string `json:"jobName"`
  65. RetryCount int8 `json:"retryCount"`
  66. GpuType string `json:"gpuType"`
  67. Image string `json:"image"`
  68. TaskRoles []TaskRole `json:"taskRoles"`
  69. Volumes []Volume `json:"volumes"`
  70. }
  71. type CreateJobResult struct {
  72. Code string `json:"code"`
  73. Msg string `json:"msg"`
  74. Payload map[string]interface{} `json:"payload"`
  75. }
  76. type GetJobResult struct {
  77. Code string `json:"code"`
  78. Msg string `json:"msg"`
  79. Payload map[string]interface{} `json:"payload"`
  80. }
  81. type GetImagesResult struct {
  82. Code string `json:"code"`
  83. Msg string `json:"msg"`
  84. Payload map[string]*ImageInfo `json:"payload"`
  85. }
  86. type CloudbrainsOptions struct {
  87. ListOptions
  88. RepoID int64 // include all repos if empty
  89. UserID int64
  90. JobID int64
  91. SortType string
  92. CloudbrainIDs []int64
  93. // JobStatus CloudbrainStatus
  94. }
  95. type TaskPod struct {
  96. TaskRoleStatus struct {
  97. Name string `json:"name"`
  98. } `json:"taskRoleStatus"`
  99. TaskStatuses []struct {
  100. TaskIndex int `json:"taskIndex"`
  101. PodUID string `json:"podUid"`
  102. PodIP string `json:"podIp"`
  103. PodName string `json:"podName"`
  104. ContainerID string `json:"containerId"`
  105. ContainerIP string `json:"containerIp"`
  106. ContainerGpus string `json:"containerGpus"`
  107. State string `json:"state"`
  108. StartAt time.Time `json:"startAt"`
  109. FinishedAt time.Time `json:"finishedAt"`
  110. ExitCode int `json:"exitCode"`
  111. ExitDiagnostics string `json:"exitDiagnostics"`
  112. RetriedCount int `json:"retriedCount"`
  113. } `json:"taskStatuses"`
  114. }
  115. func ConvertToTaskPod(input map[string]interface{}) (TaskPod, error) {
  116. data, _ := json.Marshal(input)
  117. var taskPod TaskPod
  118. err := json.Unmarshal(data, &taskPod)
  119. return taskPod, err
  120. }
  121. type JobResultPayload struct {
  122. ID string `json:"id"`
  123. Name string `json:"name"`
  124. Platform string `json:"platform"`
  125. JobStatus struct {
  126. Username string `json:"username"`
  127. State string `json:"state"`
  128. SubState string `json:"subState"`
  129. ExecutionType string `json:"executionType"`
  130. Retries int `json:"retries"`
  131. CreatedTime int64 `json:"createdTime"`
  132. CompletedTime int64 `json:"completedTime"`
  133. AppID string `json:"appId"`
  134. AppProgress string `json:"appProgress"`
  135. AppTrackingURL string `json:"appTrackingUrl"`
  136. AppLaunchedTime int64 `json:"appLaunchedTime"`
  137. AppCompletedTime interface{} `json:"appCompletedTime"`
  138. AppExitCode int `json:"appExitCode"`
  139. AppExitDiagnostics string `json:"appExitDiagnostics"`
  140. AppExitType interface{} `json:"appExitType"`
  141. VirtualCluster string `json:"virtualCluster"`
  142. } `json:"jobStatus"`
  143. TaskRoles map[string]interface{} `json:"taskRoles"`
  144. Resource struct {
  145. CPU int `json:"cpu"`
  146. Memory string `json:"memory"`
  147. NvidiaComGpu int `json:"nvidia.com/gpu"`
  148. } `json:"resource"`
  149. Config struct {
  150. Image string `json:"image"`
  151. JobID string `json:"jobId"`
  152. GpuType string `json:"gpuType"`
  153. JobName string `json:"jobName"`
  154. JobType string `json:"jobType"`
  155. TaskRoles []struct {
  156. Name string `json:"name"`
  157. ShmMB int `json:"shmMB"`
  158. Command string `json:"command"`
  159. MemoryMB int `json:"memoryMB"`
  160. CPUNumber int `json:"cpuNumber"`
  161. GpuNumber int `json:"gpuNumber"`
  162. IsMainRole bool `json:"isMainRole"`
  163. TaskNumber int `json:"taskNumber"`
  164. NeedIBDevice bool `json:"needIBDevice"`
  165. MinFailedTaskCount int `json:"minFailedTaskCount"`
  166. MinSucceededTaskCount int `json:"minSucceededTaskCount"`
  167. } `json:"taskRoles"`
  168. RetryCount int `json:"retryCount"`
  169. } `json:"config"`
  170. Userinfo struct {
  171. User string `json:"user"`
  172. OrgID string `json:"org_id"`
  173. } `json:"userinfo"`
  174. }
  175. func ConvertToJobResultPayload(input map[string]interface{}) (JobResultPayload, error) {
  176. data, _ := json.Marshal(input)
  177. var jobResultPayload JobResultPayload
  178. err := json.Unmarshal(data, &jobResultPayload)
  179. return jobResultPayload, err
  180. }
  181. type ImagesResultPayload struct {
  182. Images []struct {
  183. ID int `json:"id"`
  184. Name string `json:"name"`
  185. Place string `json:"place"`
  186. Description string `json:"description"`
  187. Provider string `json:"provider"`
  188. Createtime string `json:"createtime"`
  189. Remark string `json:"remark"`
  190. } `json:"taskStatuses"`
  191. }
  192. type ImageInfo struct {
  193. ID int `json:"id"`
  194. Name string `json:"name"`
  195. Place string `json:"place"`
  196. Description string `json:"description"`
  197. Provider string `json:"provider"`
  198. Createtime string `json:"createtime"`
  199. Remark string `json:"remark"`
  200. PlaceView string
  201. }
  202. type CommitImageParams struct {
  203. Ip string `json:"ip"`
  204. TaskContainerId string `json:"taskContainerId"`
  205. ImageTag string `json:"imageTag"`
  206. ImageDescription string `json:"imageDescription"`
  207. }
  208. type CommitImageResult struct {
  209. Code string `json:"code"`
  210. Msg string `json:"msg"`
  211. Payload map[string]interface{} `json:"payload"`
  212. }
  213. type StopJobResult struct {
  214. Code string `json:"code"`
  215. Msg string `json:"msg"`
  216. }
  217. func Cloudbrains(opts *CloudbrainsOptions) ([]*Cloudbrain, int64, error) {
  218. sess := x.NewSession()
  219. defer sess.Close()
  220. var cond = builder.NewCond()
  221. if opts.RepoID > 0 {
  222. cond = cond.And(
  223. builder.Eq{"cloudbrain.repo_id": opts.RepoID},
  224. )
  225. }
  226. if opts.UserID > 0 {
  227. cond = cond.And(
  228. builder.Eq{"cloudbrain.user_id": opts.UserID},
  229. )
  230. }
  231. if (opts.JobID) > 0 {
  232. cond = cond.And(
  233. builder.Eq{"cloudbrain.job_id": opts.JobID},
  234. )
  235. }
  236. // switch opts.JobStatus {
  237. // case JobWaiting:
  238. // cond.And(builder.Eq{"cloudbrain.status": int(JobWaiting)})
  239. // case JobFailed:
  240. // cond.And(builder.Eq{"cloudbrain.status": int(JobFailed)})
  241. // case JobStopped:
  242. // cond.And(builder.Eq{"cloudbrain.status": int(JobStopped)})
  243. // case JobSucceeded:
  244. // cond.And(builder.Eq{"cloudbrain.status": int(JobSucceeded)})
  245. // }
  246. if len(opts.CloudbrainIDs) > 0 {
  247. cond = cond.And(builder.In("cloudbrain.id", opts.CloudbrainIDs))
  248. }
  249. count, err := sess.Where(cond).Count(new(Cloudbrain))
  250. if err != nil {
  251. return nil, 0, fmt.Errorf("Count: %v", err)
  252. }
  253. if opts.Page >= 0 && opts.PageSize > 0 {
  254. var start int
  255. if opts.Page == 0 {
  256. start = 0
  257. } else {
  258. start = (opts.Page - 1) * opts.PageSize
  259. }
  260. sess.Limit(opts.PageSize, start)
  261. }
  262. sess.OrderBy("cloudbrain.created_unix DESC")
  263. cloudbrains := make([]*Cloudbrain, 0, setting.UI.IssuePagingNum)
  264. if err := sess.Where(cond).Find(&cloudbrains); err != nil {
  265. return nil, 0, fmt.Errorf("Find: %v", err)
  266. }
  267. sess.Close()
  268. return cloudbrains, count, nil
  269. }
  270. func CreateCloudbrain(cloudbrain *Cloudbrain) (err error) {
  271. if _, err = x.Insert(cloudbrain); err != nil {
  272. return err
  273. }
  274. return nil
  275. }
  276. func getRepoCloudBrain(cb *Cloudbrain) (*Cloudbrain, error) {
  277. has, err := x.Get(cb)
  278. if err != nil {
  279. return nil, err
  280. } else if !has {
  281. return nil, errors.New("cloudbrain task is not found")
  282. }
  283. return cb, nil
  284. }
  285. func GetRepoCloudBrainByJobID(repoID int64, jobID string) (*Cloudbrain, error) {
  286. cb := &Cloudbrain{JobID: jobID, RepoID: repoID}
  287. return getRepoCloudBrain(cb)
  288. }
  289. func GetCloudbrainByJobID(jobID string) (*Cloudbrain, error) {
  290. cb := &Cloudbrain{JobID: jobID}
  291. return getRepoCloudBrain(cb)
  292. }
  293. func SetCloudbrainStatusByJobID(jobID string, status CloudbrainStatus) (err error) {
  294. cb := &Cloudbrain{JobID: jobID, Status: string(status)}
  295. _, err = x.Cols("status").Where("cloudbrain.job_id=?", jobID).Update(cb)
  296. return
  297. }
  298. func UpdateJob(job *Cloudbrain) error {
  299. return updateJob(x, job)
  300. }
  301. func updateJob(e Engine, job *Cloudbrain) error {
  302. var sess *xorm.Session
  303. sess = e.Where("job_id = ?", job.JobID)
  304. _, err := sess.Cols("status", "container_id", "container_ip").Update(job)
  305. return err
  306. }