mirror of
https://github.com/tuna/tunasync.git
synced 2026-07-03 12:28:07 +08:00
feat(worker): add rsync success exit code configuration
This commit is contained in:
@@ -63,8 +63,24 @@ name = "elvish"
|
||||
provider = "rsync"
|
||||
upstream = "rsync://rsync.elv.sh/elvish/"
|
||||
use_ipv6 = false
|
||||
|
||||
# 仅对 rsync / two-stage-rsync 生效
|
||||
# 与 dangerous_global_success_exit_codes / success_exit_codes 追加合并
|
||||
rsync_success_exit_codes = [23, 24]
|
||||
```
|
||||
|
||||
如果你想对所有 rsync 镜像统一放行某些 rsync 退出码,可在 `[global]` 里设置:
|
||||
|
||||
```conf
|
||||
dangerous_global_rsync_success_exit_codes = [23, 24]
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `rsync_success_exit_codes` 仅对 `provider = "rsync"` 或 `provider = "two-stage-rsync"` 生效。
|
||||
- 和 `dangerous_global_success_exit_codes`、`success_exit_codes` 一样,采用“全局 + 镜像追加合并”语义。
|
||||
- 推荐只放行 `23`、`24` 这类“同步完成但有部分文件问题”的退出码。
|
||||
|
||||
编辑 `~/tunasync_demo/manager.conf`:
|
||||
|
||||
```conf
|
||||
|
||||
@@ -66,6 +66,8 @@ type globalConfig struct {
|
||||
|
||||
// merged with mirror-specific options. make sure you know what you are doing!
|
||||
SuccessExitCodes []int `toml:"dangerous_global_success_exit_codes"`
|
||||
// rsync-only extension of dangerous_global_success_exit_codes
|
||||
RsyncSuccessExitCodes []int `toml:"dangerous_global_rsync_success_exit_codes"`
|
||||
}
|
||||
|
||||
type managerConfig struct {
|
||||
@@ -174,6 +176,8 @@ type mirrorConfig struct {
|
||||
|
||||
// will be merged with global option
|
||||
SuccessExitCodes []int `toml:"success_exit_codes"`
|
||||
// only effective for rsync and two-stage-rsync providers
|
||||
RsyncSuccessExitCodes []int `toml:"rsync_success_exit_codes"`
|
||||
|
||||
Command string `toml:"command"`
|
||||
FailOnMatch string `toml:"fail_on_match"`
|
||||
|
||||
@@ -577,4 +577,79 @@ success_exit_codes = [30, 40]
|
||||
So(ok, ShouldBeTrue)
|
||||
So(p.successExitCodes, ShouldResemble, []int{10, 20, 30, 40})
|
||||
})
|
||||
|
||||
Convey("rsync_success_exit_codes should be merged for rsync providers", t, func() {
|
||||
tmpfile, err := os.CreateTemp("", "tunasync")
|
||||
So(err, ShouldEqual, nil)
|
||||
defer os.Remove(tmpfile.Name())
|
||||
|
||||
cfgBlob1 := `
|
||||
[global]
|
||||
name = "test_worker"
|
||||
log_dir = "/var/log/tunasync/{{.Name}}"
|
||||
mirror_dir = "/data/mirrors"
|
||||
concurrent = 10
|
||||
interval = 240
|
||||
retry = 3
|
||||
timeout = 86400
|
||||
dangerous_global_success_exit_codes = [10]
|
||||
dangerous_global_rsync_success_exit_codes = [23, 24]
|
||||
|
||||
[manager]
|
||||
api_base = "https://127.0.0.1:5000"
|
||||
|
||||
[server]
|
||||
hostname = "worker1.example.com"
|
||||
listen_addr = "127.0.0.1"
|
||||
listen_port = 6000
|
||||
|
||||
[[mirrors]]
|
||||
name = "foo"
|
||||
provider = "rsync"
|
||||
upstream = "rsync://foo.bar/"
|
||||
success_exit_codes = [20]
|
||||
rsync_success_exit_codes = [25]
|
||||
|
||||
[[mirrors]]
|
||||
name = "bar"
|
||||
provider = "two-stage-rsync"
|
||||
stage1_profile = "debian"
|
||||
upstream = "rsync://foo.bar/debian/"
|
||||
success_exit_codes = [30]
|
||||
rsync_success_exit_codes = [26]
|
||||
|
||||
[[mirrors]]
|
||||
name = "cmd"
|
||||
provider = "command"
|
||||
upstream = "https://example.com/"
|
||||
command = "true"
|
||||
success_exit_codes = [40]
|
||||
rsync_success_exit_codes = [99]
|
||||
`
|
||||
|
||||
err = os.WriteFile(tmpfile.Name(), []byte(cfgBlob1), 0644)
|
||||
So(err, ShouldEqual, nil)
|
||||
defer tmpfile.Close()
|
||||
|
||||
cfg, err := LoadConfig(tmpfile.Name())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
providers := map[string]mirrorProvider{}
|
||||
for _, m := range cfg.Mirrors {
|
||||
p := newMirrorProvider(m, cfg)
|
||||
providers[p.Name()] = p
|
||||
}
|
||||
|
||||
rp, ok := providers["foo"].(*rsyncProvider)
|
||||
So(ok, ShouldBeTrue)
|
||||
So(rp.successExitCodes, ShouldResemble, []int{10, 20, 23, 24, 25})
|
||||
|
||||
tp, ok := providers["bar"].(*twoStageRsyncProvider)
|
||||
So(ok, ShouldBeTrue)
|
||||
So(tp.successExitCodes, ShouldResemble, []int{10, 30, 23, 24, 26})
|
||||
|
||||
cp, ok := providers["cmd"].(*cmdProvider)
|
||||
So(ok, ShouldBeTrue)
|
||||
So(cp.successExitCodes, ShouldResemble, []int{10, 40})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -260,6 +260,22 @@ func newMirrorProvider(mirror mirrorConfig, cfg *Config) mirrorProvider {
|
||||
if mirror.SuccessExitCodes != nil {
|
||||
successExitCodes = append(successExitCodes, mirror.SuccessExitCodes...)
|
||||
}
|
||||
|
||||
isRsyncProvider := mirror.Provider == provRsync || mirror.Provider == provTwoStageRsync
|
||||
if isRsyncProvider {
|
||||
if cfg.Global.RsyncSuccessExitCodes != nil {
|
||||
successExitCodes = append(successExitCodes, cfg.Global.RsyncSuccessExitCodes...)
|
||||
}
|
||||
if mirror.RsyncSuccessExitCodes != nil {
|
||||
successExitCodes = append(successExitCodes, mirror.RsyncSuccessExitCodes...)
|
||||
}
|
||||
} else if mirror.RsyncSuccessExitCodes != nil {
|
||||
logger.Warningf(
|
||||
"Mirror %s config item rsync_success_exit_codes is ignored for non-rsync provider",
|
||||
mirror.Name,
|
||||
)
|
||||
}
|
||||
|
||||
if len(successExitCodes) > 0 {
|
||||
logger.Infof("Non-zero success exit codes set for mirror %s: %v", mirror.Name, successExitCodes)
|
||||
provider.SetSuccessExitCodes(successExitCodes)
|
||||
|
||||
Reference in New Issue
Block a user