Skip to content

Commit ed396f9

Browse files
authored
Merge branch 'main' into K8SPG-873
2 parents c189e1d + 9ace0ef commit ed396f9

10 files changed

Lines changed: 183 additions & 83 deletions

File tree

cmd/postgres-operator/main.go

Lines changed: 62 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"time"
1515
"unicode"
1616

17+
"github.com/kelseyhightower/envconfig"
1718
volumesnapshotv1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1"
1819
"github.com/pkg/errors"
1920
"go.opentelemetry.io/otel"
@@ -283,69 +284,68 @@ func initManager(ctx context.Context) (runtime.Options, error) {
283284

284285
options.HealthProbeBindAddress = ":8081"
285286

287+
options.Controller.GroupKindConcurrency = map[string]int{
288+
"PostgresCluster." + v1beta1.GroupVersion.Group: 1,
289+
"PGUpgrade." + v1beta1.GroupVersion.Group: 1,
290+
"PGAdmin." + v1beta1.GroupVersion.Group: 1,
291+
"PerconaPGCluster." + v2.GroupVersion.Group: 1,
292+
"PerconaPGUpgrade." + v2.GroupVersion.Group: 1,
293+
"PerconaPGBackup." + v2.GroupVersion.Group: 1,
294+
"PerconaPGRestore." + v2.GroupVersion.Group: 1,
295+
}
296+
297+
// K8SPG-915
298+
envs := new(envConfig)
299+
if err := envconfig.Process("", envs); err != nil {
300+
return options, errors.Wrap(err, "parse env vars")
301+
}
302+
303+
options.LeaseDuration = &envs.LeaseDuration
304+
options.RenewDeadline = &envs.RenewDeadline
305+
options.RetryPeriod = &envs.RetryPeriod
306+
options.PprofBindAddress = envs.PprofBindAddress
307+
308+
options.LeaderElection = envs.LeaderElection
309+
if options.LeaderElection {
310+
options.LeaderElectionID = perconaRuntime.ElectionID
311+
}
312+
286313
// Enable leader elections when configured with a valid Lease.coordination.k8s.io name.
287314
// - https://docs.k8s.io/concepts/architecture/leases
288315
// - https://releases.k8s.io/v1.30.0/pkg/apis/coordination/validation/validation.go#L26
289-
if lease := os.Getenv("PGO_CONTROLLER_LEASE_NAME"); len(lease) > 0 {
316+
if lease := envs.LeaderElectionID; options.LeaderElection && len(lease) > 0 {
290317
if errs := validation.IsDNS1123Subdomain(lease); len(errs) > 0 {
291318
return options, fmt.Errorf("value for PGO_CONTROLLER_LEASE_NAME is invalid: %v", errs)
292319
}
293320

294-
options.LeaderElection = true
295321
options.LeaderElectionID = lease
296-
options.LeaderElectionNamespace = os.Getenv("PGO_NAMESPACE")
297-
} else {
298-
// K8SPG-761
299-
options.LeaderElection = true
300-
options.LeaderElectionID = perconaRuntime.ElectionID
322+
options.LeaderElectionNamespace = envs.LeaderElectionNamespace
301323
}
302324

303-
// Check PGO_TARGET_NAMESPACE for backwards compatibility with
304-
// "singlenamespace" installations
305-
singlenamespace := strings.TrimSpace(os.Getenv("PGO_TARGET_NAMESPACE"))
306-
307-
// Check PGO_TARGET_NAMESPACES for non-cluster-wide, multi-namespace
308-
// installations
309-
multinamespace := strings.TrimSpace(os.Getenv("PGO_TARGET_NAMESPACES"))
310-
311-
// Initialize DefaultNamespaces if any target namespaces are set
312-
if len(singlenamespace) > 0 || len(multinamespace) > 0 {
325+
if len(envs.SingleNamespace) > 0 || len(envs.MultiNamespaces) > 0 {
326+
// Initialize DefaultNamespaces if any target namespaces are set
313327
options.Cache.DefaultNamespaces = map[string]runtime.CacheConfig{}
314-
}
315328

316-
if len(singlenamespace) > 0 {
317-
options.Cache.DefaultNamespaces[singlenamespace] = runtime.CacheConfig{}
318-
}
319-
320-
if len(multinamespace) > 0 {
321-
for _, namespace := range strings.FieldsFunc(multinamespace, func(c rune) bool {
322-
return c != '-' && !unicode.IsLetter(c) && !unicode.IsNumber(c)
323-
}) {
324-
options.Cache.DefaultNamespaces[namespace] = runtime.CacheConfig{}
329+
if len(envs.SingleNamespace) > 0 {
330+
options.Cache.DefaultNamespaces[envs.SingleNamespace] = runtime.CacheConfig{}
325331
}
326-
}
327332

328-
options.Controller.GroupKindConcurrency = map[string]int{
329-
"PostgresCluster." + v1beta1.GroupVersion.Group: 1,
330-
"PGUpgrade." + v1beta1.GroupVersion.Group: 1,
331-
"PGAdmin." + v1beta1.GroupVersion.Group: 1,
332-
"PerconaPGCluster." + v2.GroupVersion.Group: 1,
333-
"PerconaPGUpgrade." + v2.GroupVersion.Group: 1,
334-
"PerconaPGBackup." + v2.GroupVersion.Group: 1,
335-
"PerconaPGRestore." + v2.GroupVersion.Group: 1,
336-
}
337-
338-
if s := os.Getenv("PGO_WORKERS"); s != "" {
339-
if i, err := strconv.Atoi(s); err == nil && i > 0 {
340-
for kind := range options.Controller.GroupKindConcurrency {
341-
options.Controller.GroupKindConcurrency[kind] = i
333+
if len(envs.MultiNamespaces) > 0 {
334+
for _, namespace := range strings.FieldsFunc(envs.MultiNamespaces, func(c rune) bool {
335+
return c != '-' && !unicode.IsLetter(c) && !unicode.IsNumber(c)
336+
}) {
337+
options.Cache.DefaultNamespaces[namespace] = runtime.CacheConfig{}
342338
}
343-
} else {
344-
log.Error(err, "PGO_WORKERS must be a positive number")
345339
}
346340
}
347341

348-
options.PprofBindAddress = os.Getenv("PPROF_BIND_ADDRESS")
342+
if envs.Workers < 0 {
343+
log.Error(nil, "PGO_WORKERS must be a non-negative number; 0 disables the override")
344+
} else if envs.Workers > 0 {
345+
for kind := range options.Controller.GroupKindConcurrency {
346+
options.Controller.GroupKindConcurrency[kind] = envs.Workers
347+
}
348+
}
349349

350350
return options, nil
351351
}
@@ -519,3 +519,20 @@ func isOpenshift(ctx context.Context, cfg *rest.Config) bool {
519519

520520
return false
521521
}
522+
523+
type envConfig struct {
524+
LeaderElection bool `default:"true" envconfig:"PGO_CONTROLLER_LEADER_ELECTION_ENABLED"`
525+
LeaderElectionID string `envconfig:"PGO_CONTROLLER_LEASE_NAME"`
526+
LeaderElectionNamespace string `envconfig:"PGO_NAMESPACE"`
527+
528+
LeaseDuration time.Duration `default:"60s" envconfig:"PGO_CONTROLLER_LEASE_DURATION"`
529+
RenewDeadline time.Duration `default:"40s" envconfig:"PGO_CONTROLLER_RENEW_DEADLINE"`
530+
RetryPeriod time.Duration `default:"10s" envconfig:"PGO_CONTROLLER_RETRY_PERIOD"`
531+
532+
SingleNamespace string `envconfig:"PGO_TARGET_NAMESPACE"`
533+
MultiNamespaces string `envconfig:"PGO_TARGET_NAMESPACES"`
534+
535+
PprofBindAddress string `envconfig:"PPROF_BIND_ADDRESS"`
536+
537+
Workers int `envconfig:"PGO_WORKERS"`
538+
}

cmd/postgres-operator/main_test.go

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package main
66

77
import (
8-
"context"
98
"reflect"
109
"testing"
1110
"time"
@@ -15,7 +14,7 @@ import (
1514
)
1615

1716
func TestInitManager(t *testing.T) {
18-
ctx := context.Background()
17+
ctx := t.Context()
1918
t.Run("Defaults", func(t *testing.T) {
2019
options, err := initManager(ctx)
2120
assert.NilError(t, err)
@@ -39,13 +38,19 @@ func TestInitManager(t *testing.T) {
3938

4039
assert.Assert(t, options.Cache.DefaultNamespaces == nil)
4140
assert.Assert(t, options.LeaderElection == true)
41+
assert.Assert(t, options.LeaseDuration.Seconds() == 60)
42+
assert.Assert(t, options.RenewDeadline.Seconds() == 40)
43+
assert.Assert(t, options.RetryPeriod.Seconds() == 10)
4244

4345
{
4446
options.Cache.SyncPeriod = nil
4547
options.Controller.GroupKindConcurrency = nil
4648
options.HealthProbeBindAddress = ""
4749
options.LeaderElection = false
4850
options.LeaderElectionID = ""
51+
options.LeaseDuration = nil
52+
options.RenewDeadline = nil
53+
options.RetryPeriod = nil
4954

5055
assert.Assert(t, reflect.ValueOf(options).IsZero(),
5156
"expected remaining fields to be unset:\n%+v", options)
@@ -62,6 +67,13 @@ func TestInitManager(t *testing.T) {
6267
assert.ErrorContains(t, err, "PGO_CONTROLLER_LEASE_NAME")
6368
assert.ErrorContains(t, err, "invalid")
6469

70+
assert.Assert(t, options.LeaderElection == true)
71+
assert.Equal(t, options.LeaderElectionNamespace, "")
72+
73+
t.Setenv("PGO_CONTROLLER_LEADER_ELECTION_ENABLED", "false")
74+
options, err = initManager(ctx)
75+
assert.NilError(t, err)
76+
6577
assert.Assert(t, options.LeaderElection == false)
6678
assert.Equal(t, options.LeaderElectionNamespace, "")
6779
})
@@ -106,7 +118,11 @@ func TestInitManager(t *testing.T) {
106118
t.Setenv("PGO_WORKERS", v)
107119

108120
options, err := initManager(ctx)
109-
assert.NilError(t, err)
121+
if v == "3.14" {
122+
assert.ErrorContains(t, err, "parse env vars: envconfig.Process: assigning PGO_WORKERS to Workers: converting '3.14' to type int. details: strconv.ParseInt: parsing \"3.14\": invalid syntax")
123+
} else {
124+
assert.NilError(t, err)
125+
}
110126
assert.DeepEqual(t, options.Controller.GroupKindConcurrency,
111127
map[string]int{
112128
"PGAdmin.postgres-operator.crunchydata.com": 1,
@@ -148,4 +164,16 @@ func TestInitManager(t *testing.T) {
148164
assert.NilError(t, err)
149165
assert.DeepEqual(t, options.PprofBindAddress, "pprof-addr")
150166
})
167+
168+
t.Run("Duration options", func(t *testing.T) {
169+
t.Setenv("PGO_CONTROLLER_LEASE_DURATION", "1s")
170+
t.Setenv("PGO_CONTROLLER_RENEW_DEADLINE", "2s")
171+
t.Setenv("PGO_CONTROLLER_RETRY_PERIOD", "3s")
172+
options, err := initManager(ctx)
173+
assert.NilError(t, err)
174+
175+
assert.Equal(t, options.LeaseDuration.Seconds(), float64(1))
176+
assert.Equal(t, options.RenewDeadline.Seconds(), float64(2))
177+
assert.Equal(t, options.RetryPeriod.Seconds(), float64(3))
178+
})
151179
}

config/manager/default/manager.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ spec:
3939
value: "1"
4040
- name: PPROF_BIND_ADDRESS
4141
value: "0"
42+
- name: PGO_CONTROLLER_LEADER_ELECTION_ENABLED
43+
value: "true"
44+
- name: PGO_CONTROLLER_LEASE_NAME
45+
value: ""
46+
- name: PGO_CONTROLLER_LEASE_DURATION
47+
value: "60s"
48+
- name: PGO_CONTROLLER_RENEW_DEADLINE
49+
value: "40s"
50+
- name: PGO_CONTROLLER_RETRY_PERIOD
51+
value: "10s"
4252
- name: PGO_FEATURE_GATES
4353
value: ""
4454
ports:

deploy/bundle.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56411,6 +56411,16 @@ spec:
5641156411
value: "1"
5641256412
- name: PPROF_BIND_ADDRESS
5641356413
value: "0"
56414+
- name: PGO_CONTROLLER_LEADER_ELECTION_ENABLED
56415+
value: "true"
56416+
- name: PGO_CONTROLLER_LEASE_NAME
56417+
value: ""
56418+
- name: PGO_CONTROLLER_LEASE_DURATION
56419+
value: 60s
56420+
- name: PGO_CONTROLLER_RENEW_DEADLINE
56421+
value: 40s
56422+
- name: PGO_CONTROLLER_RETRY_PERIOD
56423+
value: 10s
5641456424
- name: PGO_FEATURE_GATES
5641556425
value: ""
5641656426
image: docker.io/perconalab/percona-postgresql-operator:main

deploy/cw-bundle.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56409,6 +56409,16 @@ spec:
5640956409
value: "1"
5641056410
- name: PPROF_BIND_ADDRESS
5641156411
value: "0"
56412+
- name: PGO_CONTROLLER_LEADER_ELECTION_ENABLED
56413+
value: "true"
56414+
- name: PGO_CONTROLLER_LEASE_NAME
56415+
value: ""
56416+
- name: PGO_CONTROLLER_LEASE_DURATION
56417+
value: 60s
56418+
- name: PGO_CONTROLLER_RENEW_DEADLINE
56419+
value: 40s
56420+
- name: PGO_CONTROLLER_RETRY_PERIOD
56421+
value: 10s
5641256422
- name: PGO_FEATURE_GATES
5641356423
value: ""
5641456424
image: docker.io/perconalab/percona-postgresql-operator:main

deploy/cw-operator.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ spec:
4646
value: "1"
4747
- name: PPROF_BIND_ADDRESS
4848
value: "0"
49+
- name: PGO_CONTROLLER_LEADER_ELECTION_ENABLED
50+
value: "true"
51+
- name: PGO_CONTROLLER_LEASE_NAME
52+
value: ""
53+
- name: PGO_CONTROLLER_LEASE_DURATION
54+
value: 60s
55+
- name: PGO_CONTROLLER_RENEW_DEADLINE
56+
value: 40s
57+
- name: PGO_CONTROLLER_RETRY_PERIOD
58+
value: 10s
4959
- name: PGO_FEATURE_GATES
5060
value: ""
5161
image: docker.io/perconalab/percona-postgresql-operator:main

deploy/operator.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ spec:
4949
value: "1"
5050
- name: PPROF_BIND_ADDRESS
5151
value: "0"
52+
- name: PGO_CONTROLLER_LEADER_ELECTION_ENABLED
53+
value: "true"
54+
- name: PGO_CONTROLLER_LEASE_NAME
55+
value: ""
56+
- name: PGO_CONTROLLER_LEASE_DURATION
57+
value: 60s
58+
- name: PGO_CONTROLLER_RENEW_DEADLINE
59+
value: 40s
60+
- name: PGO_CONTROLLER_RETRY_PERIOD
61+
value: 10s
5262
- name: PGO_FEATURE_GATES
5363
value: ""
5464
image: docker.io/perconalab/percona-postgresql-operator:main

0 commit comments

Comments
 (0)