mirror of https://github.com/go-gitea/gitea
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>pull/20289/head^2
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