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.

mirror.go 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package mirror
  4. import (
  5. "context"
  6. "fmt"
  7. repo_model "code.gitea.io/gitea/models/repo"
  8. "code.gitea.io/gitea/modules/graceful"
  9. "code.gitea.io/gitea/modules/log"
  10. "code.gitea.io/gitea/modules/queue"
  11. "code.gitea.io/gitea/modules/setting"
  12. )
  13. // doMirrorSync causes this request to mirror itself
  14. func doMirrorSync(ctx context.Context, req *SyncRequest) {
  15. if req.ReferenceID == 0 {
  16. log.Warn("Skipping mirror sync request, no mirror ID was specified")
  17. return
  18. }
  19. switch req.Type {
  20. case PushMirrorType:
  21. _ = SyncPushMirror(ctx, req.ReferenceID)
  22. case PullMirrorType:
  23. _ = SyncPullMirror(ctx, req.ReferenceID)
  24. default:
  25. log.Error("Unknown Request type in queue: %v for MirrorID[%d]", req.Type, req.ReferenceID)
  26. }
  27. }
  28. var errLimit = fmt.Errorf("reached limit")
  29. // Update checks and updates mirror repositories.
  30. func Update(ctx context.Context, pullLimit, pushLimit int) error {
  31. if !setting.Mirror.Enabled {
  32. log.Warn("Mirror feature disabled, but cron job enabled: skip update")
  33. return nil
  34. }
  35. log.Trace("Doing: Update")
  36. handler := func(bean any) error {
  37. var repo *repo_model.Repository
  38. var mirrorType SyncType
  39. var referenceID int64
  40. if m, ok := bean.(*repo_model.Mirror); ok {
  41. if m.GetRepository(ctx) == nil {
  42. log.Error("Disconnected mirror found: %d", m.ID)
  43. return nil
  44. }
  45. repo = m.Repo
  46. mirrorType = PullMirrorType
  47. referenceID = m.RepoID
  48. } else if m, ok := bean.(*repo_model.PushMirror); ok {
  49. if m.GetRepository(ctx) == nil {
  50. log.Error("Disconnected push-mirror found: %d", m.ID)
  51. return nil
  52. }
  53. repo = m.Repo
  54. mirrorType = PushMirrorType
  55. referenceID = m.ID
  56. } else {
  57. log.Error("Unknown bean: %v", bean)
  58. return nil
  59. }
  60. // Check we've not been cancelled
  61. select {
  62. case <-ctx.Done():
  63. return fmt.Errorf("aborted")
  64. default:
  65. }
  66. // Push to the Queue
  67. if err := PushToQueue(mirrorType, referenceID); err != nil {
  68. if err == queue.ErrAlreadyInQueue {
  69. if mirrorType == PushMirrorType {
  70. log.Trace("PushMirrors for %-v already queued for sync", repo)
  71. } else {
  72. log.Trace("PullMirrors for %-v already queued for sync", repo)
  73. }
  74. return nil
  75. }
  76. return err
  77. }
  78. return nil
  79. }
  80. pullMirrorsRequested := 0
  81. if pullLimit != 0 {
  82. if err := repo_model.MirrorsIterate(ctx, pullLimit, func(_ int, bean any) error {
  83. if err := handler(bean); err != nil {
  84. return err
  85. }
  86. pullMirrorsRequested++
  87. return nil
  88. }); err != nil && err != errLimit {
  89. log.Error("MirrorsIterate: %v", err)
  90. return err
  91. }
  92. }
  93. pushMirrorsRequested := 0
  94. if pushLimit != 0 {
  95. if err := repo_model.PushMirrorsIterate(ctx, pushLimit, func(idx int, bean any) error {
  96. if err := handler(bean); err != nil {
  97. return err
  98. }
  99. pushMirrorsRequested++
  100. return nil
  101. }); err != nil && err != errLimit {
  102. log.Error("PushMirrorsIterate: %v", err)
  103. return err
  104. }
  105. }
  106. log.Trace("Finished: Update: %d pull mirrors and %d push mirrors queued", pullMirrorsRequested, pushMirrorsRequested)
  107. return nil
  108. }
  109. func queueHandler(items ...*SyncRequest) []*SyncRequest {
  110. for _, req := range items {
  111. doMirrorSync(graceful.GetManager().ShutdownContext(), req)
  112. }
  113. return nil
  114. }
  115. // InitSyncMirrors initializes a go routine to sync the mirrors
  116. func InitSyncMirrors() {
  117. StartSyncMirrors(queueHandler)
  118. }