Skip to content

K8SPSMDB-1518: allow specifying logrotate configuration#2151

Merged
hors merged 50 commits intomainfrom
K8SPSMDB-1518
Jan 7, 2026
Merged

K8SPSMDB-1518: allow specifying logrotate configuration#2151
hors merged 50 commits intomainfrom
K8SPSMDB-1518

Conversation

@mayankshah1607
Copy link
Copy Markdown
Member

@mayankshah1607 mayankshah1607 commented Dec 17, 2025

K8SPSMDB-1518 Powered by Pull Request Badge

CHANGE DESCRIPTION

Allows specifying custom configuration for logrotate:

  • override the default logroate conf
  • provide additional logrotate configuration
  • allow specifying logrotate schedule

Examples:

  1. Override the main logrotate configuration:
apiVersion: psmdb.percona.com/v1
kind: PerconaServerMongoDB
metadata:
  name: minimal-cluster
spec:
  logcollector:
    # ...
    logrotate:
      configuration: |
        /data/db/logs/*.log {
           daily
           minsize 10K
           maxsize 20K
           rotate 10
           missingok
           nocompress
           notifempty
           sharedscripts
           postrotate
               mongosh "mongodb://${MONGODB_USER}:${MONGODB_PASSWORD}@${MONGODB_HOST}:${MONGODB_PORT}/admin" \
                       --eval 'db.adminCommand({ logRotate: 1 })'
               find /data/db/logs/ -type f -name 'mongod.log.*' -mtime +7 -delete
               find /data/db/logs/ -type f -name 'mongod.full.log' -mtime +7 -delete
           endscript
        }
  1. Provide additional logrotate config (for example, for rotating auditlogs)
apiVersion: v1
kind: ConfigMap
metadata:
  name: logrotate-custom-conf
data:
  custom.conf: |
    /data/db/audit/*.json {
       minsize 10K
       maxsize 20K
       rotate 10
       missingok
       nocompress
       notifempty
       sharedscripts
       copytruncate
      }
---
apiVersion: psmdb.percona.com/v1
kind: PerconaServerMongoDB
metadata:
  name: minimal-cluster
spec:
  # ...
  replsets:
  - name: rs0
    size: 1
    configuration: |
      auditLog:
        destination: file
        format: JSON
        path: /data/db/audit/audit.json
    volumeSpec:
      persistentVolumeClaim:
        resources:
          requests:
            storage: 3Gi
  logcollector:
    # ...
    logrotate:
      extraConfig:
        name: logrotate-custom-conf
  1. Provide custom schedule
apiVersion: psmdb.percona.com/v1
kind: PerconaServerMongoDB
metadata:
  name: minimal-cluster
spec:
  # ...
  replsets:
  - name: rs0
    size: 1
    configuration: |
      auditLog:
        destination: file
        format: JSON
        path: /data/db/audit/audit.json
    volumeSpec:
      persistentVolumeClaim:
        resources:
          requests:
            storage: 3Gi
  logcollector:
    # ...
    logrotate:
      schedule: "0 0 * * 0"

CHECKLIST

Jira

  • Is the Jira ticket created and referenced properly?
  • Does the Jira ticket have the proper statuses for documentation (Needs Doc) and QA (Needs QA)?
  • Does the Jira ticket link to the proper milestone (Fix Version field)?

Tests

  • Is an E2E test/test case added for the new feature/change?
  • Are unit tests added where appropriate?
  • Are OpenShift compare files changed for E2E tests (compare/*-oc.yml)?

Config/Logging/Testability

  • Are all needed new/changed options added to default YAML files?
  • Are all needed new/changed options added to the Helm Chart?
  • Did we add proper logging messages for operator actions?
  • Did we ensure compatibility with the previous version or cluster upgrade process?
  • Does the change support oldest and newest supported MongoDB version?
  • Does the change support oldest and newest supported Kubernetes version?

Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Copilot AI review requested due to automatic review settings December 17, 2025 12:21
@pull-request-size pull-request-size bot added the size/L 100-499 lines label Dec 17, 2025
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for customizable logrotate configuration in the Percona Server MongoDB Operator. It introduces new API fields to allow users to specify custom logrotate configurations either inline or via external ConfigMaps, and refactors the logrotate container code into a dedicated package for better organization.

Key changes:

  • Added LogRotateSpec type with Configuration and ExtraConfig fields to the API
  • Refactored logrotate container creation from pkg/psmdb/logcollector/container.go to new package pkg/psmdb/logcollector/logrotate
  • Enhanced configuration hash calculation to include logrotate configurations for pod restart triggers

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
pkg/apis/psmdb/v1/psmdb_types.go Adds LogRotateSpec type with configuration fields
pkg/apis/psmdb/v1/zz_generated.deepcopy.go Auto-generated deep copy methods for LogRotateSpec
pkg/psmdb/logcollector/logrotate/container.go New package with logrotate container creation logic and volume mounts
pkg/psmdb/logcollector/container.go Removes logRotationContainer function, delegates to logrotate package
pkg/psmdb/statefulset.go Adds logrotate config params, volumes, and enhanced hash calculation
pkg/controller/perconaservermongodb/statefulset.go Retrieves logrotate configs and passes to statefulset creation
pkg/controller/perconaservermongodb/psmdb_controller.go Adds reconcileLogRotateConfigMaps for managing logrotate ConfigMap
build/logcollector/entrypoint.sh Adds support for custom logrotate config directory in entrypoint script
config/crd/bases/psmdb.percona.com_perconaservermongodbs.yaml Updates CRD schema with logRotate fields
deploy/crd.yaml Updates CRD schema with logRotate fields
deploy/bundle.yaml Updates CRD schema with logRotate fields
deploy/cw-bundle.yaml Updates CRD schema with logRotate fields
e2e-tests/version-service/conf/crd.yaml Updates CRD schema with logRotate fields

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Copilot AI review requested due to automatic review settings December 17, 2025 12:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Copilot AI review requested due to automatic review settings December 22, 2025 10:09
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1511 to +1512
// ExtraConfig allows specifying logrotate configuration file in addition to the main configuration file.
// This should be a reference to a ConfigMap in the same namespace.
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation states that ExtraConfig should reference a ConfigMap in the same namespace, but does not specify the required structure or key names within that ConfigMap. The entrypoint script expects a file named 'custom.conf' (line 15 of build/logcollector/entrypoint.sh), but when a ConfigMap is projected into a volume, each key in the ConfigMap becomes a filename. Users need to know they must create a ConfigMap with a key named 'custom.conf' for this feature to work correctly. Consider adding this requirement to the field documentation.

Suggested change
// ExtraConfig allows specifying logrotate configuration file in addition to the main configuration file.
// This should be a reference to a ConfigMap in the same namespace.
// ExtraConfig allows specifying a logrotate configuration file in addition to the main configuration file.
// This should be a reference to a ConfigMap in the same namespace.
// The referenced ConfigMap must contain a key named "custom.conf"; when the ConfigMap is mounted as a volume,
// that key becomes a file named "custom.conf" that is loaded as the extra logrotate configuration.

Copilot uses AI. Check for mistakes.
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Copilot AI review requested due to automatic review settings December 22, 2025 10:19
@mayankshah1607 mayankshah1607 marked this pull request as ready for review December 22, 2025 10:20
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
@mayankshah1607 mayankshah1607 requested review from gkech and hors January 5, 2026 05:01
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Copilot AI review requested due to automatic review settings January 5, 2026 06:38
Copy link
Copy Markdown

Copilot AI commented Jan 5, 2026

@mayankshah1607 I've opened a new pull request, #2170, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings January 5, 2026 06:51
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: Mayank Shah <mayank.shah@percona.com>
@hors hors requested a review from egegunes January 5, 2026 10:40
Copilot AI review requested due to automatic review settings January 5, 2026 11:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

ExtraConfig corev1.LocalObjectReference `json:"extraConfig,omitempty"`
// Schedule allows specifying the schedule for logrotate.
// This should be a valid cron expression.
//+kubebuilder:default:="0 0 * * *"
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Schedule field lacks validation for cron expression format. Invalid cron expressions will be passed directly to go-cron, which may cause runtime errors. Consider adding validation (e.g., using a kubebuilder validation marker like +kubebuilder:validation:Pattern) or documenting that invalid schedules will result in container failures.

Suggested change
//+kubebuilder:default:="0 0 * * *"
//+kubebuilder:default:="0 0 * * *"
//+kubebuilder:validation:Pattern=`^(\S+\s+){4}\S+$`

Copilot uses AI. Check for mistakes.
mkdir -p /tmp/fluentbit/custom
set +e
local fluentbit_conf_dir="/opt/percona/logcollector/fluentbit/custom"
for conf_file in $fluentbit_conf_dir/*.conf; do
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The loop variable conf_file is not quoted. If the glob pattern doesn't match any files or if filenames contain spaces, this could cause issues. The variable should be quoted: for conf_file in "$fluentbit_conf_dir"/*.conf; do

Suggested change
for conf_file in $fluentbit_conf_dir/*.conf; do
for conf_file in "$fluentbit_conf_dir"/*.conf; do

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +111
func Container(cr *api.PerconaServerMongoDB, mongoPort int32) (*corev1.Container, error) {
if cr.Spec.LogCollector == nil {
return nil, errors.New("logcollector can't be nil")
}

usersSecretName := api.UserSecretName(cr)

envs := []corev1.EnvVar{
{
Name: "MONGODB_HOST",
Value: "localhost",
},
{
Name: "MONGODB_PORT",
Value: strconv.Itoa(int(mongoPort)),
},
{
Name: "MONGODB_USER",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Key: "MONGODB_CLUSTER_ADMIN_USER_ESCAPED",
LocalObjectReference: corev1.LocalObjectReference{
Name: usersSecretName,
},
Optional: ptr.To(false),
},
},
},
{
Name: "MONGODB_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
Key: "MONGODB_CLUSTER_ADMIN_PASSWORD_ESCAPED",
LocalObjectReference: corev1.LocalObjectReference{
Name: usersSecretName,
},
Optional: ptr.To(false),
},
},
},
}

container := corev1.Container{
Name: "logrotate",
Image: cr.Spec.LogCollector.Image,
Env: envs,
ImagePullPolicy: cr.Spec.LogCollector.ImagePullPolicy,
SecurityContext: cr.Spec.LogCollector.ContainerSecurityContext,
Resources: cr.Spec.LogCollector.Resources,
Args: []string{
"logrotate",
},
Command: []string{"/opt/percona/logcollector/entrypoint.sh"},
VolumeMounts: []corev1.VolumeMount{
{
Name: config.MongodDataVolClaimName,
MountPath: config.MongodContainerDataDir,
},
{
Name: config.BinVolumeName,
MountPath: config.BinMountPath,
},
},
}

if cr.Spec.LogCollector.LogRotate != nil {
if cr.Spec.LogCollector.LogRotate.Configuration != "" || cr.Spec.LogCollector.LogRotate.ExtraConfig.Name != "" {
container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
Name: VolumeName,
MountPath: configDir,
})
}
if cr.Spec.LogCollector.LogRotate.Schedule != "" {
container.Env = append(container.Env, corev1.EnvVar{
Name: "LOGROTATE_SCHEDULE",
Value: cr.Spec.LogCollector.LogRotate.Schedule,
})
}
}

return &container, nil
}
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no test coverage for the new logrotate.Container function. The test file pkg/psmdb/logcollector/container_test.go tests the Containers function which calls logrotate.Container, but direct unit tests for the logrotate package's Container function would improve test coverage and make it easier to verify edge cases like nil LogRotate spec or empty values.

Copilot uses AI. Check for mistakes.
@JNKPercona
Copy link
Copy Markdown
Collaborator

Test Name Result Time
arbiter passed 00:00:00
balancer passed 00:00:00
cross-site-sharded passed 00:00:00
custom-replset-name passed 00:00:00
custom-tls passed 00:00:00
custom-users-roles passed 00:00:00
custom-users-roles-sharded passed 00:00:00
data-at-rest-encryption passed 00:00:00
data-sharded passed 00:00:00
demand-backup passed 00:00:00
demand-backup-eks-credentials-irsa passed 00:00:00
demand-backup-fs passed 00:00:00
demand-backup-if-unhealthy passed 00:00:00
demand-backup-incremental passed 00:00:00
demand-backup-incremental-sharded passed 00:00:00
demand-backup-physical-parallel passed 00:00:00
demand-backup-physical-aws passed 00:00:00
demand-backup-physical-azure passed 00:00:00
demand-backup-physical-gcp-s3 passed 00:00:00
demand-backup-physical-gcp-native passed 00:00:00
demand-backup-physical-minio passed 00:00:00
demand-backup-physical-minio-native passed 00:00:00
demand-backup-physical-sharded-parallel passed 00:00:00
demand-backup-physical-sharded-aws passed 00:00:00
demand-backup-physical-sharded-azure passed 00:00:00
demand-backup-physical-sharded-gcp-native passed 00:00:00
demand-backup-physical-sharded-minio passed 00:00:00
demand-backup-physical-sharded-minio-native passed 00:00:00
demand-backup-sharded passed 00:00:00
expose-sharded passed 00:00:00
finalizer passed 00:00:00
ignore-labels-annotations passed 00:00:00
init-deploy passed 00:00:00
ldap passed 00:00:00
ldap-tls passed 00:13:03
limits passed 00:00:00
liveness passed 00:00:00
mongod-major-upgrade passed 00:00:00
mongod-major-upgrade-sharded passed 00:00:00
monitoring-2-0 passed 00:00:00
monitoring-pmm3 passed 00:00:00
multi-cluster-service passed 00:00:00
multi-storage passed 00:00:00
non-voting-and-hidden passed 00:00:00
one-pod passed 00:00:00
operator-self-healing-chaos passed 00:00:00
pitr passed 00:00:00
pitr-physical passed 00:00:00
pitr-sharded passed 00:00:00
pitr-to-new-cluster passed 00:00:00
pitr-physical-backup-source passed 00:00:00
preinit-updates passed 00:00:00
pvc-resize passed 00:00:00
recover-no-primary passed 00:00:00
replset-overrides passed 00:00:00
replset-remapping passed 00:00:00
replset-remapping-sharded passed 00:00:00
rs-shard-migration passed 00:00:00
scaling passed 00:00:00
scheduled-backup passed 00:00:00
security-context passed 00:00:00
self-healing-chaos passed 00:00:00
service-per-pod passed 00:00:00
serviceless-external-nodes passed 00:00:00
smart-update passed 00:00:00
split-horizon passed 00:00:00
stable-resource-version passed 00:00:00
storage passed 00:00:00
tls-issue-cert-manager passed 00:00:00
unsafe-psa passed 00:00:00
upgrade passed 00:00:00
upgrade-consistency passed 00:00:00
upgrade-consistency-sharded-tls passed 00:00:00
upgrade-sharded passed 00:00:00
upgrade-partial-backup passed 00:00:00
users passed 00:00:00
users-vault passed 00:00:00
version-service passed 00:00:00
Summary Value
Tests Run 78/78
Job Duration 00:40:46
Total Test Time 00:13:03

commit: f9b073b
image: perconalab/percona-server-mongodb-operator:PR-2151-f9b073b0

@hors hors merged commit 3813b41 into main Jan 7, 2026
11 of 12 checks passed
@hors hors deleted the K8SPSMDB-1518 branch January 7, 2026 11:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants