Skip to content

Commit 0dc2bbd

Browse files
authored
Merge branch 'main' into K8SPG-594_delete_installed_ext
2 parents a4c54f2 + 76b98e6 commit 0dc2bbd

File tree

11 files changed

+287
-4
lines changed

11 files changed

+287
-4
lines changed

cmd/postgres-operator/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ func main() {
7979
features := feature.NewGate()
8080
err = features.SetFromMap(map[string]bool{
8181
string(feature.InstanceSidecars): true, // needed for PMM
82+
string(feature.PGBouncerSidecars): true, // K8SPG-645
8283
string(feature.TablespaceVolumes): true,
8384
})
8485
assertNoError(err)

e2e-tests/run-pr.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pitr
1010
scaling
1111
scheduled-backup
1212
self-healing
13+
sidecars
1314
start-from-backup
1415
tablespaces
1516
telemetry-transfer

e2e-tests/run-release.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pitr
1212
scaling
1313
scheduled-backup
1414
self-healing
15+
sidecars
1516
start-from-backup
1617
tablespaces
1718
telemetry-transfer
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestAssert
3+
timeout: 120
4+
---
5+
apiVersion: apiextensions.k8s.io/v1
6+
kind: CustomResourceDefinition
7+
metadata:
8+
name: perconapgclusters.pgv2.percona.com
9+
spec:
10+
group: pgv2.percona.com
11+
names:
12+
kind: PerconaPGCluster
13+
listKind: PerconaPGClusterList
14+
plural: perconapgclusters
15+
singular: perconapgcluster
16+
scope: Namespaced
17+
---
18+
apiVersion: kuttl.dev/v1beta1
19+
kind: TestAssert
20+
metadata:
21+
name: check-operator-deploy-status
22+
timeout: 120
23+
commands:
24+
- script: kubectl assert exist-enhanced deployment percona-postgresql-operator -n ${OPERATOR_NS:-$NAMESPACE} --field-selector status.readyReplicas=1
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestStep
3+
timeout: 10
4+
commands:
5+
- script: |-
6+
set -o errexit
7+
set -o xtrace
8+
9+
source ../../functions
10+
init_temp_dir # do this only in the first TestStep
11+
12+
deploy_operator
13+
deploy_client
14+
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestAssert
3+
timeout: 180
4+
---
5+
kind: StatefulSet
6+
apiVersion: apps/v1
7+
metadata:
8+
name: sidecars-repo-host
9+
labels:
10+
postgres-operator.crunchydata.com/cluster: sidecars
11+
postgres-operator.crunchydata.com/data: pgbackrest
12+
postgres-operator.crunchydata.com/pgbackrest: ''
13+
postgres-operator.crunchydata.com/pgbackrest-dedicated: ''
14+
ownerReferences:
15+
- apiVersion: postgres-operator.crunchydata.com/v1beta1
16+
kind: PostgresCluster
17+
name: sidecars
18+
controller: true
19+
blockOwnerDeletion: true
20+
status:
21+
observedGeneration: 1
22+
replicas: 1
23+
readyReplicas: 1
24+
currentReplicas: 1
25+
updatedReplicas: 1
26+
collisionCount: 0
27+
---
28+
kind: StatefulSet
29+
apiVersion: apps/v1
30+
metadata:
31+
labels:
32+
postgres-operator.crunchydata.com/cluster: sidecars
33+
postgres-operator.crunchydata.com/data: postgres
34+
postgres-operator.crunchydata.com/instance-set: instance1
35+
ownerReferences:
36+
- apiVersion: postgres-operator.crunchydata.com/v1beta1
37+
kind: PostgresCluster
38+
name: sidecars
39+
controller: true
40+
blockOwnerDeletion: true
41+
status:
42+
observedGeneration: 1
43+
replicas: 1
44+
readyReplicas: 1
45+
currentReplicas: 1
46+
updatedReplicas: 1
47+
collisionCount: 0
48+
---
49+
kind: Deployment
50+
apiVersion: apps/v1
51+
metadata:
52+
name: sidecars-pgbouncer
53+
labels:
54+
postgres-operator.crunchydata.com/cluster: sidecars
55+
postgres-operator.crunchydata.com/role: pgbouncer
56+
annotations:
57+
deployment.kubernetes.io/revision: '1'
58+
ownerReferences:
59+
- apiVersion: postgres-operator.crunchydata.com/v1beta1
60+
kind: PostgresCluster
61+
name: sidecars
62+
controller: true
63+
blockOwnerDeletion: true
64+
status:
65+
observedGeneration: 1
66+
replicas: 3
67+
updatedReplicas: 3
68+
readyReplicas: 3
69+
---
70+
kind: Job
71+
apiVersion: batch/v1
72+
metadata:
73+
labels:
74+
postgres-operator.crunchydata.com/cluster: sidecars
75+
postgres-operator.crunchydata.com/pgbackrest: ''
76+
postgres-operator.crunchydata.com/pgbackrest-backup: replica-create
77+
postgres-operator.crunchydata.com/pgbackrest-repo: repo1
78+
ownerReferences:
79+
- apiVersion: pgv2.percona.com/v2
80+
kind: PerconaPGBackup
81+
controller: true
82+
blockOwnerDeletion: true
83+
status:
84+
succeeded: 1
85+
---
86+
apiVersion: postgres-operator.crunchydata.com/v1beta1
87+
kind: PostgresCluster
88+
metadata:
89+
name: sidecars
90+
ownerReferences:
91+
- apiVersion: pgv2.percona.com/v2
92+
kind: PerconaPGCluster
93+
name: sidecars
94+
controller: true
95+
blockOwnerDeletion: true
96+
finalizers:
97+
- postgres-operator.crunchydata.com/finalizer
98+
status:
99+
instances:
100+
- name: instance1
101+
readyReplicas: 3
102+
replicas: 3
103+
updatedReplicas: 3
104+
observedGeneration: 1
105+
pgbackrest:
106+
repoHost:
107+
apiVersion: apps/v1
108+
kind: StatefulSet
109+
ready: true
110+
repos:
111+
- bound: true
112+
name: repo1
113+
replicaCreateBackupComplete: true
114+
stanzaCreated: true
115+
proxy:
116+
pgBouncer:
117+
readyReplicas: 3
118+
replicas: 3
119+
---
120+
apiVersion: pgv2.percona.com/v2
121+
kind: PerconaPGCluster
122+
metadata:
123+
labels:
124+
e2e: sidecars
125+
name: sidecars
126+
spec:
127+
instances:
128+
- affinity:
129+
podAntiAffinity:
130+
preferredDuringSchedulingIgnoredDuringExecution:
131+
- podAffinityTerm:
132+
labelSelector:
133+
matchLabels:
134+
postgres-operator.crunchydata.com/data: postgres
135+
topologyKey: kubernetes.io/hostname
136+
weight: 1
137+
dataVolumeClaimSpec:
138+
accessModes:
139+
- ReadWriteOnce
140+
resources:
141+
requests:
142+
storage: 1Gi
143+
name: instance1
144+
replicas: 3
145+
sidecars:
146+
- command:
147+
- sleep
148+
- 30d
149+
image: busybox
150+
name: sidecar1
151+
- command:
152+
- sleep
153+
- 30d
154+
image: busybox
155+
name: sidecar2
156+
proxy:
157+
pgBouncer:
158+
affinity:
159+
podAntiAffinity:
160+
preferredDuringSchedulingIgnoredDuringExecution:
161+
- podAffinityTerm:
162+
labelSelector:
163+
matchLabels:
164+
postgres-operator.crunchydata.com/role: pgbouncer
165+
topologyKey: kubernetes.io/hostname
166+
weight: 1
167+
replicas: 3
168+
sidecars:
169+
- command:
170+
- sleep
171+
- 30d
172+
image: busybox
173+
name: sidecar1
174+
status:
175+
pgbouncer:
176+
ready: 3
177+
size: 3
178+
postgres:
179+
instances:
180+
- name: instance1
181+
ready: 3
182+
size: 3
183+
ready: 3
184+
size: 3
185+
state: ready
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestStep
3+
timeout: 20
4+
commands:
5+
- script: |-
6+
set -o errexit
7+
set -o xtrace
8+
9+
source ../../functions
10+
11+
get_cr \
12+
| yq eval '.spec.instances[0].sidecars = [{"name": "sidecar1", "image": "busybox", "command": ["sleep", "30d"]}]' - \
13+
| yq eval '.spec.instances[0].sidecars += [{"name": "sidecar2", "image": "busybox", "command": ["sleep", "30d"]}]' - \
14+
| yq eval '.spec.proxy.pgBouncer.sidecars = [{"name": "sidecar1", "image": "busybox", "command": ["sleep", "30d"]}]' - \
15+
| kubectl -n "${NAMESPACE}" apply -f -
16+
timeout: 30
17+
18+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestStep
3+
delete:
4+
- apiVersion: pgv2.percona.com/v2
5+
kind: PerconaPGCluster
6+
metadata:
7+
name: self-healing
8+
- apiVersion: postgres-operator.crunchydata.com/v1beta1
9+
kind: PostgresCluster
10+
metadata:
11+
name: self-healing
12+
commands:
13+
- script: |-
14+
set -o errexit
15+
set -o xtrace
16+
17+
source ../../functions
18+
19+
destroy_operator
20+
timeout: 60
21+

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ require (
3030
go.opentelemetry.io/otel/trace v1.32.0
3131
go.uber.org/zap v1.27.0
3232
golang.org/x/crypto v0.30.0
33-
google.golang.org/grpc v1.67.1
33+
google.golang.org/grpc v1.68.1
3434
gotest.tools/v3 v3.5.1
3535
k8s.io/api v0.31.3
3636
k8s.io/apimachinery v0.31.3

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
357357
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
358358
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
359359
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
360-
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
361-
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
360+
google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0=
361+
google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw=
362362
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
363363
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
364364
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=

percona/watcher/wal.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ func WatchCommitTimestamps(ctx context.Context, cli client.Client, eventChan cha
6464

6565
latestBackup, err := getLatestBackup(ctx, cli, cr)
6666
if err != nil {
67-
log.Error(err, "get latest backup")
67+
if localCr.Status.State != pgv2.AppStateInit || (!errors.Is(err, errRunningBackup) && !errors.Is(err, errNoBackups)) {
68+
log.Error(err, "get latest backup")
69+
}
70+
6871
continue
6972
}
7073

@@ -104,6 +107,11 @@ func WatchCommitTimestamps(ctx context.Context, cli client.Client, eventChan cha
104107
}
105108
}
106109

110+
var (
111+
errRunningBackup = errors.New("backups are running")
112+
errNoBackups = errors.New("no backups found")
113+
)
114+
107115
func getLatestBackup(ctx context.Context, cli client.Client, cr *pgv2.PerconaPGCluster) (*pgv2.PerconaPGBackup, error) {
108116
backupList := &pgv2.PerconaPGBackupList{}
109117
err := cli.List(ctx, backupList, &client.ListOptions{
@@ -117,15 +125,25 @@ func getLatestBackup(ctx context.Context, cli client.Client, cr *pgv2.PerconaPGC
117125
return nil, err
118126
}
119127

128+
if len(backupList.Items) == 0 {
129+
return nil, errNoBackups
130+
}
131+
120132
latest := &pgv2.PerconaPGBackup{}
133+
runningBackupExists := false
121134
for _, backup := range backupList.Items {
122135
backup := backup
123136
if latest.Status.CompletedAt == nil || backup.Status.CompletedAt.After(latest.Status.CompletedAt.Time) {
124137
latest = &backup
138+
} else if backup.Status.State == pgv2.BackupStarting || backup.Status.State == pgv2.BackupRunning {
139+
runningBackupExists = true
125140
}
126141
}
127142

128143
if latest.Status.CompletedAt == nil {
144+
if runningBackupExists {
145+
return nil, errRunningBackup
146+
}
129147
return nil, errors.New("no completed backups found")
130148
}
131149

0 commit comments

Comments
 (0)