Skip to content

Add PVC for persistent PostgreSQL storage#107

Merged
openshift-merge-bot[bot] merged 1 commit into
openstack-lightspeed:lcore-migrationfrom
umago:persistent-database
May 27, 2026
Merged

Add PVC for persistent PostgreSQL storage#107
openshift-merge-bot[bot] merged 1 commit into
openstack-lightspeed:lcore-migrationfrom
umago:persistent-database

Conversation

@umago
Copy link
Copy Markdown
Contributor

@umago umago commented May 21, 2026

Introduce a "database" field on the OpenStackLightspeed CR spec that allows configuring a PersistentVolumeClaim for the PostgreSQL data directory.

A few details about the implementation:

  • Reuse existing PVC if one already exists with matching size
  • Block reconciliation with a clear error if existing PVC size does not match the requested size
  • If database is omitted from the CR, create a persistent storage with the default values
  • If no database.class is specified uses the cluster default
  • Default PVC size is "1Gi"

The PVC is created without an owner reference so that data survives CR deletion and is reused on re-creation.

Summary by CodeRabbit

Release Notes

  • New Features

    • Persistent PostgreSQL storage is now configurable with customizable volume size and storage class options. Configure via the OpenStackLightspeed resource. Default storage size is 1Gi when not specified.
  • Documentation

    • Sample configuration manifests now include examples demonstrating persistent database storage setup for OpenStackLightspeed deployments.

Review Change Stack

@openshift-ci openshift-ci Bot requested review from Akrog and lpiwowar May 21, 2026 14:19
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f6949d88-e492-41a3-88a9-b21eaf5c244d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately and concisely describes the main change: adding a PersistentVolumeClaim for persistent PostgreSQL storage, which is the core objective of this changeset across all modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@umago umago force-pushed the persistent-database branch from a9ac9e3 to c22c241 Compare May 21, 2026 14:24
@umago umago marked this pull request as draft May 21, 2026 14:54
@umago umago force-pushed the persistent-database branch from c22c241 to 408cd23 Compare May 21, 2026 15:00
@umago umago marked this pull request as ready for review May 21, 2026 15:14
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
api/v1beta1/openstacklightspeed_types.go (1)

52-55: 💤 Low value

Consider naming the field storageClass (or storageClassName) for native-API alignment.

The Kubernetes convention for selecting a StorageClass on a PVC is storageClassName (see PersistentVolumeClaimSpec.StorageClassName). The bare class JSON key is unusual in this ecosystem and may surprise users writing CRs. Since this is a brand-new optional field and the API has not shipped, renaming now avoids a breaking change later.

♻️ Suggested rename
-	// +kubebuilder:validation:Optional
-	// StorageClass name for the PersistentVolumeClaim. If omitted, the cluster's
-	// default StorageClass is used.
-	Class string `json:"class,omitempty"`
+	// +kubebuilder:validation:Optional
+	// StorageClassName for the PersistentVolumeClaim. If omitted, the cluster's
+	// default StorageClass is used.
+	StorageClassName string `json:"storageClassName,omitempty"`

Remember to update the sample manifest, the CRD bundle/base YAMLs, and any controller code that reads spec.database.class.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/v1beta1/openstacklightspeed_types.go` around lines 52 - 55, Rename the
PVC storage selector field from Class to StorageClassName (or storageClass if
you prefer camelCase) to match Kubernetes conventions: update the struct field
name (Class) to StorageClassName, change the json tag from
`json:"class,omitempty"` to `json:"storageClassName,omitempty"` and adjust the
kubebuilder validation marker if needed; then update all references in
manifests, CRD YAMLs, sample manifests, and controller code that currently
access spec.database.class to use spec.database.storageClassName (or
spec.database.storageClass) so consumers and the controller read the new field
name consistently.
test/kuttl/tests/persistent-database/03-assert-openstack-lightspeed-instance.yaml (2)

40-49: ⚡ Quick win

Assert the Postgres Deployment uses a PVC-backed data volume.

Current checks only validate Deployment readiness. Add an assertion on spec.template.spec.volumes to confirm it references openstack-lightspeed-data; otherwise an emptyDir regression could pass unnoticed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@test/kuttl/tests/persistent-database/03-assert-openstack-lightspeed-instance.yaml`
around lines 40 - 49, Add an assertion to the test that verifies the Deployment
lightspeed-postgres-server in namespace openstack-lightspeed has a PVC-backed
volume: check spec.template.spec.volumes contains an entry with
persistentVolumeClaim.claimName equal to "openstack-lightspeed-data" (rather
than an emptyDir), so update the test assertions to inspect
spec.template.spec.volumes and fail if the PVC reference is missing or if only
emptyDir is present.

10-18: ⚡ Quick win

Add an assertion that the PVC has no owner references.

This PR relies on the PVC surviving CR deletion. Please assert the PVC is not controller-owned to lock that behavior against regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@test/kuttl/tests/persistent-database/03-assert-openstack-lightspeed-instance.yaml`
around lines 10 - 18, Add an assertion to the kuttl test for the PVC named
"openstack-lightspeed-data" in namespace "openstack-lightspeed" to verify it has
no ownerReferences (i.e., ownerReferences is absent or an empty array) so the
PVC is not controller-owned; update the test manifest
03-assert-openstack-lightspeed-instance.yaml to include this check after the PVC
exists assertion to lock the behavior that the PVC survives CR deletion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@api/v1beta1/openstacklightspeed_types.go`:
- Around line 45-56: The Size field on DatabaseSpec lacks a kubebuilder
validation pattern allowing invalid Kubernetes quantity strings to pass
admission; add a +kubebuilder:validation:Pattern tag on the Size field in type
DatabaseSpec using the standard k8s resource quantity regex (e.g. the usual
kubernetes quantity pattern used for memory/storage like
^([+-])?([0-9]+)([EPTGMkmunpf]i?)?$) so invalid values fail at admission, then
regenerate the CRD manifests (run controller-gen / your repo make target) so the
bundle/base YAML schemas pick up the new pattern.

In `@internal/controller/openstacklightspeed_controller.go`:
- Line 73: Update the kubebuilder RBAC marker in
openstacklightspeed_controller.go that currently grants PVC deletion rights:
locate the comment line containing
"+kubebuilder:rbac:groups="",resources=persistentvolumeclaims,namespace=openstack-lightspeed,verbs=..."
and remove the "delete" verb so the verbs list becomes
get;list;watch;create;patch;update to preserve the persistence contract and
prevent PVC deletion.
- Line 280: reconcilePostgresPVC currently creates/patches the PVC without
setting an ownerReference, so the controller's
Owns(&corev1.PersistentVolumeClaim{}) in openstacklightspeed_controller.go will
never be triggered; fix by adding
controllerutil.SetControllerReference(h.GetBeforeObject(), pvc, h.GetScheme())
inside the PVC mutate callback used by controllerutil.CreateOrPatch in
reconcilePostgresPVC so the PVC gets a controller ownerReference on
create/update; if you intentionally must avoid ownerReferences instead, replace
the Owns(&corev1.PersistentVolumeClaim{}) watch in
openstacklightspeed_controller.go with an explicit Watches(...) +
handler.EnqueueRequestsFromMapFunc that maps PVC events back to the owning
Postgres/OpenStack resource.

---

Nitpick comments:
In `@api/v1beta1/openstacklightspeed_types.go`:
- Around line 52-55: Rename the PVC storage selector field from Class to
StorageClassName (or storageClass if you prefer camelCase) to match Kubernetes
conventions: update the struct field name (Class) to StorageClassName, change
the json tag from `json:"class,omitempty"` to
`json:"storageClassName,omitempty"` and adjust the kubebuilder validation marker
if needed; then update all references in manifests, CRD YAMLs, sample manifests,
and controller code that currently access spec.database.class to use
spec.database.storageClassName (or spec.database.storageClass) so consumers and
the controller read the new field name consistently.

In
`@test/kuttl/tests/persistent-database/03-assert-openstack-lightspeed-instance.yaml`:
- Around line 40-49: Add an assertion to the test that verifies the Deployment
lightspeed-postgres-server in namespace openstack-lightspeed has a PVC-backed
volume: check spec.template.spec.volumes contains an entry with
persistentVolumeClaim.claimName equal to "openstack-lightspeed-data" (rather
than an emptyDir), so update the test assertions to inspect
spec.template.spec.volumes and fail if the PVC reference is missing or if only
emptyDir is present.
- Around line 10-18: Add an assertion to the kuttl test for the PVC named
"openstack-lightspeed-data" in namespace "openstack-lightspeed" to verify it has
no ownerReferences (i.e., ownerReferences is absent or an empty array) so the
PVC is not controller-owned; update the test manifest
03-assert-openstack-lightspeed-instance.yaml to include this check after the PVC
exists assertion to lock the behavior that the PVC survives CR deletion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e0e3087b-f592-4e7d-bd2e-d6608c229946

📥 Commits

Reviewing files that changed from the base of the PR and between a8abf60 and 408cd23.

📒 Files selected for processing (21)
  • api/v1beta1/openstacklightspeed_types.go
  • api/v1beta1/zz_generated.deepcopy.go
  • bundle/manifests/lightspeed.openstack.org_openstacklightspeeds.yaml
  • bundle/manifests/openstack-lightspeed-operator.clusterserviceversion.yaml
  • config/crd/bases/lightspeed.openstack.org_openstacklightspeeds.yaml
  • config/manifests/bases/openstack-lightspeed-operator.clusterserviceversion.yaml
  • config/rbac/role.yaml
  • config/samples/api_v1beta1_openstacklightspeed.yaml
  • internal/controller/constants.go
  • internal/controller/errors.go
  • internal/controller/openstacklightspeed_controller.go
  • internal/controller/postgres_deployment.go
  • internal/controller/postgres_reconciler.go
  • test/kuttl/tests/persistent-database/00-mock-resources.yaml
  • test/kuttl/tests/persistent-database/01-assert-mock-objects-created.yaml
  • test/kuttl/tests/persistent-database/02-create-openstack-lightspeed-instance.yaml
  • test/kuttl/tests/persistent-database/03-assert-openstack-lightspeed-instance.yaml
  • test/kuttl/tests/persistent-database/04-cleanup-openstack-lightspeed-instance.yaml
  • test/kuttl/tests/persistent-database/05-errors-openstack-lightspeed-instance.yaml
  • test/kuttl/tests/persistent-database/06-cleanup-mock-objects.yaml
  • test/kuttl/tests/persistent-database/07-errors-mock-objects.yaml

Comment thread api/v1beta1/openstacklightspeed_types.go
Comment thread internal/controller/openstacklightspeed_controller.go Outdated
Comment thread internal/controller/openstacklightspeed_controller.go Outdated
@umago umago force-pushed the persistent-database branch 3 times, most recently from d11b739 to ba50b7e Compare May 25, 2026 08:31
Copy link
Copy Markdown
Contributor

@lpiwowar lpiwowar left a comment

Choose a reason for hiding this comment

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

Overall LGTM! 👍 Thank you! Just three things crossed my mind.

Comment thread api/v1beta1/openstacklightspeed_types.go Outdated
Comment thread internal/controller/postgres_deployment.go Outdated
Comment thread internal/controller/postgres_reconciler.go Outdated
@umago umago force-pushed the persistent-database branch from 67f5245 to 63b0c1d Compare May 26, 2026 10:39
@umago
Copy link
Copy Markdown
Contributor Author

umago commented May 26, 2026

The resource. Quantity works nicely:

$ oc apply -f cr.yaml 
The OpenStackLightspeed "openstack-lightspeed" is invalid: spec.database.size: Invalid value: "hahahaa": spec.database.size in body should match '^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$'

@umago umago force-pushed the persistent-database branch 2 times, most recently from b7e0886 to 49d47a6 Compare May 27, 2026 09:22
Introduce a "database" field on the OpenStackLightspeed CR spec that
allows configuring a PersistentVolumeClaim for the PostgreSQL data
directory.

A few details about the implementation:

* Reuse existing PVC if one already exists with matching size
* Block reconciliation with a clear error if existing PVC size does
not match the requested size
* If database is omitted from the CR, create a persistent storage with
the default values
* If no database.class is specified uses the cluster default
* Default PVC size is "1Gi"

The PVC is created without an owner reference so that data survives
CR deletion and is reused on re-creation.

Signed-off-by: Lucas Alvares Gomes <lucasagomes@gmail.com>
@umago umago force-pushed the persistent-database branch from 49d47a6 to 5b8e848 Compare May 27, 2026 09:52
PostgresConfigVolumeMountPath = "/usr/share/pgsql/postgresql.conf.sample"
PostgresDataVolume = "postgres-data"
PostgresDataVolumeMountPath = "/var/lib/pgsql"
PostgresDataPVCName = "openstack-lightspeed-data"
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.

nit: I would prefer it ending in -database or -db.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the review. Done in a follow-up PR: #108

return fmt.Errorf("%w: requested size %s but existing PVC has %s",
ErrPostgresPVCSizeMismatch, requestedQty.String(), existingQty.String())
}
h.GetLogger().Info("Postgres PVC already exists with matching size", "name", pvc.Name)
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.

nit: Say what happens: Reusing existing Postgress PVC with matching size

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the review. Done in a follow-up PR: #108

Copy link
Copy Markdown
Contributor

@Akrog Akrog left a comment

Choose a reason for hiding this comment

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

/lgtm
/approve

@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented May 27, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Akrog, umago

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot openshift-merge-bot Bot merged commit 0f8b424 into openstack-lightspeed:lcore-migration May 27, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants