@@ -23,13 +23,19 @@ import (
23
23
"strings"
24
24
25
25
"github.com/pkg/errors"
26
+
27
+ "github.com/crunchydata/postgres-operator/pkg/apis/postgres-operator.crunchydata.com/v1beta1"
26
28
)
27
29
28
30
const (
29
31
// errMsgConfigHashMismatch is the error message displayed when a configuration hash mismatch
30
32
// is detected while attempting stanza creation
31
33
errMsgConfigHashMismatch = "postgres operator error: pgBackRest config hash mismatch"
32
34
35
+ // errMsgStaleReposWithVolumesConfig is the error message displayed when a volume-backed repo has been
36
+ // configured, but the configuration has not yet propagated into the container.
37
+ errMsgStaleReposWithVolumesConfig = "postgres operator error: pgBackRest stale volume-backed repo configuration"
38
+
33
39
// errMsgBackupDbMismatch is the error message returned from pgBackRest when PG versions
34
40
// or PG system identifiers do not match between the PG instance and the existing stanza
35
41
errMsgBackupDbMismatch = "backup and archive info files exist but do not match the database"
@@ -51,7 +57,7 @@ type Executor func(
51
57
// from running (with a config mismatch indicating that the pgBackRest configuration as stored in
52
58
// the cluster's pgBackRest ConfigMap has not yet propagated to the Pod).
53
59
func (exec Executor ) StanzaCreateOrUpgrade (ctx context.Context , configHash string ,
54
- upgrade bool ) (bool , error ) {
60
+ upgrade bool , postgresCluster * v1beta1. PostgresCluster ) (bool , error ) {
55
61
56
62
var stdout , stderr bytes.Buffer
57
63
@@ -60,22 +66,46 @@ func (exec Executor) StanzaCreateOrUpgrade(ctx context.Context, configHash strin
60
66
stanzaCmd = "upgrade"
61
67
}
62
68
69
+ var reposWithVolumes []v1beta1.PGBackRestRepo
70
+ for _ , repo := range postgresCluster .Spec .Backups .PGBackRest .Repos {
71
+ if repo .Volume != nil {
72
+ reposWithVolumes = append (reposWithVolumes , repo )
73
+ }
74
+ }
75
+
76
+ grep := "grep %s-path /etc/pgbackrest/conf.d/pgbackrest_instance.conf"
77
+
78
+ var checkRepoCmd string
79
+ if len (reposWithVolumes ) > 0 {
80
+ repo := reposWithVolumes [0 ]
81
+ checkRepoCmd = checkRepoCmd + fmt .Sprintf (grep , repo .Name )
82
+
83
+ reposWithVolumes = reposWithVolumes [1 :]
84
+ for _ , repo := range reposWithVolumes {
85
+ checkRepoCmd = checkRepoCmd + fmt .Sprintf (" && " + grep , repo .Name )
86
+ }
87
+ }
88
+
63
89
// this is the script that is run to create a stanza. First it checks the
64
90
// "config-hash" file to ensure all configuration changes (e.g. from ConfigMaps) have
65
91
// propagated to the container, and if not, it prints an error and returns with exit code 1).
92
+ // Next, it checks that any volume-backed repo added to the config has propagated into
93
+ // the container, and if not, prints an error and exits with code 1.
66
94
// Otherwise, it runs the pgbackrest command, which will either be "stanza-create" or
67
95
// "stanza-upgrade", depending on the value of the boolean "upgrade" parameter.
68
96
const script = `
69
- declare -r hash="$1" stanza="$2" message ="$3" cmd ="$4"
97
+ declare -r hash="$1" stanza="$2" hash_msg ="$3" vol_msg ="$4" cmd="$5" check_repo_cmd="$6 "
70
98
if [[ "$(< /etc/pgbackrest/conf.d/config-hash)" != "${hash}" ]]; then
71
- printf >&2 "%s" "${message}"; exit 1;
99
+ printf >&2 "%s" "${hash_msg}"; exit 1;
100
+ elif ! bash -c "${check_repo_cmd}"; then
101
+ printf >&2 "%s" "${vol_msg}"; exit 1;
72
102
else
73
103
pgbackrest "${cmd}" --stanza="${stanza}"
74
104
fi
75
105
`
76
106
if err := exec (ctx , nil , & stdout , & stderr , "bash" , "-ceu" , "--" ,
77
- script , "-" , configHash , DefaultStanzaName , errMsgConfigHashMismatch ,
78
- fmt .Sprintf ("stanza-%s" , stanzaCmd )); err != nil {
107
+ script , "-" , configHash , DefaultStanzaName , errMsgConfigHashMismatch , errMsgStaleReposWithVolumesConfig ,
108
+ fmt .Sprintf ("stanza-%s" , stanzaCmd ), checkRepoCmd ); err != nil {
79
109
80
110
errReturn := stderr .String ()
81
111
86
116
return true , nil
87
117
}
88
118
119
+ // if the configuration for volume-backed repositories is stale, return true and don't return an error since this
120
+ // is expected while waiting for config changes in ConfigMaps to make it to the container
121
+ if errReturn == errMsgStaleReposWithVolumesConfig {
122
+ return true , nil
123
+ }
124
+
89
125
// if the err returned from pgbackrest command is about a version mismatch
90
126
// then we should run upgrade rather than create
91
127
if strings .Contains (errReturn , errMsgBackupDbMismatch ) {
92
- return exec .StanzaCreateOrUpgrade (ctx , configHash , true )
128
+ return exec .StanzaCreateOrUpgrade (ctx , configHash , true , postgresCluster )
93
129
}
94
130
95
131
// if none of the above errors, return the err
0 commit comments