Skip to content

Commit 3f35acf

Browse files
author
Anthony Landreth
committed
Use force-conflicts instead of overwrite
1 parent f7c4e7b commit 3f35acf

File tree

8 files changed

+141
-30
lines changed

8 files changed

+141
-30
lines changed
Binary file not shown.

docs/content/reference/pgo_backup.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ Backup cluster
77

88
### Synopsis
99

10-
Backup allows you to take a backup of a PostgreSQL cluster, either using
11-
the current "spec.backups.pgbackrest.manual" settings on the PostgreSQL cluster
12-
or by overwriting those settings using the flags
10+
Backup allows you to take a backup of a PostgreSQL cluster, using
11+
the current "spec.backups.pgbackrest.manual" settings on the PostgreSQL cluster.
12+
Overwriting those settings requires the --force-conflicts flag.
1313

1414
#### RBAC Requirements
1515
Resources Verbs
@@ -31,16 +31,16 @@ pgo backup CLUSTER_NAME [flags]
3131
# on the 'hippo' postgrescluster and trigger a backup
3232
pgo backup hippo --repoName="repo1" --options="--type=full"
3333
34-
# When receiving an ownership conflict message
35-
pgo backup hippo --overwrite
34+
# Resolve ownership conflict
35+
pgo backup hippo --force-conflicts
3636
```
3737

3838
### Options
3939

4040
```
41+
--force-conflicts take ownership and overwrite the backup annotation
4142
-h, --help help for backup
4243
--options stringArray options for taking a backup; can be used multiple times
43-
--overwrite overwrite the backup annotation
4444
--repoName string repoName to backup to
4545
```
4646

docs/content/reference/pgo_restore.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,15 @@ pgo restore CLUSTER_NAME [flags]
2626
2727
# Restore the 'hippo' cluster to a specific point in time
2828
pgo restore hippo --repoName repo1 --options '--type=time --target="2021-06-09 14:15:11-04"'
29+
30+
# Resolve ownership conflict
31+
pgo restore hippo --force-conflicts
2932
```
3033

3134
### Options
3235

3336
```
37+
--force-conflicts take ownership and overwrite the restore annotation
3438
-h, --help help for restore
3539
--options stringArray options to pass to the "pgbackrest restore" command; can be used multiple times
3640
--repoName string repository to restore from

internal/cmd/backup.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ func newBackupCommand(config *internal.Config) *cobra.Command {
3535
cmdBackup := &cobra.Command{
3636
Use: "backup CLUSTER_NAME",
3737
Short: "Backup cluster",
38-
Long: `Backup allows you to take a backup of a PostgreSQL cluster, either using
39-
the current "spec.backups.pgbackrest.manual" settings on the PostgreSQL cluster
40-
or by overwriting those settings using the flags
38+
Long: `Backup allows you to take a backup of a PostgreSQL cluster, using
39+
the current "spec.backups.pgbackrest.manual" settings on the PostgreSQL cluster.
40+
Overwriting those settings requires the --force-conflicts flag.
4141
4242
#### RBAC Requirements
4343
Resources Verbs
@@ -54,18 +54,18 @@ pgo backup hippo
5454
# on the 'hippo' postgrescluster and trigger a backup
5555
pgo backup hippo --repoName="repo1" --options="--type=full"
5656
57-
# When receiving an ownership conflict message
58-
pgo backup hippo --overwrite
57+
# Resolve ownership conflict
58+
pgo backup hippo --force-conflicts
5959
`)
6060

6161
// Limit the number of args, that is, only one cluster name
6262
cmdBackup.Args = cobra.ExactArgs(1)
6363

64-
// `backup` command accepts `repoName`, `overwrite` and `options` flags;
64+
// `backup` command accepts `repoName`, `force-conflicts` and `options` flags;
6565
// multiple options flags can be used, with each becoming a new line
6666
// in the options array on the spec
6767
backup := pgBackRestBackup{}
68-
cmdBackup.Flags().BoolVar(&backup.Overwrite, "overwrite", false, "overwrite the backup annotation")
68+
cmdBackup.Flags().BoolVar(&backup.ForceConflicts, "force-conflicts", false, "take ownership and overwrite the backup annotation")
6969
cmdBackup.Flags().StringVar(&backup.RepoName, "repoName", "", "repoName to backup to")
7070
cmdBackup.Flags().StringArrayVar(&backup.Options, "options", []string{},
7171
"options for taking a backup; can be used multiple times")
@@ -112,7 +112,7 @@ pgo backup hippo --overwrite
112112
// Update the spec/annotate
113113
// TODO(benjaminjb): Would we want to allow a dry-run option here?
114114
patchOptions := metav1.PatchOptions{}
115-
if backup.Overwrite {
115+
if backup.ForceConflicts {
116116
b := true
117117
patchOptions.Force = &b
118118
}
@@ -139,9 +139,9 @@ pgo backup hippo --overwrite
139139
}
140140

141141
type pgBackRestBackup struct {
142-
Options []string
143-
RepoName string
144-
Overwrite bool
142+
Options []string
143+
RepoName string
144+
ForceConflicts bool
145145
}
146146

147147
func (config pgBackRestBackup) modifyIntent(

internal/cmd/restore.go

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ pgo restore hippo --repoName repo1
4747
4848
# Restore the 'hippo' cluster to a specific point in time
4949
pgo restore hippo --repoName repo1 --options '--type=time --target="2021-06-09 14:15:11-04"'
50+
51+
# Resolve ownership conflict
52+
pgo restore hippo --force-conflicts
5053
`)
5154

5255
restore := pgBackRestRestore{Config: config}
@@ -57,6 +60,8 @@ pgo restore hippo --repoName repo1 --options '--type=time --target="2021-06-09 1
5760
cmd.Flags().StringVar(&restore.RepoName, "repoName", "",
5861
"repository to restore from")
5962

63+
cmd.Flags().BoolVar(&restore.ForceConflicts, "force-conflicts", false, "take ownership and overwrite the restore annotation")
64+
6065
// Only one positional argument: the PostgresCluster name.
6166
cmd.Args = cobra.ExactArgs(1)
6267

@@ -104,8 +109,9 @@ This is recommended after your restore is complete. Running "pgo restore" will e
104109
type pgBackRestRestore struct {
105110
*internal.Config
106111

107-
Options []string
108-
RepoName string
112+
Options []string
113+
RepoName string
114+
ForceConflicts bool
109115

110116
PostgresCluster string
111117
}
@@ -153,14 +159,20 @@ func (config pgBackRestRestore) Run(ctx context.Context) error {
153159
if err != nil {
154160
return err
155161
}
162+
patchOptions := metav1.PatchOptions{
163+
DryRun: []string{metav1.DryRunAll},
164+
}
165+
166+
if config.ForceConflicts {
167+
b := true
168+
patchOptions.Force = &b
169+
}
156170

157171
// Perform a dry-run patch to understand what settings will be used should
158172
// the restore proceed.
159173
cluster, err = client.Namespace(namespace).Patch(ctx,
160174
config.PostgresCluster, types.ApplyPatchType, patch,
161-
config.Patch.PatchOptions(metav1.PatchOptions{
162-
DryRun: []string{metav1.DryRunAll},
163-
}))
175+
config.Patch.PatchOptions(patchOptions))
164176
if err != nil {
165177
return err
166178
}
@@ -176,10 +188,16 @@ func (config pgBackRestRestore) Run(ctx context.Context) error {
176188
return nil
177189
}
178190

191+
patchOptions = metav1.PatchOptions{}
192+
if config.ForceConflicts {
193+
b := true
194+
patchOptions.Force = &b
195+
}
196+
179197
// They agreed to continue. Send the patch again without dry-run.
180198
_, err = client.Namespace(namespace).Patch(ctx,
181199
config.PostgresCluster, types.ApplyPatchType, patch,
182-
config.Patch.PatchOptions(metav1.PatchOptions{}))
200+
config.Patch.PatchOptions(patchOptions))
183201

184202
if err == nil {
185203
fmt.Fprintf(config.Out, "%s/%s patched\n",
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
# The cluster should not have changed.
3+
apiVersion: postgres-operator.crunchydata.com/v1beta1
4+
kind: PostgresCluster
5+
metadata:
6+
name: backup-cluster
7+
spec:
8+
backups:
9+
pgbackrest:
10+
manual:
11+
options:
12+
- --type=full
13+
repoName: repo4
14+
15+
---
16+
apiVersion: kuttl.dev/v1beta1
17+
kind: TestStep
18+
commands:
19+
- script: |
20+
pgbackrest_backup_annotation() {
21+
kubectl get --namespace "${NAMESPACE}" postgrescluster/backup-cluster \
22+
--output 'go-template={{ index .metadata.annotations "postgres-operator.crunchydata.com/pgbackrest-backup" }}'
23+
}
24+
25+
kubectl --namespace "${NAMESPACE}" annotate postgrescluster/backup-cluster \
26+
postgres-operator.crunchydata.com/pgbackrest-backup="$(date)" --overwrite || exit
27+
28+
PRIOR=$(pgbackrest_backup_annotation)
29+
RESULT=$(kubectl-pgo --namespace "${NAMESPACE}" backup backup-cluster --force-conflicts)
30+
CURRENT=$(pgbackrest_backup_annotation)
31+
32+
if [ "${CURRENT}" = "${PRIOR}" ]; then
33+
printf 'Expected annotation to change, got %q' "${CURRENT}"
34+
exit 1
35+
fi
36+
37+
echo "RESULT from taking backup: ${RESULT}"
38+
39+
if [[ -n $RESULT && "$RESULT" == "postgresclusters/backup-cluster backup initiated" ]]; then
40+
exit 0
41+
fi
42+
43+
exit 1

testing/kuttl/e2e/backup/12--backup-with-overwrite.yaml

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
apiVersion: postgres-operator.crunchydata.com/v1beta1
3+
kind: PostgresCluster
4+
metadata:
5+
name: restore-cluster
6+
spec:
7+
postgresVersion: 14
8+
instances:
9+
- name: instance1
10+
dataVolumeClaimSpec:
11+
accessModes: [ReadWriteOnce]
12+
resources: { requests: { storage: 1Gi } }
13+
backups:
14+
pgbackrest:
15+
repos:
16+
- name: repo2
17+
volume:
18+
volumeClaimSpec:
19+
accessModes: [ReadWriteOnce]
20+
resources: { requests: { storage: 1Gi } }
21+
restore:
22+
enabled: true
23+
repoName: repo2
24+
options:
25+
- --db-include=restore-cluster
26+
27+
---
28+
apiVersion: kuttl.dev/v1beta1
29+
kind: TestStep
30+
commands:
31+
- script: |
32+
pgbackrest_restore_annotation() {
33+
kubectl --namespace "${NAMESPACE}" get postgrescluster/restore-cluster \
34+
--output "jsonpath-as-json={.metadata.annotations['postgres-operator\.crunchydata\.com/pgbackrest-restore']}"
35+
}
36+
37+
kubectl --namespace "${NAMESPACE}" annotate postgrescluster/restore-cluster \
38+
postgres-operator.crunchydata.com/pgbackrest-restore="$(date)" --overwrite || exit
39+
40+
41+
PRIOR=$(pgbackrest_restore_annotation)
42+
# Running restore will update the annotation.
43+
echo yes | kubectl-pgo --namespace="${NAMESPACE}" restore restore-cluster --options="--db-include=restore-cluster" --repoName="repo2" --force-conflicts
44+
CURRENT=$(pgbackrest_restore_annotation)
45+
46+
if [ "${CURRENT}" != "${PRIOR}" ]; then
47+
exit 0
48+
fi
49+
50+
printf 'Expected annotation to change, got PRIOR %q CURRENT %q' "${PRIOR}" "${CURRENT}"
51+
echo "RESULT from taking restore: ${RESULT}"
52+
53+
exit 1

0 commit comments

Comments
 (0)