mirror of
https://github.com/project-zot/zot.git
synced 2026-06-18 05:28:07 +08:00
feat(sync): move stream from global to per upstream
Signed-off-by: Vishwas Rajashekar <dev@vrajashkr.com>
This commit is contained in:
@@ -1565,6 +1565,33 @@ func validateSync(config *config.Config, logger zlog.Logger) error {
|
||||
// can't check with IsSyncEnabled(), because it can't test invalid sync configs
|
||||
if extensionsConfig != nil && extensionsConfig.Sync != nil && len(extensionsConfig.Sync.Registries) > 0 {
|
||||
for regID, regCfg := range extensionsConfig.Sync.Registries {
|
||||
// check streaming sync configuration
|
||||
if regCfg.IsStreamEnabled() {
|
||||
if !regCfg.OnDemand {
|
||||
msg := "streaming sync requires onDemand to be enabled"
|
||||
logger.Error().Err(zerr.ErrBadConfig).Int("id", regID).Interface("extensions.sync.registries[id]",
|
||||
extensionsConfig.Sync.Registries[regID]).Msg(msg)
|
||||
|
||||
return fmt.Errorf("%w: %s", zerr.ErrBadConfig, msg)
|
||||
}
|
||||
|
||||
if regCfg.MaxRetries != nil {
|
||||
msg := "maxRetries cannot be used when streaming sync is enabled"
|
||||
logger.Error().Err(zerr.ErrBadConfig).Int("id", regID).Interface("extensions.sync.registries[id]",
|
||||
extensionsConfig.Sync.Registries[regID]).Msg(msg)
|
||||
|
||||
return fmt.Errorf("%w: %s", zerr.ErrBadConfig, msg)
|
||||
}
|
||||
|
||||
if regCfg.RetryDelay != nil {
|
||||
msg := "retryDelay cannot be used when streaming sync is enabled"
|
||||
logger.Error().Err(zerr.ErrBadConfig).Int("id", regID).Interface("extensions.sync.registries[id]",
|
||||
extensionsConfig.Sync.Registries[regID]).Msg(msg)
|
||||
|
||||
return fmt.Errorf("%w: %s", zerr.ErrBadConfig, msg)
|
||||
}
|
||||
}
|
||||
|
||||
// check retry options are configured for sync
|
||||
if regCfg.MaxRetries != nil && regCfg.RetryDelay == nil {
|
||||
msg := "retryDelay is required when using maxRetries"
|
||||
|
||||
@@ -3446,3 +3446,101 @@ func TestBearerASMConfigValidation(t *testing.T) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestValidateStreamingSync(t *testing.T) {
|
||||
Convey("Test streaming sync config validation", t, func() {
|
||||
Convey("Valid streaming sync with onDemand enabled", func() {
|
||||
content := `{"storage":{"rootDirectory":"/tmp/zot"},
|
||||
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
|
||||
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
|
||||
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
|
||||
"onDemand": true, "stream": true}]}}}`
|
||||
cfg := config.New()
|
||||
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
|
||||
err := cli.LoadConfiguration(cfg, tmpfile)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("Reject streaming sync when onDemand is false", func() {
|
||||
content := `{"storage":{"rootDirectory":"/tmp/zot"},
|
||||
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
|
||||
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
|
||||
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
|
||||
"onDemand": false, "stream": true}]}}}`
|
||||
cfg := config.New()
|
||||
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
|
||||
err := cli.LoadConfiguration(cfg, tmpfile)
|
||||
So(err, ShouldNotBeNil)
|
||||
So(err, ShouldWrap, zerr.ErrBadConfig)
|
||||
So(err.Error(), ShouldContainSubstring, "streaming sync requires onDemand to be enabled")
|
||||
})
|
||||
|
||||
Convey("Reject streaming sync when maxRetries is set", func() {
|
||||
content := `{"storage":{"rootDirectory":"/tmp/zot"},
|
||||
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
|
||||
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
|
||||
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
|
||||
"onDemand": true, "stream": true, "maxRetries": 3, "retryDelay": "10s"}]}}}`
|
||||
cfg := config.New()
|
||||
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
|
||||
err := cli.LoadConfiguration(cfg, tmpfile)
|
||||
So(err, ShouldNotBeNil)
|
||||
So(err, ShouldWrap, zerr.ErrBadConfig)
|
||||
So(err.Error(), ShouldContainSubstring, "maxRetries cannot be used when streaming sync is enabled")
|
||||
})
|
||||
|
||||
Convey("Reject streaming sync when retryDelay is set without maxRetries", func() {
|
||||
content := `{"storage":{"rootDirectory":"/tmp/zot"},
|
||||
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
|
||||
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
|
||||
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
|
||||
"onDemand": true, "stream": true, "retryDelay": "10s"}]}}}`
|
||||
cfg := config.New()
|
||||
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
|
||||
err := cli.LoadConfiguration(cfg, tmpfile)
|
||||
So(err, ShouldNotBeNil)
|
||||
So(err, ShouldWrap, zerr.ErrBadConfig)
|
||||
So(err.Error(), ShouldContainSubstring, "retryDelay cannot be used when streaming sync is enabled")
|
||||
})
|
||||
|
||||
Convey("Non-streaming sync allows maxRetries with retryDelay", func() {
|
||||
content := `{"storage":{"rootDirectory":"/tmp/zot"},
|
||||
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
|
||||
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
|
||||
"extensions":{"sync": {"registries": [{"urls":["localhost:9999"],
|
||||
"onDemand": true, "maxRetries": 3, "retryDelay": "10s"}]}}}`
|
||||
cfg := config.New()
|
||||
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
|
||||
err := cli.LoadConfiguration(cfg, tmpfile)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("Streaming registry and non-streaming registry can coexist", func() {
|
||||
content := `{"storage":{"rootDirectory":"/tmp/zot"},
|
||||
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
|
||||
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
|
||||
"extensions":{"sync": {"registries": [
|
||||
{"urls":["localhost:9999"], "onDemand": true, "stream": true},
|
||||
{"urls":["localhost:9998"], "onDemand": true, "maxRetries": 3, "retryDelay": "10s"}
|
||||
]}}}`
|
||||
cfg := config.New()
|
||||
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
|
||||
err := cli.LoadConfiguration(cfg, tmpfile)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("Streaming upstream and periodic sync upstreams can coexist", func() {
|
||||
content := `{"storage":{"rootDirectory":"/tmp/zot"},
|
||||
"http":{"address":"127.0.0.1","port":"8080","realm":"zot",
|
||||
"auth":{"htpasswd":{"path":"test/data/htpasswd"},"failDelay":1}},
|
||||
"extensions":{"sync": {"registries": [
|
||||
{"urls":["localhost:9999"], "onDemand": true, "stream": true},
|
||||
{"urls":["localhost:9998"], "onDemand": false, "pollInterval": "12h"}
|
||||
]}}}`
|
||||
cfg := config.New()
|
||||
tmpfile := MakeTempFileWithContent(t, "zot-test.json", content)
|
||||
err := cli.LoadConfiguration(cfg, tmpfile)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user