From 0501e185bab4969064c5b92977747be30bd38e95 Mon Sep 17 00:00:00 2001 From: Armando Ruocco Date: Wed, 24 Sep 2025 12:32:59 +0200 Subject: [PATCH] feat: introduce `logLevel` setting to control verbosity (#536) This commit adds a new `logLevel` field to the plugin configuration, allowing users to select the desired log verbosity for the instances (e.g. error, warning, info, debug, trace). Closes #514 Signed-off-by: Armando Ruocco Signed-off-by: Gabriele Bartolini Co-authored-by: Gabriele Bartolini --- .wordlist.txt | 1 + api/v1/objectstore_types.go | 7 +++ .../barmancloud.cnpg.io_objectstores.yaml | 16 ++++++ hack/examples/minio-store.yaml | 3 +- internal/cnpgi/operator/lifecycle.go | 27 +++++++++- internal/cnpgi/operator/lifecycle_test.go | 54 +++++++++++++++++++ manifest.yaml | 16 ++++++ web/docs/plugin-barman-cloud.v1.md | 1 + 8 files changed, 121 insertions(+), 4 deletions(-) diff --git a/.wordlist.txt b/.wordlist.txt index fd703f4..e872a38 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -13,6 +13,7 @@ DigitalOcean Docusaurus EDB EKS +Enum EnvVar GCP GKE diff --git a/api/v1/objectstore_types.go b/api/v1/objectstore_types.go index d9ceb52..5eeadf0 100644 --- a/api/v1/objectstore_types.go +++ b/api/v1/objectstore_types.go @@ -41,8 +41,15 @@ type InstanceSidecarConfiguration struct { // 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. + // +kubebuilder:validation:XValidation:rule="!self.exists(a, a.startsWith('--log-level'))",reason="FieldValueForbidden",message="do not set --log-level in additionalContainerArgs; use spec.instanceSidecarConfiguration.logLevel" // +optional AdditionalContainerArgs []string `json:"additionalContainerArgs,omitempty"` + + // The log level for PostgreSQL instances. Valid values are: `error`, `warning`, `info` (default), `debug`, `trace` + // +kubebuilder:default:=info + // +kubebuilder:validation:Enum:=error;warning;info;debug;trace + // +optional + LogLevel string `json:"logLevel,omitempty"` } // ObjectStoreSpec defines the desired state of ObjectStore. diff --git a/config/crd/bases/barmancloud.cnpg.io_objectstores.yaml b/config/crd/bases/barmancloud.cnpg.io_objectstores.yaml index 8c7f005..7d12b8c 100644 --- a/config/crd/bases/barmancloud.cnpg.io_objectstores.yaml +++ b/config/crd/bases/barmancloud.cnpg.io_objectstores.yaml @@ -399,6 +399,11 @@ spec: items: type: string type: array + x-kubernetes-validations: + - message: do not set --log-level in additionalContainerArgs; + use spec.instanceSidecarConfiguration.logLevel + reason: FieldValueForbidden + rule: '!self.exists(a, a.startsWith(''--log-level''))' env: description: The environment to be explicitly passed to the sidecar items: @@ -557,6 +562,17 @@ spec: - name type: object type: array + logLevel: + default: info + description: 'The log level for PostgreSQL instances. Valid values + are: `error`, `warning`, `info` (default), `debug`, `trace`' + enum: + - error + - warning + - info + - debug + - trace + type: string resources: description: Resources define cpu/memory requests and limits for the sidecar that runs in the instance pods. diff --git a/hack/examples/minio-store.yaml b/hack/examples/minio-store.yaml index 26ed965..cb9eb65 100644 --- a/hack/examples/minio-store.yaml +++ b/hack/examples/minio-store.yaml @@ -5,6 +5,7 @@ metadata: spec: retentionPolicy: "1m" instanceSidecarConfiguration: + logLevel: "debug" retentionPolicyIntervalSeconds: 1800 resources: requests: @@ -13,8 +14,6 @@ spec: limits: memory: "512Mi" cpu: "500m" - additionalContainerArgs: - - --log-level=debug configuration: endpointCA: name: minio-server-tls diff --git a/internal/cnpgi/operator/lifecycle.go b/internal/cnpgi/operator/lifecycle.go index d7eba1f..a777aaf 100644 --- a/internal/cnpgi/operator/lifecycle.go +++ b/internal/cnpgi/operator/lifecycle.go @@ -236,6 +236,19 @@ func (impl LifecycleImplementation) collectAdditionalInstanceArgs( ctx context.Context, pluginConfiguration *config.PluginConfiguration, ) ([]string, error) { + collectTypedAdditionalArgs := func(store *barmancloudv1.ObjectStore) []string { + if store == nil { + return nil + } + + var args []string + if len(store.Spec.InstanceSidecarConfiguration.LogLevel) > 0 { + args = append(args, fmt.Sprintf("--log-level=%s", store.Spec.InstanceSidecarConfiguration.LogLevel)) + } + + return args + } + // Prefer the cluster object store (backup/archive). If not set, fallback to the recovery object store. // If neither is configured, no additional args are provided. if len(pluginConfiguration.BarmanObjectName) > 0 { @@ -244,7 +257,12 @@ func (impl LifecycleImplementation) collectAdditionalInstanceArgs( return nil, fmt.Errorf("while getting barman object store %s: %w", pluginConfiguration.GetBarmanObjectKey().String(), err) } - return barmanObjectStore.Spec.InstanceSidecarConfiguration.AdditionalContainerArgs, nil + args := barmanObjectStore.Spec.InstanceSidecarConfiguration.AdditionalContainerArgs + args = append( + args, + collectTypedAdditionalArgs(&barmanObjectStore)..., + ) + return args, nil } if len(pluginConfiguration.RecoveryBarmanObjectName) > 0 { @@ -253,7 +271,12 @@ func (impl LifecycleImplementation) collectAdditionalInstanceArgs( return nil, fmt.Errorf("while getting recovery barman object store %s: %w", pluginConfiguration.GetRecoveryBarmanObjectKey().String(), err) } - return barmanObjectStore.Spec.InstanceSidecarConfiguration.AdditionalContainerArgs, nil + args := barmanObjectStore.Spec.InstanceSidecarConfiguration.AdditionalContainerArgs + args = append( + args, + collectTypedAdditionalArgs(&barmanObjectStore)..., + ) + return args, nil } return nil, nil diff --git a/internal/cnpgi/operator/lifecycle_test.go b/internal/cnpgi/operator/lifecycle_test.go index 675d657..48692ff 100644 --- a/internal/cnpgi/operator/lifecycle_test.go +++ b/internal/cnpgi/operator/lifecycle_test.go @@ -313,6 +313,60 @@ var _ = Describe("LifecycleImplementation", func() { Expect(err.Error()).To(ContainSubstring(ns + "/" + pc.RecoveryBarmanObjectName)) Expect(args).To(BeNil()) }) + + It("includes --log-level from primary object store when set", func(ctx SpecContext) { + ns := "test-ns" + cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: ns}} + pc := &config.PluginConfiguration{ + Cluster: cluster, + BarmanObjectName: "primary-store", + } + store := &barmancloudv1.ObjectStore{ + TypeMeta: metav1.TypeMeta{Kind: "ObjectStore", APIVersion: barmancloudv1.GroupVersion.String()}, + ObjectMeta: metav1.ObjectMeta{Name: pc.BarmanObjectName, Namespace: ns}, + Spec: barmancloudv1.ObjectStoreSpec{ + InstanceSidecarConfiguration: barmancloudv1.InstanceSidecarConfiguration{ + AdditionalContainerArgs: []string{"--alpha"}, + LogLevel: "debug", + }, + }, + } + s := runtime.NewScheme() + _ = barmancloudv1.AddToScheme(s) + cli := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(store).Build() + + impl := LifecycleImplementation{Client: cli} + args, err := impl.collectAdditionalInstanceArgs(ctx, pc) + Expect(err).NotTo(HaveOccurred()) + Expect(args).To(Equal([]string{"--alpha", "--log-level=debug"})) + }) + + It("includes --log-level from recovery object store when primary not set", func(ctx SpecContext) { + ns := "test-ns" + cluster := &cnpgv1.Cluster{ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: ns}} + pc := &config.PluginConfiguration{ + Cluster: cluster, + BarmanObjectName: "", + RecoveryBarmanObjectName: "reco-store", + } + store := &barmancloudv1.ObjectStore{ + TypeMeta: metav1.TypeMeta{Kind: "ObjectStore", APIVersion: barmancloudv1.GroupVersion.String()}, + ObjectMeta: metav1.ObjectMeta{Name: pc.RecoveryBarmanObjectName, Namespace: ns}, + Spec: barmancloudv1.ObjectStoreSpec{ + InstanceSidecarConfiguration: barmancloudv1.InstanceSidecarConfiguration{ + LogLevel: "info", + }, + }, + } + s := runtime.NewScheme() + _ = barmancloudv1.AddToScheme(s) + cli := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(store).Build() + + impl := LifecycleImplementation{Client: cli} + args, err := impl.collectAdditionalInstanceArgs(ctx, pc) + Expect(err).NotTo(HaveOccurred()) + Expect(args).To(Equal([]string{"--log-level=info"})) + }) }) }) diff --git a/manifest.yaml b/manifest.yaml index 5641fed..f2d601d 100644 --- a/manifest.yaml +++ b/manifest.yaml @@ -398,6 +398,11 @@ spec: items: type: string type: array + x-kubernetes-validations: + - message: do not set --log-level in additionalContainerArgs; + use spec.instanceSidecarConfiguration.logLevel + reason: FieldValueForbidden + rule: '!self.exists(a, a.startsWith(''--log-level''))' env: description: The environment to be explicitly passed to the sidecar items: @@ -556,6 +561,17 @@ spec: - name type: object type: array + logLevel: + default: info + description: 'The log level for PostgreSQL instances. Valid values + are: `error`, `warning`, `info` (default), `debug`, `trace`' + enum: + - error + - warning + - info + - debug + - trace + type: string resources: description: Resources define cpu/memory requests and limits for the sidecar that runs in the instance pods. diff --git a/web/docs/plugin-barman-cloud.v1.md b/web/docs/plugin-barman-cloud.v1.md index ea50bd9..7bd607c 100644 --- a/web/docs/plugin-barman-cloud.v1.md +++ b/web/docs/plugin-barman-cloud.v1.md @@ -30,6 +30,7 @@ _Appears in:_ | `retentionPolicyIntervalSeconds` _integer_ | The retentionCheckInterval defines the frequency at which the
system checks and enforces retention policies. | | 1800 | | | `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#resourcerequirements-v1-core)_ | Resources define cpu/memory requests and limits for the sidecar that runs in the instance pods. | | | | | `additionalContainerArgs` _string array_ | 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. | | | | +| `logLevel` _string_ | The log level for PostgreSQL instances. Valid values are: `error`, `warning`, `info` (default), `debug`, `trace` | | info | Enum: [error warning info debug trace]
| #### ObjectStore