镜像自地址
https://github.com/tuna/tunasync.git
已同步 2025-12-06 14:36:47 +00:00
feature(worker): framework of mirror provider
这个提交包含在:
@@ -1,2 +1,3 @@
|
|||||||
github.com/tuna/tunasync/internal
|
github.com/tuna/tunasync/internal
|
||||||
github.com/tuna/tunasync/manager
|
github.com/tuna/tunasync/manager
|
||||||
|
github.com/tuna/tunasync/worker
|
||||||
|
|||||||
@@ -1,13 +1,93 @@
|
|||||||
// mirror provider is the wrapper of mirror jobs
|
|
||||||
|
|
||||||
package worker
|
package worker
|
||||||
|
|
||||||
// a mirrorProvider instance
|
// mirror provider is the wrapper of mirror jobs
|
||||||
|
|
||||||
|
type providerType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
_WorkingDirKey = "working_dir"
|
||||||
|
_LogDirKey = "log_dir"
|
||||||
|
_LogFileKey = "log_file"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A mirrorProvider instance
|
||||||
type mirrorProvider interface {
|
type mirrorProvider interface {
|
||||||
|
// name
|
||||||
|
Name() string
|
||||||
|
|
||||||
|
// TODO: implement Run, Terminate and Hooks
|
||||||
// run mirror job
|
// run mirror job
|
||||||
Run()
|
Run()
|
||||||
// terminate mirror job
|
// terminate mirror job
|
||||||
Terminate()
|
Terminate()
|
||||||
// get context
|
// job hooks
|
||||||
Context()
|
Hooks()
|
||||||
|
|
||||||
|
Interval() int
|
||||||
|
|
||||||
|
WorkingDir() string
|
||||||
|
LogDir() string
|
||||||
|
LogFile() string
|
||||||
|
|
||||||
|
// enter context
|
||||||
|
EnterContext() *Context
|
||||||
|
// exit context
|
||||||
|
ExitContext() *Context
|
||||||
|
// return context
|
||||||
|
Context() *Context
|
||||||
|
}
|
||||||
|
|
||||||
|
type baseProvider struct {
|
||||||
|
ctx *Context
|
||||||
|
name string
|
||||||
|
interval int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *baseProvider) Name() string {
|
||||||
|
return p.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *baseProvider) EnterContext() *Context {
|
||||||
|
p.ctx = p.ctx.Enter()
|
||||||
|
return p.ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *baseProvider) ExitContext() *Context {
|
||||||
|
p.ctx, _ = p.ctx.Exit()
|
||||||
|
return p.ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *baseProvider) Context() *Context {
|
||||||
|
return p.ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *baseProvider) Interval() int {
|
||||||
|
return p.interval
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *baseProvider) WorkingDir() string {
|
||||||
|
if v, ok := p.ctx.Get(_WorkingDirKey); ok {
|
||||||
|
if s, ok := v.(string); ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic("working dir is impossible to be non-exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *baseProvider) LogDir() string {
|
||||||
|
if v, ok := p.ctx.Get(_LogDirKey); ok {
|
||||||
|
if s, ok := v.(string); ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic("log dir is impossible to be unavailable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *baseProvider) LogFile() string {
|
||||||
|
if v, ok := p.ctx.Get(_LogFileKey); ok {
|
||||||
|
if s, ok := v.(string); ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic("log dir is impossible to be unavailable")
|
||||||
}
|
}
|
||||||
|
|||||||
59
worker/provider_test.go
普通文件
59
worker/provider_test.go
普通文件
@@ -0,0 +1,59 @@
|
|||||||
|
package worker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRsyncProvider(t *testing.T) {
|
||||||
|
Convey("Rsync Provider should work", t, func() {
|
||||||
|
|
||||||
|
c := rsyncConfig{
|
||||||
|
name: "tuna",
|
||||||
|
upstreamURL: "rsync://rsync.tuna.moe/tuna/",
|
||||||
|
workingDir: "/srv/mirror/production/tuna",
|
||||||
|
logDir: "/var/log/tunasync",
|
||||||
|
logFile: "tuna.log",
|
||||||
|
useIPv6: true,
|
||||||
|
interval: 600,
|
||||||
|
}
|
||||||
|
|
||||||
|
provider, err := newRsyncProvider(c)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
|
So(provider.Name(), ShouldEqual, c.name)
|
||||||
|
So(provider.WorkingDir(), ShouldEqual, c.workingDir)
|
||||||
|
So(provider.LogDir(), ShouldEqual, c.logDir)
|
||||||
|
So(provider.LogFile(), ShouldEqual, c.logFile)
|
||||||
|
|
||||||
|
Convey("When entering a context (auto exit)", func() {
|
||||||
|
func() {
|
||||||
|
ctx := provider.EnterContext()
|
||||||
|
defer provider.ExitContext()
|
||||||
|
So(provider.WorkingDir(), ShouldEqual, c.workingDir)
|
||||||
|
newWorkingDir := "/srv/mirror/working/tuna"
|
||||||
|
ctx.Set(_WorkingDirKey, newWorkingDir)
|
||||||
|
So(provider.WorkingDir(), ShouldEqual, newWorkingDir)
|
||||||
|
}()
|
||||||
|
|
||||||
|
Convey("After context is done", func() {
|
||||||
|
So(provider.WorkingDir(), ShouldEqual, c.workingDir)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("When entering a context (manually exit)", func() {
|
||||||
|
ctx := provider.EnterContext()
|
||||||
|
So(provider.WorkingDir(), ShouldEqual, c.workingDir)
|
||||||
|
newWorkingDir := "/srv/mirror/working/tuna"
|
||||||
|
ctx.Set(_WorkingDirKey, newWorkingDir)
|
||||||
|
So(provider.WorkingDir(), ShouldEqual, newWorkingDir)
|
||||||
|
|
||||||
|
Convey("After context is done", func() {
|
||||||
|
provider.ExitContext()
|
||||||
|
So(provider.WorkingDir(), ShouldEqual, c.workingDir)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
48
worker/rsync_provider.go
普通文件
48
worker/rsync_provider.go
普通文件
@@ -0,0 +1,48 @@
|
|||||||
|
package worker
|
||||||
|
|
||||||
|
type rsyncConfig struct {
|
||||||
|
name string
|
||||||
|
upstreamURL, password, excludeFile string
|
||||||
|
workingDir, logDir, logFile string
|
||||||
|
useIPv6 bool
|
||||||
|
interval int
|
||||||
|
}
|
||||||
|
|
||||||
|
// An RsyncProvider provides the implementation to rsync-based syncing jobs
|
||||||
|
type rsyncProvider struct {
|
||||||
|
baseProvider
|
||||||
|
rsyncConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRsyncProvider(c rsyncConfig) (*rsyncProvider, error) {
|
||||||
|
// TODO: check config options
|
||||||
|
provider := &rsyncProvider{
|
||||||
|
baseProvider: baseProvider{
|
||||||
|
name: c.name,
|
||||||
|
ctx: NewContext(),
|
||||||
|
interval: c.interval,
|
||||||
|
},
|
||||||
|
rsyncConfig: c,
|
||||||
|
}
|
||||||
|
|
||||||
|
provider.ctx.Set(_WorkingDirKey, c.workingDir)
|
||||||
|
provider.ctx.Set(_LogDirKey, c.logDir)
|
||||||
|
provider.ctx.Set(_LogFileKey, c.logFile)
|
||||||
|
|
||||||
|
return provider, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: implement this
|
||||||
|
func (p *rsyncProvider) Run() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: implement this
|
||||||
|
func (p *rsyncProvider) Terminate() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: implement this
|
||||||
|
func (p *rsyncProvider) Hooks() {
|
||||||
|
|
||||||
|
}
|
||||||
在新工单中引用
屏蔽一个用户