镜像自地址
https://github.com/tuna/tunasync.git
已同步 2025-12-05 22:16:47 +00:00
feature(worker): framework of mirror provider
这个提交包含在:
@@ -1,2 +1,3 @@
|
||||
github.com/tuna/tunasync/internal
|
||||
github.com/tuna/tunasync/manager
|
||||
github.com/tuna/tunasync/worker
|
||||
|
||||
@@ -1,13 +1,93 @@
|
||||
// mirror provider is the wrapper of mirror jobs
|
||||
|
||||
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 {
|
||||
// name
|
||||
Name() string
|
||||
|
||||
// TODO: implement Run, Terminate and Hooks
|
||||
// run mirror job
|
||||
Run()
|
||||
// terminate mirror job
|
||||
Terminate()
|
||||
// get context
|
||||
Context()
|
||||
// job hooks
|
||||
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() {
|
||||
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户