Skip to content

CH-288 add support for RWX volumes - #862

Merged
filippomc merged 15 commits into
developfrom
feature/CH-288
Sep 1, 2026
Merged

CH-288 add support for RWX volumes#862
filippomc merged 15 commits into
developfrom
feature/CH-288

Conversation

@filippomc

@filippomc filippomc commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Closes CH-288

Implemented solution

ReadWriteMany support at the application level, and a configurable storage class for every auto-created volume (standard was hardcoded in the templates).

Setting Default Meaning
harness.deployment.volume.writeMany false Create and mount the volume as ReadWriteMany
harness.deployment.volume.storageClass standard Storage class of the volume claim, overrides the deployment default
harness.database.storageClass - (default) Storage class of the database volume claim (plain, statefulset and CNPG operator storage); null omits it
  • A ReadWriteMany volume attaches to several nodes, so its pods are not pinned: no podAffinity, no Recreate strategy, and a statefulset keeps mounting the shared PVC instead of provisioning one per replica.
  • Argo workflows are covered too: volume_requires_affinity resolves ReadWriteMany from the application configuration, so a workflow mounting a writeMany application volume gets no usesvolume affinity, without needing the :rwx marker (still honoured for claims no application declares).
  • Storage class resolution: usenfs → volume storageClassharness.deployment.storageClassstandard when the key is absent (values generated before this change render as today).
  • usenfs is now legacy sugar for writeMany + the nfs provisioner class, and the nfs settings prevail: harness-deployment warns on collision (sets usenfs and storageClass efs-sc: the nfs server storage class prevails).
  • Database volumes stay ReadWriteOnce by design.

Deployment update required (alert:deployment): the database PVC previously emitted no storageClassName and now emits standard, which is immutable on an existing claim. Clusters whose default class is standard (minikube, kind, GKE) are unaffected (no-op patch); on EKS/AKS set harness.database.storageClass to the cluster class or to null before upgrading a release that already has a database volume, otherwise helm upgrade is rejected. Same for flipping writeMany or the storage class on a live volume: the claim must be recreated and the data is not migrated.

How to test this PR

conda activate ch
cd tools/deployment-cli-tools && pytest tests/test_helm.py     # 41 tests, incl. the 3 new volume ones
cd ../../libraries/cloudharness-common && pytest tests/test_workflow.py

Manually, on an application with harness.deployment.volume:

  1. writeMany: true → the PVC is ReadWriteMany and the Deployment has no strategy: Recreate and no affinity.
  2. storageClass: efs-sc on the volume → storageClassName: efs-sc; harness.deployment.storageClass: null with no volume class → no storageClassName at all.
  3. usenfs: true together with storageClass/writeMany: false → the PVC gets the nfs class and ReadWriteMany, and harness-deployment logs the collision warnings.
  4. harness.database.storageClassstandard by default on the database PVC, null omits it.

Sanity checks:

  • The pull request is explicitly linked to the relevant issue(s)
  • The issue is well described: clearly states the problem and the general proposed solution(s)
  • In this PR it is explicitly stated how to test the current change
  • The issue seta the scope and the type of issue (bug, story, task, etc.)
  • The relevant components are indicated in the issue (if any)
  • All the automated test checks are passing
  • All the linked issues are included in one Sprint
  • All the linked issues are in the Review state
  • All the linked issues are assigned

Breaking changes (select one):

  • The present changes do not change the preexisting api in any way
  • This PR and the issue are tagged as a breaking-change and the migration procedure is well described above

Possible deployment updates issues (select one):

  • There is no reason why deployments based on CloudHarness may break after the current update
  • This PR and the issue are tagged as alert:deployment because might need to delete stateful sets

Test coverage (select one):

  • Tests for the relevant cases are included in this pr
  • The changes included in this pr are out of the current test coverage scope

Documentation (select one):

  • The documentation has been updated to match the current changes
  • The changes included in this PR are out of the current documentation scope

Nice to have (if relevant):

  • Screenshots of the changes
  • Explanatory video/animated gif

@filippomc
filippomc requested a review from aranega August 31, 2026 14:35
Comment thread tools/deployment-cli-tools/ch_cli_tools/configurationgenerator.py Fixed
Comment thread tools/deployment-cli-tools/ch_cli_tools/configurationgenerator.py Fixed
@afonsobspinto

Copy link
Copy Markdown
Member

This is going to be useful for neuroglass skeleton ingestion 👍

@aranega aranega left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@filippomc All looks good :) thanks a lot for the quick implementation!

@aranega aranega left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I reviewed the delta between the last version and my last acceptance, all looks good :)

Comment on lines +21 to +26
import {
WriteFile200ResponseFromJSON,
WriteFile200ResponseToJSON,
WriteFileRequestFromJSON,
WriteFileRequestToJSON,
} from '../models/index';
* Do not edit the class manually.
*/

import { mapValues } from '../runtime';
* Do not edit the class manually.
*/

import { mapValues } from '../runtime';
@@ -0,0 +1,113 @@
from datetime import date, datetime # noqa: F401
@@ -0,0 +1,113 @@
from datetime import date, datetime # noqa: F401

from typing import List, Dict # noqa: F401
@@ -0,0 +1,61 @@
from datetime import date, datetime # noqa: F401
@@ -0,0 +1,61 @@
from datetime import date, datetime # noqa: F401

from typing import List, Dict # noqa: F401
Comment thread libraries/cloudharness-common/cloudharness/utils/__init__.py Fixed
return response

@app.before_request
def handle_preflight():
try:
import flask
request = flask.request if flask.has_request_context() else None
except:
@filippomc
filippomc merged commit 861bbec into develop Sep 1, 2026
9 of 11 checks passed
@filippomc
filippomc deleted the feature/CH-288 branch September 1, 2026 17:02
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.

4 participants