mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-12 23:54:01 +09:00
Annotate storageClass as immutable across every stateful app whose chart exposes one — clickhouse, foundationdb, harbor, http-cache, kafka (Kafka + ZooKeeper), kubernetes (top-level only), mariadb, mongodb, nats, openbao, opensearch, postgres, qdrant, rabbitmq, redis, vm-disk. Without coverage across the catalogue the UI would render storageClass read-only on some apps and editable on others — a worse mental model than uniform behaviour. The annotation lands at the schema layer (CEL XValidation rule 'self == oldSelf' on values.schema.json / types.go / embedded openAPISchema in cozyrds/<app>.yaml). The cozystack aggregated apiserver does not yet evaluate CEL on application-backed resources; that is tracked at cozystack/cozystack#2657. The UI (cozystack/cozystack-ui#6) consumes the marker today. The PVC-pinning argument is identical for every chart: Kubernetes fixes a PVC's storageClassName at creation time, so editing this field on an existing resource never migrated data. The schema annotation makes that contract explicit. kubernetes.nodeGroups[name].storageClass is intentionally NOT annotated: the field is optional and undefaulted, so a strict 'self == oldSelf' rule would block any future attempt to set it on an existing node group. A richer ratcheting form is needed there — see docs/storage-immutability.md. A refactor in pkg/registry/apps/application/rest.go extracts the inline schema-build path into buildSpecSchema so it can be unit-tested. Three regression tests in rest_spec_schema_test.go pin the contract that x-kubernetes-validations survives the v1->internal->structural conversion (loaded from the actual MariaDB ApplicationDefinition fixture on disk, not a hand-edited mock). Each per-app README gains a one-line blockquote pointing to a new docs/storage-immutability.md that explains the contract and which consumers enforce it today. Requires cozystack/cozyvalues-gen with @immutable support — bump the pre-commit pin in .github/workflows/pre-commit.yml once the release exists. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Aleksei Sviridkin <f@lex.la>
87 lines
2.2 KiB
JSON
87 lines
2.2 KiB
JSON
{
|
|
"title": "Chart Values",
|
|
"type": "object",
|
|
"properties": {
|
|
"source": {
|
|
"description": "The source image location used to create a disk.",
|
|
"type": "object",
|
|
"default": {},
|
|
"properties": {
|
|
"disk": {
|
|
"description": "Clone an existing vm-disk.",
|
|
"type": "object",
|
|
"required": [
|
|
"name"
|
|
],
|
|
"properties": {
|
|
"name": {
|
|
"description": "Name of the vm-disk to clone.",
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"http": {
|
|
"description": "Download image from an HTTP source.",
|
|
"type": "object",
|
|
"required": [
|
|
"url"
|
|
],
|
|
"properties": {
|
|
"url": {
|
|
"description": "URL to download the image.",
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"image": {
|
|
"description": "Use image by name from default collection.",
|
|
"type": "object",
|
|
"required": [
|
|
"name"
|
|
],
|
|
"properties": {
|
|
"name": {
|
|
"description": "Name of the image to use.",
|
|
"type": "string"
|
|
}
|
|
}
|
|
},
|
|
"upload": {
|
|
"description": "Upload local image.",
|
|
"type": "object"
|
|
}
|
|
}
|
|
},
|
|
"optical": {
|
|
"description": "Defines if disk should be considered optical.",
|
|
"type": "boolean",
|
|
"default": false
|
|
},
|
|
"storage": {
|
|
"description": "The size of the disk allocated for the virtual machine.",
|
|
"default": "5Gi",
|
|
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
|
"anyOf": [
|
|
{
|
|
"type": "integer"
|
|
},
|
|
{
|
|
"type": "string"
|
|
}
|
|
],
|
|
"x-kubernetes-int-or-string": true
|
|
},
|
|
"storageClass": {
|
|
"description": "StorageClass used to store the data.",
|
|
"type": "string",
|
|
"default": "replicated",
|
|
"x-kubernetes-validations": [
|
|
{
|
|
"rule": "self == oldSelf",
|
|
"message": "storageClass is immutable"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|