From 43b2e63addcd34de69daee634eb791e7ced601f9 Mon Sep 17 00:00:00 2001 From: yaoge123 Date: Mon, 13 Apr 2026 07:14:05 +0800 Subject: [PATCH] feat(worker): add rsync success exit code configuration --- docs/zh_CN/get_started.md | 16 +++++++++ worker/config.go | 4 +++ worker/config_test.go | 75 +++++++++++++++++++++++++++++++++++++++ worker/provider.go | 16 +++++++++ 4 files changed, 111 insertions(+) diff --git a/docs/zh_CN/get_started.md b/docs/zh_CN/get_started.md index ae34afb..5458306 100644 --- a/docs/zh_CN/get_started.md +++ b/docs/zh_CN/get_started.md @@ -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 diff --git a/worker/config.go b/worker/config.go index dc91c79..0347fcc 100644 --- a/worker/config.go +++ b/worker/config.go @@ -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"` diff --git a/worker/config_test.go b/worker/config_test.go index 5b564ee..8ce96d0 100644 --- a/worker/config_test.go +++ b/worker/config_test.go @@ -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}) + }) } diff --git a/worker/provider.go b/worker/provider.go index dada7e3..f782fbc 100644 --- a/worker/provider.go +++ b/worker/provider.go @@ -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)