From c776bfb128043ac76feb2cf73f5385337eac4cb7 Mon Sep 17 00:00:00 2001 From: wang yan Date: Wed, 6 Dec 2023 10:08:35 +0800 Subject: [PATCH 1/3] support sentinel in v2.8.3 Signed-off-by: wang yan --- configuration/configuration.go | 3 ++ registry/handlers/app.go | 41 ++++++++++++++++++++++++- registry/handlers/app_test.go | 55 +++++++++++++++++++++++++++++++++- 3 files changed, 97 insertions(+), 2 deletions(-) diff --git a/configuration/configuration.go b/configuration/configuration.go index 7076df85d4f..cbb3ba1bf99 100644 --- a/configuration/configuration.go +++ b/configuration/configuration.go @@ -168,6 +168,9 @@ type Configuration struct { // Addr specifies the the redis instance available to the application. Addr string `yaml:"addr,omitempty"` + // SentinelMasterSet specifies the redis sentinel master set name. + SentinelMasterSet string `yaml:"sentinelMasterSet,omitempty"` + // Password string to use when making a connection. Password string `yaml:"password,omitempty"` diff --git a/registry/handlers/app.go b/registry/handlers/app.go index bf56cea22a5..56dfa8566f4 100644 --- a/registry/handlers/app.go +++ b/registry/handlers/app.go @@ -16,6 +16,7 @@ import ( "strings" "time" + "github.com/FZambia/sentinel" "github.com/distribution/reference" "github.com/docker/distribution" "github.com/docker/distribution/configuration" @@ -37,7 +38,6 @@ import ( "github.com/docker/distribution/registry/storage/driver/factory" storagemiddleware "github.com/docker/distribution/registry/storage/driver/middleware" "github.com/docker/distribution/version" - "github.com/docker/go-metrics" "github.com/docker/libtrust" "github.com/garyburd/redigo/redis" "github.com/gorilla/mux" @@ -499,6 +499,45 @@ func (app *App) configureRedis(configuration *configuration.Configuration) { return } + var getRedisAddr func() (string, error) + var testOnBorrow func(c redis.Conn, t time.Time) error + if configuration.Redis.SentinelMasterSet != "" { + sntnl := &sentinel.Sentinel{ + Addrs: strings.Split(configuration.Redis.Addr, ","), + MasterName: configuration.Redis.SentinelMasterSet, + Dial: func(addr string) (redis.Conn, error) { + c, err := redis.DialTimeout("tcp", addr, + configuration.Redis.DialTimeout, + configuration.Redis.ReadTimeout, + configuration.Redis.WriteTimeout) + if err != nil { + return nil, err + } + return c, nil + }, + } + getRedisAddr = func() (string, error) { + return sntnl.MasterAddr() + } + testOnBorrow = func(c redis.Conn, t time.Time) error { + if !sentinel.TestRole(c, "master") { + return errors.New("role check failed") + } + return nil + } + + } else { + getRedisAddr = func() (string, error) { + return configuration.Redis.Addr, nil + } + testOnBorrow = func(c redis.Conn, t time.Time) error { + // TODO(stevvooe): We can probably do something more interesting + // here with the health package. + _, err := c.Do("PING") + return err + } + } + pool := &redis.Pool{ Dial: func() (redis.Conn, error) { // TODO(stevvooe): Yet another use case for contextual timing. diff --git a/registry/handlers/app_test.go b/registry/handlers/app_test.go index 60a57e6c157..8a644d83d80 100644 --- a/registry/handlers/app_test.go +++ b/registry/handlers/app_test.go @@ -140,7 +140,29 @@ func TestAppDispatcher(t *testing.T) { // TestNewApp covers the creation of an application via NewApp with a // configuration. func TestNewApp(t *testing.T) { - ctx := context.Background() + + config := configuration.Configuration{ + Storage: configuration.Storage{ + "testdriver": nil, + "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ + "enabled": false, + }}, + }, + Auth: configuration.Auth{ + // For now, we simply test that new auth results in a viable + // application. + "silly": { + "realm": "realm-test", + "service": "service-test", + }, + }, + } + runAppWithConfig(t, config) +} + +// TestNewApp covers the creation of an application via NewApp with a +// configuration(with redis). +func TestNewAppWithRedis(t *testing.T) { config := configuration.Configuration{ Storage: configuration.Storage{ "testdriver": nil, @@ -157,7 +179,38 @@ func TestNewApp(t *testing.T) { }, }, } + config.Redis.Addr = "127.0.0.1:6379" + config.Redis.DB = 0 + runAppWithConfig(t, config) +} +// TestNewApp covers the creation of an application via NewApp with a +// configuration(with redis sentinel cluster). +func TestNewAppWithRedisSentinelCluster(t *testing.T) { + config := configuration.Configuration{ + Storage: configuration.Storage{ + "testdriver": nil, + "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ + "enabled": false, + }}, + }, + Auth: configuration.Auth{ + // For now, we simply test that new auth results in a viable + // application. + "silly": { + "realm": "realm-test", + "service": "service-test", + }, + }, + } + config.Redis.Addr = "192.168.0.11:26379,192.168.0.12:26379" + config.Redis.DB = 0 + config.Redis.SentinelMasterSet = "mymaster" + runAppWithConfig(t, config) +} + +func runAppWithConfig(t *testing.T, config configuration.Configuration) { + ctx := context.Background() // Mostly, with this test, given a sane configuration, we are simply // ensuring that NewApp doesn't panic. We might want to tweak this // behavior. From 8dcbe10b228810b1e4a487f3124d507a0fae35a1 Mon Sep 17 00:00:00 2001 From: wang yan Date: Wed, 6 Dec 2023 10:26:11 +0800 Subject: [PATCH 2/3] fix --- registry/handlers/app.go | 1 + 1 file changed, 1 insertion(+) diff --git a/registry/handlers/app.go b/registry/handlers/app.go index 56dfa8566f4..e82979fe74f 100644 --- a/registry/handlers/app.go +++ b/registry/handlers/app.go @@ -3,6 +3,7 @@ package handlers import ( "context" "crypto/rand" + "errors" "expvar" "fmt" "math" From f332fe93e9ea5b36070440c872dfbfaac2e05409 Mon Sep 17 00:00:00 2001 From: wang yan Date: Wed, 6 Dec 2023 10:47:54 +0800 Subject: [PATCH 3/3] fix --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2f353a49906..707d4184841 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,6 +36,7 @@ jobs: - name: Build working-directory: ./src/github.com/docker/distribution run: | + go env DCO_VERBOSITY=-q script/validate/dco GO111MODULE=on script/setup/install-dev-tools script/validate/vendor