mirror of
https://github.com/cloudnative-pg/plugin-barman-cloud.git
synced 2026-01-11 21:23:12 +01:00
Merge 74535f84a3 into 529737ffa4
This commit is contained in:
commit
ea381c13b0
2
Makefile
2
Makefile
@ -80,7 +80,7 @@ lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
|
||||
|
||||
.PHONY: build
|
||||
build: manifests generate fmt vet ## Build manager binary.
|
||||
go build -o bin/manager cmd/main.go
|
||||
go build -o bin/manager cmd/manager/main.go
|
||||
|
||||
.PHONY: run
|
||||
run: manifests generate fmt vet ## Run a controller from your host.
|
||||
|
||||
@ -22,6 +22,35 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ProbeConfig holds configuration for probe timing and thresholds
|
||||
// This is a subset of the corev1.Probe type, with only the fields that we want to expose as configuration.
|
||||
type ProbeConfig struct {
|
||||
// InitialDelaySeconds is the number of seconds after the container has started before startup probes are initiated.
|
||||
// +kubebuilder:default:=0
|
||||
// +optional
|
||||
InitialDelaySeconds int32 `json:"initialDelaySeconds,omitempty"`
|
||||
|
||||
// TimeoutSeconds is the number of seconds after which the probe times out.
|
||||
// +kubebuilder:default:=10
|
||||
// +optional
|
||||
TimeoutSeconds int32 `json:"timeoutSeconds,omitempty"`
|
||||
|
||||
// PeriodSeconds is how often (in seconds) to perform the probe.
|
||||
// +kubebuilder:default:=10
|
||||
// +optional
|
||||
PeriodSeconds int32 `json:"periodSeconds,omitempty"`
|
||||
|
||||
// SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
|
||||
// +kubebuilder:default:=1
|
||||
// +optional
|
||||
SuccessThreshold int32 `json:"successThreshold,omitempty"`
|
||||
|
||||
// FailureThreshold is the minimum consecutive failures for the probe to be considered failed.
|
||||
// +kubebuilder:default:=10
|
||||
// +optional
|
||||
FailureThreshold int32 `json:"failureThreshold,omitempty"`
|
||||
}
|
||||
|
||||
// InstanceSidecarConfiguration defines the configuration for the sidecar that runs in the instance pods.
|
||||
type InstanceSidecarConfiguration struct {
|
||||
// The environment to be explicitly passed to the sidecar
|
||||
@ -38,6 +67,17 @@ type InstanceSidecarConfiguration struct {
|
||||
// +optional
|
||||
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
|
||||
|
||||
// StartupProbe defines the configuration for the startup probe of the sidecar container.
|
||||
// +optional
|
||||
StartupProbe *ProbeConfig `json:"startupProbe,omitempty"`
|
||||
|
||||
// LivenessProbe defines the configuration for the liveness probe of the sidecar container.
|
||||
// +optional
|
||||
LivenessProbe *ProbeConfig `json:"livenessProbe,omitempty"`
|
||||
|
||||
// ReadinessProbe defines the configuration for the readiness probe of the sidecar container.
|
||||
// +optional
|
||||
ReadinessProbe *ProbeConfig `json:"readinessProbe,omitempty"`
|
||||
// AdditionalContainerArgs is an optional list of command-line arguments
|
||||
// to be passed to the sidecar container when it starts.
|
||||
// The provided arguments are appended to the container’s default arguments.
|
||||
|
||||
@ -36,6 +36,21 @@ func (in *InstanceSidecarConfiguration) DeepCopyInto(out *InstanceSidecarConfigu
|
||||
}
|
||||
}
|
||||
in.Resources.DeepCopyInto(&out.Resources)
|
||||
if in.StartupProbe != nil {
|
||||
in, out := &in.StartupProbe, &out.StartupProbe
|
||||
*out = new(ProbeConfig)
|
||||
**out = **in
|
||||
}
|
||||
if in.LivenessProbe != nil {
|
||||
in, out := &in.LivenessProbe, &out.LivenessProbe
|
||||
*out = new(ProbeConfig)
|
||||
**out = **in
|
||||
}
|
||||
if in.ReadinessProbe != nil {
|
||||
in, out := &in.ReadinessProbe, &out.ReadinessProbe
|
||||
*out = new(ProbeConfig)
|
||||
**out = **in
|
||||
}
|
||||
if in.AdditionalContainerArgs != nil {
|
||||
in, out := &in.AdditionalContainerArgs, &out.AdditionalContainerArgs
|
||||
*out = make([]string, len(*in))
|
||||
@ -151,6 +166,21 @@ func (in *ObjectStoreStatus) DeepCopy() *ObjectStoreStatus {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ProbeConfig) DeepCopyInto(out *ProbeConfig) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProbeConfig.
|
||||
func (in *ProbeConfig) DeepCopy() *ProbeConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ProbeConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RecoveryWindow) DeepCopyInto(out *RecoveryWindow) {
|
||||
*out = *in
|
||||
|
||||
@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.18.0
|
||||
controller-gen.kubebuilder.io/version: v0.16.1
|
||||
name: objectstores.barmancloud.cnpg.io
|
||||
spec:
|
||||
group: barmancloud.cnpg.io
|
||||
@ -562,6 +562,78 @@ spec:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
livenessProbe:
|
||||
description: LivenessProbe defines the configuration for the liveness
|
||||
probe of the sidecar container.
|
||||
properties:
|
||||
failureThreshold:
|
||||
default: 10
|
||||
description: FailureThreshold is the minimum consecutive failures
|
||||
for the probe to be considered failed.
|
||||
format: int32
|
||||
type: integer
|
||||
initialDelaySeconds:
|
||||
default: 0
|
||||
description: InitialDelaySeconds is the number of seconds
|
||||
after the container has started before startup probes are
|
||||
initiated.
|
||||
format: int32
|
||||
type: integer
|
||||
periodSeconds:
|
||||
default: 10
|
||||
description: PeriodSeconds is how often (in seconds) to perform
|
||||
the probe.
|
||||
format: int32
|
||||
type: integer
|
||||
successThreshold:
|
||||
default: 1
|
||||
description: SuccessThreshold is the minimum consecutive successes
|
||||
for the probe to be considered successful.
|
||||
format: int32
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
default: 10
|
||||
description: TimeoutSeconds is the number of seconds after
|
||||
which the probe times out.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
readinessProbe:
|
||||
description: ReadinessProbe defines the configuration for the
|
||||
readiness probe of the sidecar container.
|
||||
properties:
|
||||
failureThreshold:
|
||||
default: 10
|
||||
description: FailureThreshold is the minimum consecutive failures
|
||||
for the probe to be considered failed.
|
||||
format: int32
|
||||
type: integer
|
||||
initialDelaySeconds:
|
||||
default: 0
|
||||
description: InitialDelaySeconds is the number of seconds
|
||||
after the container has started before startup probes are
|
||||
initiated.
|
||||
format: int32
|
||||
type: integer
|
||||
periodSeconds:
|
||||
default: 10
|
||||
description: PeriodSeconds is how often (in seconds) to perform
|
||||
the probe.
|
||||
format: int32
|
||||
type: integer
|
||||
successThreshold:
|
||||
default: 1
|
||||
description: SuccessThreshold is the minimum consecutive successes
|
||||
for the probe to be considered successful.
|
||||
format: int32
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
default: 10
|
||||
description: TimeoutSeconds is the number of seconds after
|
||||
which the probe times out.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
logLevel:
|
||||
default: info
|
||||
description: 'The log level for PostgreSQL instances. Valid values
|
||||
@ -639,6 +711,42 @@ spec:
|
||||
The retentionCheckInterval defines the frequency at which the
|
||||
system checks and enforces retention policies.
|
||||
type: integer
|
||||
startupProbe:
|
||||
description: StartupProbe defines the configuration for the startup
|
||||
probe of the sidecar container.
|
||||
properties:
|
||||
failureThreshold:
|
||||
default: 10
|
||||
description: FailureThreshold is the minimum consecutive failures
|
||||
for the probe to be considered failed.
|
||||
format: int32
|
||||
type: integer
|
||||
initialDelaySeconds:
|
||||
default: 0
|
||||
description: InitialDelaySeconds is the number of seconds
|
||||
after the container has started before startup probes are
|
||||
initiated.
|
||||
format: int32
|
||||
type: integer
|
||||
periodSeconds:
|
||||
default: 10
|
||||
description: PeriodSeconds is how often (in seconds) to perform
|
||||
the probe.
|
||||
format: int32
|
||||
type: integer
|
||||
successThreshold:
|
||||
default: 1
|
||||
description: SuccessThreshold is the minimum consecutive successes
|
||||
for the probe to be considered successful.
|
||||
format: int32
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
default: 10
|
||||
description: TimeoutSeconds is the number of seconds after
|
||||
which the probe times out.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
type: object
|
||||
retentionPolicy:
|
||||
description: |-
|
||||
|
||||
@ -14,6 +14,26 @@ spec:
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "500m"
|
||||
additionalContainerArgs:
|
||||
- --log-level=debug
|
||||
startupProbe:
|
||||
initialDelaySeconds: 1
|
||||
timeoutSeconds: 10
|
||||
periodSeconds: 1
|
||||
failureThreshold: 10
|
||||
successThreshold: 1
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 30
|
||||
timeoutSeconds: 5
|
||||
periodSeconds: 10
|
||||
failureThreshold: 3
|
||||
successThreshold: 1
|
||||
readinessProbe:
|
||||
initialDelaySeconds: 5
|
||||
timeoutSeconds: 5
|
||||
periodSeconds: 5
|
||||
failureThreshold: 3
|
||||
successThreshold: 1
|
||||
configuration:
|
||||
endpointCA:
|
||||
name: minio-server-tls
|
||||
|
||||
@ -126,10 +126,28 @@ func (impl LifecycleImplementation) reconcileJob(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
startupProbe, err := impl.collectSidecarStartupProbeForRecoveryJob(ctx, pluginConfiguration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
livenessProbe, err := impl.collectSidecarLivenessProbeForRecoveryJob(ctx, pluginConfiguration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
readinessProbe, err := impl.collectSidecarReadinessProbeForRecoveryJob(ctx, pluginConfiguration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return reconcileJob(ctx, cluster, request, sidecarConfiguration{
|
||||
env: env,
|
||||
certificates: certificates,
|
||||
resources: resources,
|
||||
env: env,
|
||||
certificates: certificates,
|
||||
resources: resources,
|
||||
startupProbe: startupProbe,
|
||||
livenessProbe: livenessProbe,
|
||||
readinessProbe: readinessProbe,
|
||||
})
|
||||
}
|
||||
|
||||
@ -138,6 +156,9 @@ type sidecarConfiguration struct {
|
||||
certificates []corev1.VolumeProjection
|
||||
resources corev1.ResourceRequirements
|
||||
additionalArgs []string
|
||||
startupProbe *barmancloudv1.ProbeConfig
|
||||
livenessProbe *barmancloudv1.ProbeConfig
|
||||
readinessProbe *barmancloudv1.ProbeConfig
|
||||
}
|
||||
|
||||
func reconcileJob(
|
||||
@ -224,10 +245,28 @@ func (impl LifecycleImplementation) reconcilePod(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
startupProbe, err := impl.collectSidecarStartupProbeForInstancePod(ctx, pluginConfiguration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
livenessProbe, err := impl.collectSidecarLivenessProbeForInstancePod(ctx, pluginConfiguration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
readinessProbe, err := impl.collectSidecarReadinessProbeForInstancePod(ctx, pluginConfiguration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return reconcileInstancePod(ctx, cluster, request, pluginConfiguration, sidecarConfiguration{
|
||||
env: env,
|
||||
certificates: certificates,
|
||||
resources: resources,
|
||||
startupProbe: startupProbe,
|
||||
livenessProbe: livenessProbe,
|
||||
readinessProbe: readinessProbe,
|
||||
additionalArgs: additionalArgs,
|
||||
})
|
||||
}
|
||||
@ -362,8 +401,6 @@ func reconcilePodSpec(
|
||||
envs = append(envs, config.env...)
|
||||
|
||||
baseProbe := &corev1.Probe{
|
||||
FailureThreshold: 10,
|
||||
TimeoutSeconds: 10,
|
||||
ProbeHandler: corev1.ProbeHandler{
|
||||
Exec: &corev1.ExecAction{
|
||||
Command: []string{"/manager", "healthcheck", "unix"},
|
||||
@ -371,11 +408,37 @@ func reconcilePodSpec(
|
||||
},
|
||||
}
|
||||
|
||||
startupProbe := createProbe(baseProbe, config.startupProbe, &barmancloudv1.ProbeConfig{
|
||||
FailureThreshold: 10,
|
||||
TimeoutSeconds: 10,
|
||||
InitialDelaySeconds: 0,
|
||||
SuccessThreshold: 1,
|
||||
PeriodSeconds: 10,
|
||||
})
|
||||
|
||||
livenessProbe := createProbe(baseProbe, config.livenessProbe, &barmancloudv1.ProbeConfig{
|
||||
FailureThreshold: 3,
|
||||
TimeoutSeconds: 10,
|
||||
InitialDelaySeconds: 0,
|
||||
SuccessThreshold: 1,
|
||||
PeriodSeconds: 10,
|
||||
})
|
||||
|
||||
readinessProbe := createProbe(baseProbe, config.readinessProbe, &barmancloudv1.ProbeConfig{
|
||||
FailureThreshold: 3,
|
||||
TimeoutSeconds: 10,
|
||||
InitialDelaySeconds: 0,
|
||||
SuccessThreshold: 1,
|
||||
PeriodSeconds: 10,
|
||||
})
|
||||
|
||||
// fixed values
|
||||
sidecarTemplate.Name = "plugin-barman-cloud"
|
||||
sidecarTemplate.Image = viper.GetString("sidecar-image")
|
||||
sidecarTemplate.ImagePullPolicy = cluster.Spec.ImagePullPolicy
|
||||
sidecarTemplate.StartupProbe = baseProbe.DeepCopy()
|
||||
sidecarTemplate.StartupProbe = startupProbe
|
||||
sidecarTemplate.LivenessProbe = livenessProbe
|
||||
sidecarTemplate.ReadinessProbe = readinessProbe
|
||||
sidecarTemplate.SecurityContext = &corev1.SecurityContext{
|
||||
AllowPrivilegeEscalation: ptr.To(false),
|
||||
RunAsNonRoot: ptr.To(true),
|
||||
@ -600,3 +663,33 @@ func getCNPGJobRole(job *batchv1.Job) string {
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// createProbe creates a probe using the base probe's handler and applies configuration or default values
|
||||
func createProbe(baseProbe *corev1.Probe, config *barmancloudv1.ProbeConfig, defaults *barmancloudv1.ProbeConfig) *corev1.Probe {
|
||||
probe := baseProbe.DeepCopy()
|
||||
probe.FailureThreshold = defaults.FailureThreshold
|
||||
probe.TimeoutSeconds = defaults.TimeoutSeconds
|
||||
probe.InitialDelaySeconds = defaults.InitialDelaySeconds
|
||||
probe.SuccessThreshold = defaults.SuccessThreshold
|
||||
probe.PeriodSeconds = defaults.PeriodSeconds
|
||||
|
||||
if config != nil {
|
||||
if config.InitialDelaySeconds != 0 {
|
||||
probe.InitialDelaySeconds = config.InitialDelaySeconds
|
||||
}
|
||||
if config.TimeoutSeconds != 0 {
|
||||
probe.TimeoutSeconds = config.TimeoutSeconds
|
||||
}
|
||||
if config.PeriodSeconds != 0 {
|
||||
probe.PeriodSeconds = config.PeriodSeconds
|
||||
}
|
||||
if config.SuccessThreshold != 0 {
|
||||
probe.SuccessThreshold = config.SuccessThreshold
|
||||
}
|
||||
if config.FailureThreshold != 0 {
|
||||
probe.FailureThreshold = config.FailureThreshold
|
||||
}
|
||||
}
|
||||
|
||||
return probe
|
||||
}
|
||||
|
||||
123
internal/cnpgi/operator/lifecycle_probes.go
Normal file
123
internal/cnpgi/operator/lifecycle_probes.go
Normal file
@ -0,0 +1,123 @@
|
||||
package operator
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
||||
)
|
||||
|
||||
// probeAccessor is a function type that extracts a specific probe configuration from an ObjectStore
|
||||
type probeAccessor func(*barmancloudv1.ObjectStore) *barmancloudv1.ProbeConfig
|
||||
|
||||
// collectSidecarProbeForRecoveryJob is a generic function to collect probe configurations for recovery jobs
|
||||
func (impl LifecycleImplementation) collectSidecarProbeForRecoveryJob(
|
||||
ctx context.Context,
|
||||
configuration *config.PluginConfiguration,
|
||||
accessor probeAccessor,
|
||||
) (*barmancloudv1.ProbeConfig, error) {
|
||||
if len(configuration.RecoveryBarmanObjectName) > 0 {
|
||||
var barmanObjectStore barmancloudv1.ObjectStore
|
||||
if err := impl.Client.Get(ctx, configuration.GetRecoveryBarmanObjectKey(), &barmanObjectStore); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return accessor(&barmanObjectStore), nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// collectSidecarProbeForInstancePod is a generic function to collect probe configurations for instance pods
|
||||
func (impl LifecycleImplementation) collectSidecarProbeForInstancePod(
|
||||
ctx context.Context,
|
||||
configuration *config.PluginConfiguration,
|
||||
accessor probeAccessor,
|
||||
probeType string,
|
||||
) (*barmancloudv1.ProbeConfig, error) {
|
||||
if len(configuration.BarmanObjectName) > 0 {
|
||||
// On a replica cluster that also archives, the designated primary
|
||||
// will use both the replica source object store and the object store
|
||||
// of the cluster.
|
||||
// In this case, we use the cluster object store for configuring
|
||||
// the probe of the sidecar container.
|
||||
|
||||
var barmanObjectStore barmancloudv1.ObjectStore
|
||||
if err := impl.Client.Get(ctx, configuration.GetBarmanObjectKey(), &barmanObjectStore); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return accessor(&barmanObjectStore), nil
|
||||
}
|
||||
|
||||
if len(configuration.RecoveryBarmanObjectName) > 0 {
|
||||
// On a replica cluster that doesn't archive, the designated primary
|
||||
// uses only the replica source object store.
|
||||
// In this case, we use the replica source object store for configuring
|
||||
// the probe of the sidecar container.
|
||||
var barmanObjectStore barmancloudv1.ObjectStore
|
||||
if err := impl.Client.Get(ctx, configuration.GetRecoveryBarmanObjectKey(), &barmanObjectStore); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return accessor(&barmanObjectStore), nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Specific probe collection methods that use the generic functions
|
||||
|
||||
func (impl LifecycleImplementation) collectSidecarStartupProbeForRecoveryJob(
|
||||
ctx context.Context,
|
||||
configuration *config.PluginConfiguration,
|
||||
) (*barmancloudv1.ProbeConfig, error) {
|
||||
return impl.collectSidecarProbeForRecoveryJob(ctx, configuration, func(store *barmancloudv1.ObjectStore) *barmancloudv1.ProbeConfig {
|
||||
return store.Spec.InstanceSidecarConfiguration.StartupProbe
|
||||
})
|
||||
}
|
||||
|
||||
func (impl LifecycleImplementation) collectSidecarStartupProbeForInstancePod(
|
||||
ctx context.Context,
|
||||
configuration *config.PluginConfiguration,
|
||||
) (*barmancloudv1.ProbeConfig, error) {
|
||||
return impl.collectSidecarProbeForInstancePod(ctx, configuration, func(store *barmancloudv1.ObjectStore) *barmancloudv1.ProbeConfig {
|
||||
return store.Spec.InstanceSidecarConfiguration.StartupProbe
|
||||
}, "startup")
|
||||
}
|
||||
|
||||
func (impl LifecycleImplementation) collectSidecarLivenessProbeForRecoveryJob(
|
||||
ctx context.Context,
|
||||
configuration *config.PluginConfiguration,
|
||||
) (*barmancloudv1.ProbeConfig, error) {
|
||||
return impl.collectSidecarProbeForRecoveryJob(ctx, configuration, func(store *barmancloudv1.ObjectStore) *barmancloudv1.ProbeConfig {
|
||||
return store.Spec.InstanceSidecarConfiguration.LivenessProbe
|
||||
})
|
||||
}
|
||||
|
||||
func (impl LifecycleImplementation) collectSidecarLivenessProbeForInstancePod(
|
||||
ctx context.Context,
|
||||
configuration *config.PluginConfiguration,
|
||||
) (*barmancloudv1.ProbeConfig, error) {
|
||||
return impl.collectSidecarProbeForInstancePod(ctx, configuration, func(store *barmancloudv1.ObjectStore) *barmancloudv1.ProbeConfig {
|
||||
return store.Spec.InstanceSidecarConfiguration.LivenessProbe
|
||||
}, "liveness")
|
||||
}
|
||||
|
||||
func (impl LifecycleImplementation) collectSidecarReadinessProbeForRecoveryJob(
|
||||
ctx context.Context,
|
||||
configuration *config.PluginConfiguration,
|
||||
) (*barmancloudv1.ProbeConfig, error) {
|
||||
return impl.collectSidecarProbeForRecoveryJob(ctx, configuration, func(store *barmancloudv1.ObjectStore) *barmancloudv1.ProbeConfig {
|
||||
return store.Spec.InstanceSidecarConfiguration.ReadinessProbe
|
||||
})
|
||||
}
|
||||
|
||||
func (impl LifecycleImplementation) collectSidecarReadinessProbeForInstancePod(
|
||||
ctx context.Context,
|
||||
configuration *config.PluginConfiguration,
|
||||
) (*barmancloudv1.ProbeConfig, error) {
|
||||
return impl.collectSidecarProbeForInstancePod(ctx, configuration, func(store *barmancloudv1.ObjectStore) *barmancloudv1.ProbeConfig {
|
||||
return store.Spec.InstanceSidecarConfiguration.ReadinessProbe
|
||||
}, "readiness")
|
||||
}
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
@ -196,6 +197,119 @@ var _ = Describe("LifecycleImplementation", func() {
|
||||
})
|
||||
|
||||
Describe("reconcileInstancePod", func() {
|
||||
It("returns a patch for a valid pod with probe configuration", func(ctx SpecContext) {
|
||||
// Configure sidecar with custom probe settings
|
||||
startupProbeConfig := &barmancloudv1.ProbeConfig{
|
||||
InitialDelaySeconds: 1,
|
||||
TimeoutSeconds: 15,
|
||||
PeriodSeconds: 2,
|
||||
FailureThreshold: 5,
|
||||
SuccessThreshold: 1,
|
||||
}
|
||||
|
||||
pod := &corev1.Pod{
|
||||
TypeMeta: podTypeMeta,
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-pod",
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: "postgres",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
podJSON, err := json.Marshal(pod)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
request := &lifecycle.OperatorLifecycleRequest{
|
||||
ObjectDefinition: podJSON,
|
||||
}
|
||||
|
||||
response, err := reconcileInstancePod(ctx, cluster, request, pluginConfiguration, sidecarConfiguration{
|
||||
startupProbe: startupProbeConfig,
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(response).NotTo(BeNil())
|
||||
Expect(response.JsonPatch).NotTo(BeEmpty())
|
||||
|
||||
// Verify the patch contains the expected probe configuration
|
||||
Expect(string(response.JsonPatch)).To(ContainSubstring("startupProbe"))
|
||||
Expect(string(response.JsonPatch)).To(ContainSubstring("\"initialDelaySeconds\":1"))
|
||||
Expect(string(response.JsonPatch)).To(ContainSubstring("\"timeoutSeconds\":15"))
|
||||
Expect(string(response.JsonPatch)).To(ContainSubstring("\"periodSeconds\":2"))
|
||||
Expect(string(response.JsonPatch)).To(ContainSubstring("\"failureThreshold\":5"))
|
||||
Expect(string(response.JsonPatch)).To(ContainSubstring("\"successThreshold\":1"))
|
||||
})
|
||||
|
||||
It("decouples probe configurations - startupProbe doesn't affect other probes", func(ctx SpecContext) {
|
||||
// Configure only startupProbe with custom settings
|
||||
startupProbeConfig := &barmancloudv1.ProbeConfig{
|
||||
InitialDelaySeconds: 5,
|
||||
TimeoutSeconds: 20,
|
||||
PeriodSeconds: 3,
|
||||
FailureThreshold: 8,
|
||||
SuccessThreshold: 2,
|
||||
}
|
||||
|
||||
pod := &corev1.Pod{
|
||||
TypeMeta: podTypeMeta,
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-pod",
|
||||
},
|
||||
Spec: corev1.PodSpec{
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: "postgres",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
podJSON, err := json.Marshal(pod)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
request := &lifecycle.OperatorLifecycleRequest{
|
||||
ObjectDefinition: podJSON,
|
||||
}
|
||||
|
||||
response, err := reconcileInstancePod(ctx, cluster, request, pluginConfiguration, sidecarConfiguration{
|
||||
startupProbe: startupProbeConfig,
|
||||
// livenessProbe and readinessProbe are nil - should use defaults
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(response).NotTo(BeNil())
|
||||
Expect(response.JsonPatch).NotTo(BeEmpty())
|
||||
|
||||
patchStr := string(response.JsonPatch)
|
||||
|
||||
// Verify startupProbe has custom settings
|
||||
Expect(patchStr).To(ContainSubstring("startupProbe"))
|
||||
Expect(patchStr).To(ContainSubstring("\"initialDelaySeconds\":5"))
|
||||
Expect(patchStr).To(ContainSubstring("\"timeoutSeconds\":20"))
|
||||
Expect(patchStr).To(ContainSubstring("\"periodSeconds\":3"))
|
||||
Expect(patchStr).To(ContainSubstring("\"failureThreshold\":8"))
|
||||
Expect(patchStr).To(ContainSubstring("\"successThreshold\":2"))
|
||||
|
||||
// Verify livenessProbe has default settings (not affected by startupProbe)
|
||||
Expect(patchStr).To(ContainSubstring("livenessProbe"))
|
||||
Expect(patchStr).To(ContainSubstring("\"failureThreshold\":3")) // default for liveness
|
||||
Expect(patchStr).To(ContainSubstring("\"timeoutSeconds\":10")) // default for liveness
|
||||
// initialDelaySeconds: 0 is omitted from JSON when it's the zero value
|
||||
|
||||
// Verify readinessProbe has default settings (not affected by startupProbe)
|
||||
Expect(patchStr).To(ContainSubstring("readinessProbe"))
|
||||
Expect(patchStr).To(ContainSubstring("\"failureThreshold\":3")) // default for readiness
|
||||
Expect(patchStr).To(ContainSubstring("\"timeoutSeconds\":10")) // default for readiness
|
||||
// initialDelaySeconds: 0 is omitted from JSON when it's the zero value
|
||||
|
||||
// Verify that livenessProbe and readinessProbe don't have startupProbe values
|
||||
Expect(patchStr).NotTo(MatchRegexp(`"livenessProbe"[^}]*"initialDelaySeconds":5`))
|
||||
Expect(patchStr).NotTo(MatchRegexp(`"readinessProbe"[^}]*"initialDelaySeconds":5`))
|
||||
})
|
||||
|
||||
It("returns a patch for a valid pod", func(ctx SpecContext) {
|
||||
pod := &corev1.Pod{
|
||||
TypeMeta: podTypeMeta,
|
||||
|
||||
108
manifest.yaml
108
manifest.yaml
@ -561,6 +561,78 @@ spec:
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
livenessProbe:
|
||||
description: LivenessProbe defines the configuration for the liveness
|
||||
probe of the sidecar container.
|
||||
properties:
|
||||
failureThreshold:
|
||||
default: 10
|
||||
description: FailureThreshold is the minimum consecutive failures
|
||||
for the probe to be considered failed.
|
||||
format: int32
|
||||
type: integer
|
||||
initialDelaySeconds:
|
||||
default: 0
|
||||
description: InitialDelaySeconds is the number of seconds
|
||||
after the container has started before startup probes are
|
||||
initiated.
|
||||
format: int32
|
||||
type: integer
|
||||
periodSeconds:
|
||||
default: 10
|
||||
description: PeriodSeconds is how often (in seconds) to perform
|
||||
the probe.
|
||||
format: int32
|
||||
type: integer
|
||||
successThreshold:
|
||||
default: 1
|
||||
description: SuccessThreshold is the minimum consecutive successes
|
||||
for the probe to be considered successful.
|
||||
format: int32
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
default: 10
|
||||
description: TimeoutSeconds is the number of seconds after
|
||||
which the probe times out.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
readinessProbe:
|
||||
description: ReadinessProbe defines the configuration for the
|
||||
readiness probe of the sidecar container.
|
||||
properties:
|
||||
failureThreshold:
|
||||
default: 10
|
||||
description: FailureThreshold is the minimum consecutive failures
|
||||
for the probe to be considered failed.
|
||||
format: int32
|
||||
type: integer
|
||||
initialDelaySeconds:
|
||||
default: 0
|
||||
description: InitialDelaySeconds is the number of seconds
|
||||
after the container has started before startup probes are
|
||||
initiated.
|
||||
format: int32
|
||||
type: integer
|
||||
periodSeconds:
|
||||
default: 10
|
||||
description: PeriodSeconds is how often (in seconds) to perform
|
||||
the probe.
|
||||
format: int32
|
||||
type: integer
|
||||
successThreshold:
|
||||
default: 1
|
||||
description: SuccessThreshold is the minimum consecutive successes
|
||||
for the probe to be considered successful.
|
||||
format: int32
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
default: 10
|
||||
description: TimeoutSeconds is the number of seconds after
|
||||
which the probe times out.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
logLevel:
|
||||
default: info
|
||||
description: 'The log level for PostgreSQL instances. Valid values
|
||||
@ -638,6 +710,42 @@ spec:
|
||||
The retentionCheckInterval defines the frequency at which the
|
||||
system checks and enforces retention policies.
|
||||
type: integer
|
||||
startupProbe:
|
||||
description: StartupProbe defines the configuration for the startup
|
||||
probe of the sidecar container.
|
||||
properties:
|
||||
failureThreshold:
|
||||
default: 10
|
||||
description: FailureThreshold is the minimum consecutive failures
|
||||
for the probe to be considered failed.
|
||||
format: int32
|
||||
type: integer
|
||||
initialDelaySeconds:
|
||||
default: 0
|
||||
description: InitialDelaySeconds is the number of seconds
|
||||
after the container has started before startup probes are
|
||||
initiated.
|
||||
format: int32
|
||||
type: integer
|
||||
periodSeconds:
|
||||
default: 10
|
||||
description: PeriodSeconds is how often (in seconds) to perform
|
||||
the probe.
|
||||
format: int32
|
||||
type: integer
|
||||
successThreshold:
|
||||
default: 1
|
||||
description: SuccessThreshold is the minimum consecutive successes
|
||||
for the probe to be considered successful.
|
||||
format: int32
|
||||
type: integer
|
||||
timeoutSeconds:
|
||||
default: 10
|
||||
description: TimeoutSeconds is the number of seconds after
|
||||
which the probe times out.
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
type: object
|
||||
retentionPolicy:
|
||||
description: |-
|
||||
|
||||
Loading…
Reference in New Issue
Block a user