finish PR1544

This commit is contained in:
Felix Kunde 2022-03-30 15:48:56 +02:00
parent cc10c3ea27
commit d78ccea3a8
8 changed files with 44 additions and 24 deletions

View File

@ -464,6 +464,13 @@ spec:
type: string type: string
standby_port: standby_port:
type: string type: string
oneOf:
- required:
- s3_wal_path
- required:
- gs_wal_path
- required:
- standby_host
streams: streams:
type: array type: array
nullable: true nullable: true

View File

@ -1088,11 +1088,15 @@ data:
### Standby clusters ### Standby clusters
The setup for [standby clusters](user.md#setting-up-a-standby-cluster) is very The setup for [standby clusters](user.md#setting-up-a-standby-cluster) is very
similar to cloning. At the moment, the operator only allows for streaming from similar to cloning. They can stream from a WAL archive (S3, GCS). Like with
the S3 WAL archive of the master specified in the manifest. Like with cloning, cloning, if you are using [additional environment variables](#custom-pod-environment-variables)
if you are using [additional environment variables](#custom-pod-environment-variables) to access your backup location you have to copy those variables and prepend
to access your backup location you have to copy those variables and prepend the the `STANDBY_` prefix for Spilo to find the backups and WAL files to stream.
`STANDBY_` prefix for Spilo to find the backups and WAL files to stream.
Alternatively, standby clusters can also stream from a remote primary cluster.
You have to specify the host address. Port is optional and defaults to 5432.
Note, that only one of the options (`s3_wal_path`, `gs_wal_path`,
`standby_host`) can be present under the `standby` top-level key.
## Logical backups ## Logical backups

View File

@ -395,24 +395,22 @@ under the `clone` top-level key and do not affect the already running cluster.
## Standby cluster ## Standby cluster
On startup, an existing `standby` top-level key creates a standby Postgres On startup, an existing `standby` top-level key creates a standby Postgres
cluster streaming from a remote location. Either from a S3 or GCS WAL cluster streaming from a remote location - either from a S3 or GCS WAL
archive or a remote primary. When both of them are set, `standby_host` archive or a remote primary. Only one of options is allowed and required
takes precedence. if the `standby` key is present.
* **s3_wal_path** * **s3_wal_path**
the url to S3 bucket containing the WAL archive of the remote primary. the url to S3 bucket containing the WAL archive of the remote primary.
Required when the `standby` section is present even when `standby_host` is set.
* **gs_wal_path** * **gs_wal_path**
the url to GS bucket containing the WAL archive of the remote primary. the url to GS bucket containing the WAL archive of the remote primary.
Optional, but `s3_wal_path` or `gs_wal_path` is required.
* **standby_host** * **standby_host**
hostname or IP address of the primary to stream from. hostname or IP address of the primary to stream from.
When set, `s3_wal_path` is ignored.
* **standby_port** * **standby_port**
TCP port on which the primary is listening for connections. TCP port on which the primary is listening for connections. Patroni will
use `"5432"` if not set.
## Volume properties ## Volume properties

View File

@ -462,6 +462,13 @@ spec:
type: string type: string
standby_port: standby_port:
type: string type: string
oneOf:
- required:
- s3_wal_path
- required:
- gs_wal_path
- required:
- standby_host
streams: streams:
type: array type: array
nullable: true nullable: true

View File

@ -12,6 +12,6 @@ spec:
version: "14" version: "14"
# Make this a standby cluster and provide either the s3 bucket path of source cluster or the remote primary host for continuous streaming. # Make this a standby cluster and provide either the s3 bucket path of source cluster or the remote primary host for continuous streaming.
standby: standby:
s3_wal_path: "s3://path/to/bucket/containing/wal/of/source/cluster/" s3_wal_path: " s3://mybucket/spilo/acid-minimal-cluster/abcd1234-2a4b-4b2a-8c9c-c1234defg567/wal/14/"
# standby_host: "" # standby_host: "acid-minimal-cluster.default"
# standby_port: "" # standby_port: "5432"

View File

@ -721,6 +721,11 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
Type: "string", Type: "string",
}, },
}, },
OneOf: []apiextv1.JSONSchemaProps{
apiextv1.JSONSchemaProps{Required: []string{"s3_wal_path"}},
apiextv1.JSONSchemaProps{Required: []string{"gs_wal_path"}},
apiextv1.JSONSchemaProps{Required: []string{"standby_host"}},
},
}, },
"streams": { "streams": {
Type: "array", Type: "array",

View File

@ -172,8 +172,8 @@ type Patroni struct {
// StandbyDescription contains remote primary config or s3 wal path // StandbyDescription contains remote primary config or s3 wal path
type StandbyDescription struct { type StandbyDescription struct {
S3WalPath string `json:"s3_wal_path,omitempty"` S3WalPath string `json:"s3_wal_path,omitempty"`
GSWalPath string `json:"gs_wal_path,omitempty"` GSWalPath string `json:"gs_wal_path,omitempty"`
StandbyHost string `json:"standby_host,omitempty"` StandbyHost string `json:"standby_host,omitempty"`
StandbyPort string `json:"standby_port,omitempty"` StandbyPort string `json:"standby_port,omitempty"`
} }

View File

@ -762,7 +762,12 @@ func (c *Cluster) generatePodTemplate(
} }
// generatePodEnvVars generates environment variables for the Spilo Pod // generatePodEnvVars generates environment variables for the Spilo Pod
func (c *Cluster) generateSpiloPodEnvVars(uid types.UID, spiloConfiguration string, cloneDescription *acidv1.CloneDescription, standbyDescription *acidv1.StandbyDescription, customPodEnvVarsList []v1.EnvVar) []v1.EnvVar { func (c *Cluster) generateSpiloPodEnvVars(
uid types.UID,
spiloConfiguration string,
cloneDescription *acidv1.CloneDescription,
standbyDescription *acidv1.StandbyDescription,
customPodEnvVarsList []v1.EnvVar) []v1.EnvVar {
envVars := []v1.EnvVar{ envVars := []v1.EnvVar{
{ {
Name: "SCOPE", Name: "SCOPE",
@ -1111,12 +1116,6 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
sort.Slice(customPodEnvVarsList, sort.Slice(customPodEnvVarsList,
func(i, j int) bool { return customPodEnvVarsList[i].Name < customPodEnvVarsList[j].Name }) func(i, j int) bool { return customPodEnvVarsList[i].Name < customPodEnvVarsList[j].Name })
if spec.StandbyCluster != nil {
if spec.StandbyCluster.S3WalPath == "" && spec.StandbyCluster.GSWalPath == "" && spec.StandbyCluster.StandbyHost == "" {
return nil, fmt.Errorf("s3_wal_path, gs_wal_path and standby_host are empty for standby cluster")
}
}
// backward compatible check for InitContainers // backward compatible check for InitContainers
if spec.InitContainersOld != nil { if spec.InitContainersOld != nil {
msg := "manifest parameter init_containers is deprecated." msg := "manifest parameter init_containers is deprecated."