Implement sync push mirror on commit (#19411)
Support synchronizing with the push mirrors whenever new commits are pushed or synced from pull mirror. Related Issues: #18220 Co-authored-by: delvh <dev.lh@web.de> Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>tokarchuk/v1.18
parent
496b8e3990
commit
49f9d43afe
@ -0,0 +1,30 @@ |
|||||||
|
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package migrations |
||||||
|
|
||||||
|
import ( |
||||||
|
"time" |
||||||
|
|
||||||
|
"code.gitea.io/gitea/models/repo" |
||||||
|
"code.gitea.io/gitea/modules/timeutil" |
||||||
|
"xorm.io/xorm" |
||||||
|
) |
||||||
|
|
||||||
|
func addSyncOnCommitColForPushMirror(x *xorm.Engine) error { |
||||||
|
type PushMirror struct { |
||||||
|
ID int64 `xorm:"pk autoincr"` |
||||||
|
RepoID int64 `xorm:"INDEX"` |
||||||
|
Repo *repo.Repository `xorm:"-"` |
||||||
|
RemoteName string |
||||||
|
|
||||||
|
SyncOnCommit bool `xorm:"NOT NULL DEFAULT true"` |
||||||
|
Interval time.Duration |
||||||
|
CreatedUnix timeutil.TimeStamp `xorm:"created"` |
||||||
|
LastUpdateUnix timeutil.TimeStamp `xorm:"INDEX last_update"` |
||||||
|
LastError string `xorm:"text"` |
||||||
|
} |
||||||
|
|
||||||
|
return x.Sync2(new(PushMirror)) |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package mirror |
||||||
|
|
||||||
|
import ( |
||||||
|
"code.gitea.io/gitea/modules/graceful" |
||||||
|
"code.gitea.io/gitea/modules/log" |
||||||
|
"code.gitea.io/gitea/modules/queue" |
||||||
|
"code.gitea.io/gitea/modules/setting" |
||||||
|
) |
||||||
|
|
||||||
|
var mirrorQueue queue.UniqueQueue |
||||||
|
|
||||||
|
// SyncType type of sync request
|
||||||
|
type SyncType int |
||||||
|
|
||||||
|
const ( |
||||||
|
// PullMirrorType for pull mirrors
|
||||||
|
PullMirrorType SyncType = iota |
||||||
|
// PushMirrorType for push mirrors
|
||||||
|
PushMirrorType |
||||||
|
) |
||||||
|
|
||||||
|
// SyncRequest for the mirror queue
|
||||||
|
type SyncRequest struct { |
||||||
|
Type SyncType |
||||||
|
ReferenceID int64 // RepoID for pull mirror, MirrorID for push mirror
|
||||||
|
} |
||||||
|
|
||||||
|
// StartSyncMirrors starts a go routine to sync the mirrors
|
||||||
|
func StartSyncMirrors(queueHandle func(data ...queue.Data) []queue.Data) { |
||||||
|
if !setting.Mirror.Enabled { |
||||||
|
return |
||||||
|
} |
||||||
|
mirrorQueue = queue.CreateUniqueQueue("mirror", queueHandle, new(SyncRequest)) |
||||||
|
|
||||||
|
go graceful.GetManager().RunWithShutdownFns(mirrorQueue.Run) |
||||||
|
} |
||||||
|
|
||||||
|
// AddPullMirrorToQueue adds repoID to mirror queue
|
||||||
|
func AddPullMirrorToQueue(repoID int64) { |
||||||
|
addMirrorToQueue(PullMirrorType, repoID) |
||||||
|
} |
||||||
|
|
||||||
|
// AddPushMirrorToQueue adds the push mirror to the queue
|
||||||
|
func AddPushMirrorToQueue(mirrorID int64) { |
||||||
|
addMirrorToQueue(PushMirrorType, mirrorID) |
||||||
|
} |
||||||
|
|
||||||
|
func addMirrorToQueue(syncType SyncType, referenceID int64) { |
||||||
|
if !setting.Mirror.Enabled { |
||||||
|
return |
||||||
|
} |
||||||
|
go func() { |
||||||
|
if err := PushToQueue(syncType, referenceID); err != nil { |
||||||
|
log.Error("Unable to push sync request for to the queue for pull mirror repo[%d]. Error: %v", referenceID, err) |
||||||
|
} |
||||||
|
}() |
||||||
|
} |
||||||
|
|
||||||
|
// PushToQueue adds the sync request to the queue
|
||||||
|
func PushToQueue(mirrorType SyncType, referenceID int64) error { |
||||||
|
return mirrorQueue.Push(&SyncRequest{ |
||||||
|
Type: mirrorType, |
||||||
|
ReferenceID: referenceID, |
||||||
|
}) |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package mirror |
||||||
|
|
||||||
|
import ( |
||||||
|
repo_model "code.gitea.io/gitea/models/repo" |
||||||
|
user_model "code.gitea.io/gitea/models/user" |
||||||
|
"code.gitea.io/gitea/modules/log" |
||||||
|
mirror_module "code.gitea.io/gitea/modules/mirror" |
||||||
|
"code.gitea.io/gitea/modules/notification/base" |
||||||
|
"code.gitea.io/gitea/modules/repository" |
||||||
|
) |
||||||
|
|
||||||
|
type mirrorNotifier struct { |
||||||
|
base.NullNotifier |
||||||
|
} |
||||||
|
|
||||||
|
var _ base.Notifier = &mirrorNotifier{} |
||||||
|
|
||||||
|
// NewNotifier create a new mirrorNotifier notifier
|
||||||
|
func NewNotifier() base.Notifier { |
||||||
|
return &mirrorNotifier{} |
||||||
|
} |
||||||
|
|
||||||
|
func (m *mirrorNotifier) NotifyPushCommits(_ *user_model.User, repo *repo_model.Repository, _ *repository.PushUpdateOptions, _ *repository.PushCommits) { |
||||||
|
syncPushMirrorWithSyncOnCommit(repo.ID) |
||||||
|
} |
||||||
|
|
||||||
|
func (m *mirrorNotifier) NotifySyncPushCommits(_ *user_model.User, repo *repo_model.Repository, _ *repository.PushUpdateOptions, _ *repository.PushCommits) { |
||||||
|
syncPushMirrorWithSyncOnCommit(repo.ID) |
||||||
|
} |
||||||
|
|
||||||
|
func syncPushMirrorWithSyncOnCommit(repoID int64) { |
||||||
|
pushMirrors, err := repo_model.GetPushMirrorsSyncedOnCommit(repoID) |
||||||
|
if err != nil { |
||||||
|
log.Error("repo_model.GetPushMirrorsSyncedOnCommit failed: %v", err) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
for _, mirror := range pushMirrors { |
||||||
|
mirror_module.AddPushMirrorToQueue(mirror.ID) |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue