Skip to content

Commit 07b3833

Browse files
csweichelFuristo
authored andcommitted
[registry-facade] Support Redis sentinel clients
1 parent 8b94185 commit 07b3833

File tree

8 files changed

+179
-37
lines changed

8 files changed

+179
-37
lines changed

components/registry-facade-api/go/config/config.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ func GetConfig(fn string) (*ServiceConfig, error) {
3131
return nil, err
3232
}
3333

34+
if cfg.Registry.IPFSCache != nil {
35+
rd := cfg.Registry.IPFSCache.Redis
36+
rd.Password = os.Getenv("REDIS_PASSWORD")
37+
cfg.Registry.IPFSCache.Redis = rd
38+
}
39+
3440
return &cfg, nil
3541
}
3642

@@ -60,9 +66,18 @@ type Config struct {
6066
}
6167

6268
type IPFSCacheConfig struct {
63-
Enabled bool `json:"enabled"`
64-
RedisAddr string `json:"redis"`
65-
IPFSAddr string `json:"ipfs"`
69+
Enabled bool `json:"enabled"`
70+
Redis RedisConfig `json:"redis"`
71+
IPFSAddr string `json:"ipfs"`
72+
}
73+
74+
type RedisConfig struct {
75+
SingleHostAddress string `json:"singleHostAddr,omitempty"`
76+
77+
MasterName string `json:"masterName,omitempty"`
78+
SentinelAddrs []string `json:"sentinelAddrs,omitempty"`
79+
Username string `json:"username,omitempty"`
80+
Password string `json:"-" env:"REDIS_PASSWORD"`
6681
}
6782

6883
// StaticLayerCfg configure statically added layer

components/registry-facade/example-config.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
"fixedSpecFN": "example-spec.json",
1414
"ipfs": {
1515
"enabled": true,
16-
"redis": "localhost:6379",
16+
"redis": {
17+
"singleHostAddr": "localhost:6379"
18+
},
1719
"ipfs": "/ip4/127.0.0.1/tcp/5001"
1820
}
1921
},

components/registry-facade/pkg/registry/registry.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,11 @@ func NewRegistry(cfg config.Config, newResolver ResolverProvider, reg prometheus
205205
if err != nil {
206206
return nil, xerrors.Errorf("cannot connect to IPFS: %w", err)
207207
}
208-
rdc := redis.NewClient(&redis.Options{
209-
Addr: cfg.IPFSCache.RedisAddr,
210-
})
208+
rdc, err := getRedisClient(cfg.IPFSCache.Redis)
209+
if err != nil {
210+
return nil, xerrors.Errorf("cannot connect to Redis: %w", err)
211+
}
212+
211213
ipfs = &IPFSStore{
212214
Redis: rdc,
213215
IPFS: core,
@@ -229,6 +231,30 @@ func NewRegistry(cfg config.Config, newResolver ResolverProvider, reg prometheus
229231
}, nil
230232
}
231233

234+
func getRedisClient(cfg config.RedisConfig) (*redis.Client, error) {
235+
if cfg.SingleHostAddress != "" {
236+
log.WithField("addr", cfg.SingleHostAddress).WithField("username", cfg.Username).Info("connecting to single Redis host")
237+
return redis.NewClient(&redis.Options{
238+
Addr: cfg.SingleHostAddress,
239+
Username: cfg.Username,
240+
Password: cfg.Password,
241+
}), nil
242+
}
243+
244+
if cfg.MasterName == "" {
245+
return nil, fmt.Errorf("redis masterName must not be empty")
246+
}
247+
if len(cfg.SentinelAddrs) == 0 {
248+
return nil, fmt.Errorf("redis sentinelAddrs must not be empty")
249+
}
250+
return redis.NewFailoverClient(&redis.FailoverOptions{
251+
MasterName: cfg.MasterName,
252+
SentinelAddrs: cfg.SentinelAddrs,
253+
Username: cfg.Username,
254+
Password: cfg.Password,
255+
}), nil
256+
}
257+
232258
// UpdateStaticLayer updates the static layer a registry-facade adds
233259
func (reg *Registry) UpdateStaticLayer(ctx context.Context, cfg []config.StaticLayerCfg) error {
234260
l, err := buildStaticLayer(ctx, cfg, reg.Resolver)

install/installer/pkg/components/registry-facade/configmap.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/gitpod-io/gitpod/installer/pkg/common"
1111
wsmanager "github.com/gitpod-io/gitpod/installer/pkg/components/ws-manager"
12+
"github.com/gitpod-io/gitpod/installer/pkg/config/v1/experimental"
1213
regfac "github.com/gitpod-io/gitpod/registry-facade/api/config"
1314

1415
corev1 "k8s.io/api/core/v1"
@@ -25,6 +26,24 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
2526
}
2627
}
2728

29+
var ipfsCache *regfac.IPFSCacheConfig
30+
_ = ctx.WithExperimental(func(ucfg *experimental.Config) error {
31+
if ucfg.Workspace == nil || !ucfg.Workspace.RegistryFacade.IPFSCache.Enabled {
32+
return nil
33+
}
34+
cacheCfg := ucfg.Workspace.RegistryFacade.IPFSCache
35+
ipfsCache = &regfac.IPFSCacheConfig{
36+
Enabled: true,
37+
IPFSAddr: cacheCfg.IPFSAddr,
38+
Redis: regfac.RedisConfig{
39+
MasterName: cacheCfg.Redis.MasterName,
40+
SentinelAddrs: cacheCfg.Redis.SentinelAddrs,
41+
Username: cacheCfg.Redis.Username,
42+
},
43+
}
44+
return nil
45+
})
46+
2847
rfcfg := regfac.ServiceConfig{
2948
Registry: regfac.Config{
3049
Port: ContainerPort,
@@ -53,6 +72,7 @@ func configmap(ctx *common.RenderContext) ([]runtime.Object, error) {
5372
Type: "image",
5473
},
5574
},
75+
IPFSCache: ipfsCache,
5676
},
5777
AuthCfg: "/mnt/pull-secret.json",
5878
PProfAddr: ":6060",

install/installer/pkg/components/registry-facade/daemonset.go

Lines changed: 75 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/gitpod-io/gitpod/installer/pkg/common"
1212
dockerregistry "github.com/gitpod-io/gitpod/installer/pkg/components/docker-registry"
1313
wsmanager "github.com/gitpod-io/gitpod/installer/pkg/components/ws-manager"
14+
"github.com/gitpod-io/gitpod/installer/pkg/config/v1/experimental"
1415

1516
appsv1 "k8s.io/api/apps/v1"
1617
corev1 "k8s.io/api/core/v1"
@@ -31,8 +32,10 @@ func daemonset(ctx *common.RenderContext) ([]runtime.Object, error) {
3132
hashObj = append(hashObj, objs...)
3233
}
3334

34-
var volumes []corev1.Volume
35-
var volumeMounts []corev1.VolumeMount
35+
var (
36+
volumes []corev1.Volume
37+
volumeMounts []corev1.VolumeMount
38+
)
3639

3740
if ctx.Config.Certificate.Name != "" {
3841
name := "config-certificates"
@@ -72,6 +75,39 @@ func daemonset(ctx *common.RenderContext) ([]runtime.Object, error) {
7275
return nil, fmt.Errorf("%s: invalid container registry config", Component)
7376
}
7477

78+
var envvars []corev1.EnvVar
79+
_ = ctx.WithExperimental(func(ucfg *experimental.Config) error {
80+
if ucfg.Workspace == nil || !ucfg.Workspace.RegistryFacade.IPFSCache.Enabled {
81+
return nil
82+
}
83+
84+
envvars = []corev1.EnvVar{
85+
{
86+
Name: "IPFS_HOST",
87+
ValueFrom: &corev1.EnvVarSource{
88+
FieldRef: &corev1.ObjectFieldSelector{
89+
FieldPath: "status.hostIP",
90+
},
91+
},
92+
},
93+
}
94+
if scr := ucfg.Workspace.RegistryFacade.IPFSCache.Redis.PasswordSecret; scr != "" {
95+
envvars = append(envvars, corev1.EnvVar{
96+
Name: "REDIS_PASSWORD",
97+
ValueFrom: &corev1.EnvVarSource{
98+
SecretKeyRef: &corev1.SecretKeySelector{
99+
LocalObjectReference: corev1.LocalObjectReference{
100+
Name: scr,
101+
},
102+
Key: "password",
103+
},
104+
},
105+
})
106+
}
107+
108+
return nil
109+
})
110+
75111
return []runtime.Object{&appsv1.DaemonSet{
76112
TypeMeta: common.TypeMetaDaemonset,
77113
ObjectMeta: metav1.ObjectMeta{
@@ -152,36 +188,46 @@ func daemonset(ctx *common.RenderContext) ([]runtime.Object, error) {
152188
Env: common.MergeEnv(
153189
common.DefaultEnv(&ctx.Config),
154190
common.TracingEnv(ctx),
155-
[]corev1.EnvVar{{
156-
Name: "GRPC_GO_RETRY",
157-
Value: "on",
158-
}, {
159-
Name: "NODENAME",
160-
ValueFrom: &corev1.EnvVarSource{
161-
FieldRef: &corev1.ObjectFieldSelector{
162-
FieldPath: "spec.nodeName",
191+
[]corev1.EnvVar{
192+
{
193+
Name: "GRPC_GO_RETRY",
194+
Value: "on",
195+
},
196+
{
197+
Name: "NODENAME",
198+
ValueFrom: &corev1.EnvVarSource{
199+
FieldRef: &corev1.ObjectFieldSelector{
200+
FieldPath: "spec.nodeName",
201+
},
163202
},
164203
},
165-
}},
204+
},
205+
),
206+
VolumeMounts: append(
207+
[]corev1.VolumeMount{
208+
{
209+
Name: "cache",
210+
MountPath: "/mnt/cache",
211+
},
212+
{
213+
Name: "config",
214+
MountPath: "/mnt/config",
215+
ReadOnly: true,
216+
},
217+
{
218+
Name: "ws-manager-client-tls-certs",
219+
MountPath: "/ws-manager-client-tls-certs",
220+
ReadOnly: true,
221+
},
222+
{
223+
Name: name,
224+
MountPath: "/mnt/pull-secret.json",
225+
SubPath: ".dockerconfigjson",
226+
},
227+
*common.InternalCAVolumeMount(),
228+
},
229+
volumeMounts...,
166230
),
167-
VolumeMounts: append([]corev1.VolumeMount{{
168-
Name: "cache",
169-
MountPath: "/mnt/cache",
170-
}, {
171-
Name: "config",
172-
MountPath: "/mnt/config",
173-
ReadOnly: true,
174-
}, {
175-
Name: "ws-manager-client-tls-certs",
176-
MountPath: "/ws-manager-client-tls-certs",
177-
ReadOnly: true,
178-
}, {
179-
Name: name,
180-
MountPath: "/mnt/pull-secret.json",
181-
SubPath: ".dockerconfigjson",
182-
},
183-
*common.InternalCAVolumeMount(),
184-
}, volumeMounts...),
185231
ReadinessProbe: &corev1.Probe{
186232
ProbeHandler: corev1.ProbeHandler{
187233
HTTPGet: &corev1.HTTPGetAction{

install/installer/pkg/config/v1/experimental/experimental.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,19 @@ type WorkspaceConfig struct {
2929
Limit resource.Quantity `json:"limit"`
3030
BurstLimit resource.Quantity `json:"burstLimit"`
3131
}
32+
33+
RegistryFacade struct {
34+
IPFSCache struct {
35+
Enabled bool `json:"enabled"`
36+
IPFSAddr string `json:"ipfsAddr"`
37+
Redis struct {
38+
MasterName string `json:"masterName"`
39+
SentinelAddrs []string `json:"sentinelAddrs"`
40+
Username string `json:"username"`
41+
PasswordSecret string `json:"passwordSecret"`
42+
} `json:"redis"`
43+
} `json:"ipfsCache"`
44+
} `json:"registryFacade"`
3245
}
3346

3447
type WebAppConfig struct {

install/installer/pkg/config/v1/experimental/validation.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
package experimental
66

7-
import "github.com/go-playground/validator/v10"
7+
import (
8+
"github.com/gitpod-io/gitpod/installer/pkg/cluster"
9+
"github.com/go-playground/validator/v10"
10+
)
811

912
var TracingSampleTypeList = map[TracingSampleType]struct{}{
1013
TracingSampleTypeConst: {},
@@ -19,3 +22,17 @@ var ValidationChecks = map[string]validator.Func{
1922
return ok
2023
},
2124
}
25+
26+
func ClusterValidation(cfg *Config) cluster.ValidationChecks {
27+
if cfg == nil {
28+
return nil
29+
}
30+
31+
var res cluster.ValidationChecks
32+
if cfg.Workspace != nil {
33+
if scr := cfg.Workspace.RegistryFacade.IPFSCache.Redis.PasswordSecret; scr != "" {
34+
res = append(res, cluster.CheckSecret(scr, cluster.CheckSecretRequiredData("password")))
35+
}
36+
}
37+
return res
38+
}

install/installer/pkg/config/v1/validation.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,5 +210,8 @@ func (v version) ClusterValidation(rcfg interface{}) cluster.ValidationChecks {
210210
return errors, nil
211211
})))
212212
}
213+
214+
res = append(res, experimental.ClusterValidation(cfg.Experimental)...)
215+
213216
return res
214217
}

0 commit comments

Comments
 (0)