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

task.go 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Copyright 2019 Gitea. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package task
  5. import (
  6. "encoding/json"
  7. "fmt"
  8. "code.gitea.io/gitea/models"
  9. "code.gitea.io/gitea/modules/graceful"
  10. "code.gitea.io/gitea/modules/log"
  11. "code.gitea.io/gitea/modules/migrations/base"
  12. "code.gitea.io/gitea/modules/queue"
  13. repo_module "code.gitea.io/gitea/modules/repository"
  14. "code.gitea.io/gitea/modules/structs"
  15. "code.gitea.io/gitea/modules/timeutil"
  16. )
  17. // taskQueue is a global queue of tasks
  18. var taskQueue queue.Queue
  19. // Run a task
  20. func Run(t *models.Task) error {
  21. switch t.Type {
  22. case structs.TaskTypeMigrateRepo:
  23. return runMigrateTask(t)
  24. default:
  25. return fmt.Errorf("Unknown task type: %d", t.Type)
  26. }
  27. }
  28. // Init will start the service to get all unfinished tasks and run them
  29. func Init() error {
  30. taskQueue = queue.CreateQueue("task", handle, &models.Task{})
  31. if taskQueue == nil {
  32. return fmt.Errorf("Unable to create Task Queue")
  33. }
  34. go graceful.GetManager().RunWithShutdownFns(taskQueue.Run)
  35. return nil
  36. }
  37. func handle(data ...queue.Data) {
  38. for _, datum := range data {
  39. task := datum.(*models.Task)
  40. if err := Run(task); err != nil {
  41. log.Error("Run task failed: %v", err)
  42. }
  43. }
  44. }
  45. // MigrateRepository add migration repository to task
  46. func MigrateRepository(doer, u *models.User, opts base.MigrateOptions) error {
  47. task, err := CreateMigrateTask(doer, u, opts)
  48. if err != nil {
  49. return err
  50. }
  51. return taskQueue.Push(task)
  52. }
  53. // CreateMigrateTask creates a migrate task
  54. func CreateMigrateTask(doer, u *models.User, opts base.MigrateOptions) (*models.Task, error) {
  55. bs, err := json.Marshal(&opts)
  56. if err != nil {
  57. return nil, err
  58. }
  59. var task = models.Task{
  60. DoerID: doer.ID,
  61. OwnerID: u.ID,
  62. Type: structs.TaskTypeMigrateRepo,
  63. Status: structs.TaskStatusQueue,
  64. PayloadContent: string(bs),
  65. }
  66. if err := models.CreateTask(&task); err != nil {
  67. return nil, err
  68. }
  69. repo, err := repo_module.CreateRepository(doer, u, models.CreateRepoOptions{
  70. Name: opts.RepoName,
  71. Description: opts.Description,
  72. OriginalURL: opts.OriginalURL,
  73. GitServiceType: opts.GitServiceType,
  74. IsPrivate: opts.Private,
  75. IsMirror: opts.Mirror,
  76. Status: models.RepositoryBeingMigrated,
  77. })
  78. if err != nil {
  79. task.EndTime = timeutil.TimeStampNow()
  80. task.Status = structs.TaskStatusFailed
  81. err2 := task.UpdateCols("end_time", "status")
  82. if err2 != nil {
  83. log.Error("UpdateCols Failed: %v", err2.Error())
  84. }
  85. return nil, err
  86. }
  87. task.RepoID = repo.ID
  88. if err = task.UpdateCols("repo_id"); err != nil {
  89. return nil, err
  90. }
  91. return &task, nil
  92. }