Skip to content

Commit a9a0f78

Browse files
authored
Merge pull request #63 from cybertec-postgresql/pgbackrest-clone
Pgbackrest clone
2 parents 9d15392 + be4b072 commit a9a0f78

File tree

9 files changed

+439
-12
lines changed

9 files changed

+439
-12
lines changed

charts/postgres-operator/crds/postgresqls.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,39 @@ spec:
133133
uid:
134134
format: uuid
135135
type: string
136+
pgbackrest:
137+
type: object
138+
properties:
139+
configuration:
140+
type: object
141+
properties:
142+
secret:
143+
type: string
144+
options:
145+
type: object
146+
additionalProperties:
147+
type: string
148+
repo:
149+
type: object
150+
properties:
151+
storage:
152+
type: string
153+
enum:
154+
- "s3"
155+
- "gcs"
156+
- "azure"
157+
- "pvc"
158+
resource:
159+
type: string
160+
endpoint:
161+
type: string
162+
region:
163+
type: string
164+
required:
165+
- storage
166+
- resource
167+
required:
168+
- repo
136169
connectionPooler:
137170
type: object
138171
properties:

charts/postgres-operator/values.yaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -440,9 +440,11 @@ configMultisite:
440440
# Must be unique for each site.
441441
site: ""
442442
# IP address or hostname of shared etcd cluster used for multicluster operation.
443-
etcd_host: ""
444-
etcd_user: ""
445-
etcd_password: ""
443+
etcd:
444+
hosts:
445+
user: ""
446+
password: ""
447+
protocol: http
446448
# Timeout for cross site failover, and timeout for demoting to read only when accessing shared etcd cluster fails.
447449
# There should be adequate safety margin between the two to allow for demotion to take place.
448450
#ttl: 90

manifests/postgresql.crd.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,39 @@ spec:
131131
uid:
132132
format: uuid
133133
type: string
134+
pgbackrest:
135+
type: object
136+
properties:
137+
configuration:
138+
type: object
139+
properties:
140+
secret:
141+
type: string
142+
options:
143+
type: object
144+
additionalProperties:
145+
type: string
146+
repo:
147+
type: object
148+
properties:
149+
storage:
150+
type: string
151+
enum:
152+
- "s3"
153+
- "gcs"
154+
- "azure"
155+
- "pvc"
156+
resource:
157+
type: string
158+
endpoint:
159+
type: string
160+
region:
161+
type: string
162+
required:
163+
- storage
164+
- resource
165+
required:
166+
- repo
134167
connectionPooler:
135168
type: object
136169
properties:

pkg/apis/cpo.opensource.cybertec.at/v1/crds.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,68 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
213213
Type: "string",
214214
Format: "uuid",
215215
},
216+
"pgbackrest": {
217+
Type: "object",
218+
Properties: map[string]apiextv1.JSONSchemaProps{
219+
"configuration": {
220+
Type: "object",
221+
Properties: map[string]apiextv1.JSONSchemaProps{
222+
"secret": {
223+
Type: "string",
224+
},
225+
},
226+
},
227+
"options": {
228+
Type: "object",
229+
AdditionalProperties: &apiextv1.JSONSchemaPropsOrBool{
230+
Schema: &apiextv1.JSONSchemaProps{
231+
Type: "string",
232+
XPreserveUnknownFields: util.True(),
233+
},
234+
},
235+
},
236+
"repo": {
237+
Type: "object",
238+
Properties: map[string]apiextv1.JSONSchemaProps{
239+
"storage": {
240+
Type: "string",
241+
Enum: []apiextv1.JSON{
242+
{
243+
Raw: []byte(`"s3"`),
244+
},
245+
{
246+
Raw: []byte(`"gcs"`),
247+
},
248+
{
249+
Raw: []byte(`"azure"`),
250+
},
251+
{
252+
Raw: []byte(`"pvc"`),
253+
},
254+
},
255+
},
256+
"resource": {
257+
Type: "string",
258+
},
259+
"endpoint": {
260+
Type: "string",
261+
},
262+
"region": {
263+
Type: "string",
264+
},
265+
"account": {
266+
Type: "string",
267+
},
268+
"key": {
269+
Type: "string",
270+
},
271+
"keyType": {
272+
Type: "string",
273+
},
274+
},
275+
},
276+
},
277+
},
216278
},
217279
},
218280
"connectionPooler": {

pkg/apis/cpo.opensource.cybertec.at/v1/postgresql_type.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -203,14 +203,15 @@ type TLSDescription struct {
203203

204204
// CloneDescription describes which cluster the new should clone and up to which point in time
205205
type CloneDescription struct {
206-
ClusterName string `json:"cluster,omitempty"`
207-
UID string `json:"uid,omitempty"`
208-
EndTimestamp string `json:"timestamp,omitempty"`
209-
S3WalPath string `json:"s3_wal_path,omitempty"`
210-
S3Endpoint string `json:"s3_endpoint,omitempty"`
211-
S3AccessKeyId string `json:"s3_access_key_id,omitempty"`
212-
S3SecretAccessKey string `json:"s3_secret_access_key,omitempty"`
213-
S3ForcePathStyle *bool `json:"s3_force_path_style,omitempty" defaults:"false"`
206+
ClusterName string `json:"cluster,omitempty"`
207+
UID string `json:"uid,omitempty"`
208+
EndTimestamp string `json:"timestamp,omitempty"`
209+
S3WalPath string `json:"s3_wal_path,omitempty"`
210+
S3Endpoint string `json:"s3_endpoint,omitempty"`
211+
S3AccessKeyId string `json:"s3_access_key_id,omitempty"`
212+
S3SecretAccessKey string `json:"s3_secret_access_key,omitempty"`
213+
S3ForcePathStyle *bool `json:"s3_force_path_style,omitempty" defaults:"false"`
214+
Pgbackrest *PgbackrestClone `json:"pgbackrest,omitempty"`
214215
}
215216

216217
// Sidecar defines a container to be run in the same pod as the Postgres container.
@@ -283,6 +284,12 @@ type Pgbackrest struct {
283284
Resources *Resources `json:"resources,omitempty"`
284285
}
285286

287+
type PgbackrestClone struct {
288+
Repo Repo `json:"repo"`
289+
Options map[string]string `json:"options"`
290+
Configuration Configuration `json:"configuration"`
291+
}
292+
286293
type Repo struct {
287294
Name string `json:"name"`
288295
Storage string `json:"storage"`

pkg/apis/cpo.opensource.cybertec.at/v1/zz_generated.deepcopy.go

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/cluster/cluster.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,12 @@ func (c *Cluster) Create() (err error) {
366366
c.logger.Info("a monitoring secret was successfully created")
367367
}
368368

369+
if specHasPgbackrestClone(&c.Postgresql.Spec) {
370+
if err := c.createPgbackrestCloneConfig(); err != nil {
371+
return fmt.Errorf("could not create pgbackrest clone config: %v", err)
372+
}
373+
}
374+
369375
if c.multisiteEnabled() {
370376
c.logger.Infof("waiting for load balancer IP to be assigned")
371377
c.waitForPrimaryLoadBalancerIp()
@@ -1067,6 +1073,28 @@ func (c *Cluster) Update(oldSpec, newSpec *cpov1.Postgresql) error {
10671073
}
10681074
}()
10691075

1076+
// Clone configmap for pgbackrest
1077+
func() {
1078+
if specHasPgbackrestClone(&oldSpec.Spec) {
1079+
if specHasPgbackrestClone(&newSpec.Spec) {
1080+
// TODO: if we know cluster state and it has been initialized, then should ignore this
1081+
if err := c.updatePgbackrestCloneConfig(); err != nil {
1082+
c.logger.Warningf("could not update pgbackrest clone config: %v", err)
1083+
updateFailed = true
1084+
}
1085+
} else {
1086+
if err := c.deletePgbackrestCloneConfig(); err != nil {
1087+
c.logger.Warningf("could not delete pgbackrest clone config: %v", err)
1088+
}
1089+
}
1090+
} else if specHasPgbackrestClone(&newSpec.Spec) {
1091+
c.logger.Warningf("Can't add a clone specification after cluster has been initialized")
1092+
updateFailed = true
1093+
} else {
1094+
// TODO: try to delete just in case?
1095+
}
1096+
}()
1097+
10701098
// Statefulset
10711099
func() {
10721100
oldSs, err := c.generateStatefulSet(&oldSpec.Spec)
@@ -1225,6 +1253,10 @@ func specHasPgbackrestPVCRepo(newSpec *cpov1.PostgresSpec) bool {
12251253
return false
12261254
}
12271255

1256+
func specHasPgbackrestClone(newSpec *cpov1.PostgresSpec) bool {
1257+
return newSpec.Clone != nil && newSpec.Clone.Pgbackrest != nil
1258+
}
1259+
12281260
func syncResources(a, b *v1.ResourceRequirements) bool {
12291261
for _, res := range []v1.ResourceName{
12301262
v1.ResourceCPU,
@@ -1291,6 +1323,10 @@ func (c *Cluster) Delete() {
12911323
c.logger.Warningf("could not delete pod disruption budget: %v", err)
12921324
}
12931325

1326+
if err := c.deletePgbackrestCloneConfig(); err != nil {
1327+
c.logger.Warningf("could not delete pgbackrest clone config: %v", err)
1328+
}
1329+
12941330
for _, role := range []PostgresRole{Master, Replica, ClusterPods} {
12951331

12961332
if !c.patroniKubernetesUseConfigMaps() {

0 commit comments

Comments
 (0)