Skip to content

K8SPG-1056 Detect PostgreSQL distribution and include it in telemetry#1664

Open
hors wants to merge 1 commit into
mainfrom
K8SPG-1056
Open

K8SPG-1056 Detect PostgreSQL distribution and include it in telemetry#1664
hors wants to merge 1 commit into
mainfrom
K8SPG-1056

Conversation

@hors

@hors hors commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

CHANGE DESCRIPTION

Solution:
Exec postgres -V in the database container alongside the existing Patroni version check to determine whether the cluster runs Percona Server for PostgreSQL ("percona") or upstream PostgreSQL ("community"). The result is stored in status.postgres.distribution and forwarded to the telemetry metadata struct so the version service can receive it once the API contract is extended on that end.

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?

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 PG version?
  • Does the change support oldest and newest supported Kubernetes version?

Exec `postgres -V` in the database container alongside the existing
Patroni version check to determine whether the cluster runs Percona
Server for PostgreSQL ("percona") or upstream PostgreSQL ("community").
The result is stored in status.postgres.distribution and forwarded to
the telemetry metadata struct so the version service can receive it
once the API contract is extended on that end.
Copilot AI review requested due to automatic review settings June 30, 2026 11:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds PostgreSQL distribution detection to the operator by executing postgres -V in the database container, storing the result in status.postgres.distribution, and threading that value into the telemetry metadata struct used by the version service integration.

Changes:

  • Extend PostgresStatus with a new distribution field and update CRD schemas accordingly.
  • Detect distribution (percona vs community) during Patroni version reconciliation via postgres -V exec.
  • Add Distribution to the telemetry meta struct and populate it from cluster status.

Reviewed changes

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

Show a summary per file
File Description
pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go Adds status.postgres.distribution field to the API type.
percona/version/version.go Extends telemetry Meta struct with Distribution.
percona/controller/pgcluster/version.go Populates telemetry meta Distribution from CR status.
percona/controller/pgcluster/patroniversion.go Implements distribution detection and persists it to CR status.
deploy/cw-bundle.yaml Updates CRD schema to include status.postgres.distribution.
deploy/crd.yaml Updates CRD schema to include status.postgres.distribution.
deploy/bundle.yaml Updates CRD schema to include status.postgres.distribution.
config/crd/bases/pgv2.percona.com_perconapgclusters.yaml Updates base CRD schema for the new status field.
build/crd/percona/generated/pgv2.percona.com_perconapgclusters.yaml Updates generated CRD schema for the new status field.

Comment on lines +59 to +62
distribution, err := r.getPostgresDistribution(ctx, &p, naming.ContainerDatabase)
if err != nil {
return errors.Wrap(err, "failed to get postgres distribution")
}
Comment on lines +332 to +345
func (r *PGClusterReconciler) getPostgresDistribution(ctx context.Context, pod *corev1.Pod, containerName string) (string, error) {
var stdout, stderr bytes.Buffer
execCli, err := clientcmd.NewClient()
if err != nil {
return "", errors.Wrap(err, "failed to create exec client")
}
if err := execCli.Exec(ctx, pod, containerName, nil, &stdout, &stderr, "postgres", "-V"); err != nil {
return "", errors.Wrap(err, "exec")
}
if strings.Contains(stdout.String(), "Percona Server for PostgreSQL") {
return "percona", nil
}
return "community", nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@hors please consider this

return errors.Wrap(err, "failed to get patroni version")
}

distribution, err := r.getPostgresDistribution(ctx, &p, naming.ContainerDatabase)
@JNKPercona

Copy link
Copy Markdown
Collaborator
Test Name Result Time
backup-enable-disable passed 00:00:00
builtin-extensions passed 00:00:00
cert-manager-tls passed 00:00:00
custom-envs passed 00:00:00
custom-tls passed 00:00:00
database-init-sql passed 00:00:00
demand-backup passed 00:00:00
demand-backup-offline-snapshot passed 00:00:00
dynamic-configuration passed 00:00:00
finalizers passed 00:00:00
init-deploy passed 00:00:00
huge-pages passed 00:00:00
major-upgrade-14-to-15 passed 00:00:00
major-upgrade-15-to-16 passed 00:00:00
major-upgrade-16-to-17 passed 00:00:00
major-upgrade-17-to-18 passed 00:00:00
ldap passed 00:00:00
ldap-tls passed 00:00:00
monitoring passed 00:00:00
monitoring-pmm3 passed 00:00:00
one-pod passed 00:00:00
operator-self-healing passed 00:00:00
pitr passed 00:00:00
scaling passed 00:00:00
scheduled-backup passed 00:00:00
self-healing passed 00:10:02
sidecars passed 00:00:00
standby-pgbackrest passed 00:00:00
standby-streaming passed 00:00:00
start-from-backup passed 00:00:00
tablespaces passed 00:00:00
telemetry-transfer passed 00:00:00
upgrade-consistency passed 00:00:00
upgrade-minor passed 00:00:00
users passed 00:00:00
Summary Value
Tests Run 35/35
Job Duration 00:39:36
Total Test Time 00:10:02

commit: 15d9300
image: perconalab/percona-postgresql-operator:PR-1664-15d93006f

@egegunes egegunes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM in general, there's one copilot comment that needs to be addressed

Comment on lines +332 to +345
func (r *PGClusterReconciler) getPostgresDistribution(ctx context.Context, pod *corev1.Pod, containerName string) (string, error) {
var stdout, stderr bytes.Buffer
execCli, err := clientcmd.NewClient()
if err != nil {
return "", errors.Wrap(err, "failed to create exec client")
}
if err := execCli.Exec(ctx, pod, containerName, nil, &stdout, &stderr, "postgres", "-V"); err != nil {
return "", errors.Wrap(err, "exec")
}
if strings.Contains(stdout.String(), "Percona Server for PostgreSQL") {
return "percona", nil
}
return "community", nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@hors please consider this

return "", errors.Wrap(err, "exec")
}
if strings.Contains(stdout.String(), "Percona Server for PostgreSQL") {
return "percona", nil

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

instead of using hardcoded values, I would prefer these to be constants

if err := execCli.Exec(ctx, pod, containerName, nil, &stdout, &stderr, "postgres", "-V"); err != nil {
return "", errors.Wrap(err, "exec")
}
if strings.Contains(stdout.String(), "Percona Server for PostgreSQL") {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

would also like to link through a comment which part of the docker image defines this particular string so we can have a refernece on the linking

return pods, nil
}

func (r *PGClusterReconciler) getPostgresDistribution(ctx context.Context, pod *corev1.Pod, containerName string) (string, error) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So the idea is that everything that is not percona is community, we will never return an empty string, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants