k8s add snapshotter and snapshot-controller to tenant k8s - #1203
Conversation
WalkthroughThis update introduces CSI snapshot functionality to the Kubernetes deployment by adding snapshot controller containers and integrating the necessary CRDs for volume snapshots. It also adds Helm chart resources and automation for managing these CRDs, including HelmRelease manifests and supporting files for the new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant HelmRelease Controller
participant Kubernetes API
participant CSI Controller Pod
participant csi-snapshotter
participant snapshot-controller
participant CRDs
User->>HelmRelease Controller: Apply HelmRelease for volumesnapshot CRD
HelmRelease Controller->>Kubernetes API: Install/Upgrade CRDs (VolumeSnapshot, etc.)
Kubernetes API->>CRDs: Registers new CRDs
User->>Kubernetes API: Deploy CSI controller (with snapshotter & controller)
Kubernetes API->>CSI Controller Pod: Start pod with csi-snapshotter & snapshot-controller
csi-snapshotter->>Kubernetes API: Watch VolumeSnapshot resources
snapshot-controller->>Kubernetes API: Manage snapshot lifecycle
Suggested labels
Suggested reviewers
Poem
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Summary of Changes
Hello klinch0, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request significantly enhances the storage capabilities of tenant Kubernetes clusters by integrating the Kubernetes Volume Snapshot feature. It deploys the essential CSI snapshotting components and their corresponding Custom Resource Definitions, allowing users to create, manage, and restore persistent volume snapshots.
Highlights
- Kubernetes Volume Snapshotting: I've added the necessary components to enable volume snapshotting capabilities within tenant Kubernetes clusters. This includes deploying the
csi-snapshotterandsnapshot-controller. - Volume Snapshot CRD Deployment: I've introduced a new HelmRelease (
volumesnapshot_crd.yaml) that manages the deployment of the Kubernetes Volume Snapshot Custom Resource Definitions (CRDs) into the tenant clusters. This ensures the cluster understands and can manageVolumeSnapshot,VolumeSnapshotContent, andVolumeSnapshotClassobjects. - CSI Snapshotter and Controller Integration: The
csi/deploy.yamlhas been updated to include thecsi-snapshotterandsnapshot-controllercontainers, configured to interact with the CSI driver and the Kubernetes API for snapshot operations.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | Gemini (@gemini-code-assist) | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Code Review
This pull request adds support for volume snapshots in tenant Kubernetes clusters by deploying the CSI snapshotter, snapshot-controller, and the necessary CRDs. The implementation is solid, but I've identified a few critical and high-severity issues. These include using incorrect image versions which would prevent pods from starting, missing resource definitions which could lead to cluster instability, and fetching dependencies from a master branch which is not recommended for production systems. Addressing these points will significantly improve the robustness and maintainability of the new functionality.
| env: | ||
| - name: ADDRESS | ||
| value: /csi/csi.sock | ||
| image: registry.k8s.io/sig-storage/csi-snapshotter:v8.2.1 |
There was a problem hiding this comment.
The image tag v8.2.1 for csi-snapshotter appears to be incorrect as it doesn't seem to exist in the registry.k8s.io/sig-storage repository. The latest stable version is v7.0.2. Using a non-existent tag will cause the pod to fail with an ImagePullBackOff error. Please use a valid and stable image tag.
image: registry.k8s.io/sig-storage/csi-snapshotter:v7.0.2
| name: kubeconfig | ||
| readOnly: true | ||
| - name: snapshot-controller | ||
| image: registry.k8s.io/sig-storage/snapshot-controller:v8.2.1 |
There was a problem hiding this comment.
The image tag v8.2.1 for snapshot-controller appears to be incorrect as it doesn't seem to exist in the registry.k8s.io/sig-storage repository. The latest stable version is v7.0.2. Using a non-existent tag will cause the pod to fail with an ImagePullBackOff error. Please use a valid and stable image tag.
image: registry.k8s.io/sig-storage/snapshot-controller:v7.0.2
| value: /csi/csi.sock | ||
| image: registry.k8s.io/sig-storage/csi-snapshotter:v8.2.1 | ||
| imagePullPolicy: IfNotPresent | ||
| resources: {} |
There was a problem hiding this comment.
It is highly recommended to define resource requests and limits for containers. Without them, the pod could be scheduled on a node with insufficient resources, or it could consume too many resources, affecting other workloads. Please provide appropriate resource settings, similar to other containers in this deployment.
resources:
requests:
cpu: 125m
memory: 128Mi
limits:
cpu: 512m
memory: 512Mi
| imagePullPolicy: IfNotPresent | ||
| volumeMounts: |
There was a problem hiding this comment.
The snapshot-controller container is missing resource definitions and a security context.
- Resources: It's crucial to set resource requests and limits to ensure pod stability and fair resource allocation on the node.
- Security Context: It's a good security practice to drop all capabilities and use a read-only root filesystem.
Please add these configurations, similar to the csi-snapshotter container.
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 125m
memory: 128Mi
limits:
cpu: 512m
memory: 512Mi
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
| wget -O ./templates/volumesnapshotclasses.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml | ||
| wget -O ./templates/volumesnapshotcontents.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml | ||
| wget -O ./templates/volumesnapshots.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml |
There was a problem hiding this comment.
Downloading CRDs from the master branch can lead to unexpected changes and break deployments. It is a best practice to pin dependencies to a specific, stable version. Please use a git tag for a stable release, for example v7.0.2 which is the latest stable release of external-snapshotter.
wget -O ./templates/volumesnapshotclasses.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v7.0.2/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
wget -O ./templates/volumesnapshotcontents.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v7.0.2/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
wget -O ./templates/volumesnapshots.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v7.0.2/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
| export NAME=victoria-metrics-operator | ||
| export NAMESPACE=cozy-$(NAME) |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (2)
packages/system/volumesnapshot-crd-for-tenant-k8s/Chart.yaml (1)
1-3: Add basic chart metadataThe chart will fail a standard
helm lintbecause mandatory informational fields are missing.
At minimum add:description: VolumeSnapshot CRDs for tenant clusters appVersion: "v8.2.1" # matches controller image tagConsider also bumping
versionto a sem-ver such as0.1.0; a0.0.0placeholder can trip up flux/helm version comparators.packages/apps/kubernetes/templates/csi/deploy.yaml (1)
162-171: No resource limits for snapshot componentsBoth snapshot containers run cluster-wide controllers; leaving resources empty can starve critical I/O paths on busy clusters.
resources: requests: cpu: 50m memory: 64Mi limits: cpu: 250m memory: 256Mi
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
packages/apps/kubernetes/templates/csi/deploy.yaml(1 hunks)packages/apps/kubernetes/templates/helmreleases/volumesnapshot_crd.yaml(1 hunks)packages/system/volumesnapshot-crd-for-tenant-k8s/Chart.yaml(1 hunks)packages/system/volumesnapshot-crd-for-tenant-k8s/Makefile(1 hunks)packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshotclasses.yaml(1 hunks)packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshotcontents.yaml(1 hunks)packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshots.yaml(1 hunks)
🧰 Additional context used
🪛 checkmake (0.2.2)
packages/system/volumesnapshot-crd-for-tenant-k8s/Makefile
[warning] 1-1: Missing required phony target "all"
(minphony)
[warning] 1-1: Missing required phony target "clean"
(minphony)
[warning] 1-1: Missing required phony target "test"
(minphony)
🪛 YAMLlint (1.37.1)
packages/apps/kubernetes/templates/csi/deploy.yaml
[warning] 139-139: wrong indentation: expected 12 but found 10
(indentation)
[warning] 144-144: wrong indentation: expected 12 but found 10
(indentation)
[warning] 152-152: wrong indentation: expected 16 but found 14
(indentation)
[warning] 157-157: wrong indentation: expected 12 but found 10
(indentation)
[warning] 169-169: wrong indentation: expected 12 but found 10
(indentation)
packages/apps/kubernetes/templates/helmreleases/volumesnapshot_crd.yaml
[error] 4-4: syntax error: expected , but found ''
(syntax)
🔇 Additional comments (2)
packages/apps/kubernetes/templates/helmreleases/volumesnapshot_crd.yaml (1)
34-39:dependsOntemplating can emit invalid YAMLIf the lookup returns nothing the first list item is omitted, but the surrounding indentation stays, producing:
dependsOn: - name:which breaks
Fluxreconciliation.Guard the whole field instead:
{{- $deps := list (dict "name" (printf "%s-cilium" .Release.Name) "namespace" .Release.Namespace) }} {{- if lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" .Release.Namespace .Release.Name }} {{- $deps = append (dict "name" .Release.Name "namespace" .Release.Namespace) $deps }} {{- end }} {{- if $deps }} dependsOn: {{- toYaml $deps | nindent 2 }} {{- end }}⛔ Skipped due to learnings
Learnt from: lllamnyp PR: cozystack/cozystack#1160 File: packages/system/hetzner-robotlb/charts/robotlb/templates/role.yaml:6-8 Timestamp: 2025-07-11T06:28:13.696Z Learning: In Helm templates, the `{{-` directive chomps all leading whitespace including newlines back to the previous content, so `{{- toYaml .Values.something | nindent 2 }}` will render correctly even with apparent indentation issues. However, for better style, it's cleaner to put the template directive on the same line as the parent key (e.g., `rules: {{- toYaml .Values.serviceAccount.permissions | nindent 2 }}`).packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshotclasses.yaml (1)
1-144: CRD version skewThe CRD was generated with controller-gen
v0.15.0(external-snapshotter master).
Your runtime images arev8.2.1; upstream tags bundle CRDs generated with that version. Mismatching generator versions occasionally introduces unknown fields that older apiservers reject (seen on v1.25-).Confirm the CRD hash in the release tag, or regenerate using the pinned tag suggested in the Makefile comment.
| update: | ||
| rm -rf templates | ||
| mkdir templates | ||
| wget -O ./templates/volumesnapshotclasses.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml | ||
| wget -O ./templates/volumesnapshotcontents.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml | ||
| wget -O ./templates/volumesnapshots.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Unpinned downloads & missing PHONY/utility targets
-
Downloading straight from
mastermeans your CRDs will silently drift whenever upstream changes. Pin to the same tag you run in the cluster (v8.2.1). -
Add
.PHONYplus commonall/clean/testtargets to silencecheckmakeand to aid maintainability.
-update:
- rm -rf templates
- mkdir templates
- wget -O ./templates/volumesnapshotclasses.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
- wget -O ./templates/volumesnapshotcontents.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
- wget -O ./templates/volumesnapshots.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
+.PHONY: update all clean
+
+TAG ?= v8.2.1
+
+update:
+ rm -rf templates && mkdir templates
+ for file in volumesnapshotclasses volumesnapshotcontents volumesnapshots; do \
+ wget -q -O ./templates/$${file}.yaml \
+ https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/$(TAG)/client/config/crd/snapshot.storage.k8s.io_$${file}.yaml ; \
+ done
+
+all: update
+clean:
+ rm -rf templates🤖 Prompt for AI Agents
In packages/system/volumesnapshot-crd-for-tenant-k8s/Makefile around lines 6 to
11, the wget commands download CRDs directly from the master branch, which can
cause silent drift when upstream changes. Fix this by pinning the URLs to a
specific tag version like v8.2.1 to ensure consistency. Additionally, add a
.PHONY target listing common targets such as all, clean, test, and update to
improve Makefile maintainability and silence checkmake warnings.
| - name: csi-snapshotter | ||
| args: | ||
| - --timeout=1m | ||
| - --csi-address=$(ADDRESS) | ||
| - --worker-threads=10 | ||
| - --kubeconfig=/etc/kubernetes/kubeconfig/super-admin.svc | ||
| env: | ||
| - name: ADDRESS | ||
| value: /csi/csi.sock | ||
| image: registry.k8s.io/sig-storage/csi-snapshotter:v8.2.1 | ||
| imagePullPolicy: IfNotPresent | ||
| resources: {} | ||
| securityContext: | ||
| capabilities: | ||
| drop: | ||
| - ALL | ||
| readOnlyRootFilesystem: true | ||
| terminationMessagePath: /dev/termination-log | ||
| terminationMessagePolicy: File | ||
| volumeMounts: | ||
| - mountPath: /csi | ||
| name: socket-dir | ||
| - mountPath: /etc/kubernetes/kubeconfig | ||
| name: kubeconfig | ||
| readOnly: true |
There was a problem hiding this comment.
Indentation & socket-path inconsistencies
YAML indentation is off by 2 spaces on multiple keys, which fails kubectl apply.
At the same time, the socket volume is mounted twice (/csi vs /var/lib/csi/sockets/pluginproxy). Align with the other side-cars to reduce confusion:
- - name: csi-snapshotter
- args:
- - --timeout=1m
- - --csi-address=$(ADDRESS)
+ - name: csi-snapshotter
+ args:
+ - --timeout=1m
+ - --csi-address=$(ADDRESS)
...
- - name: ADDRESS
- value: /csi/csi.sock
+ - name: ADDRESS
+ value: /var/lib/csi/sockets/pluginproxy/csi.sock
...
- - mountPath: /csi
- name: socket-dir
+ - mountPath: /var/lib/csi/sockets/pluginproxy
+ name: socket-dirApply the same indent fix to the subsequent snapshot-controller stanza.
After templating, run kubectl apply --dry-run=client -f deploy.yaml to catch structural issues early.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: csi-snapshotter | |
| args: | |
| - --timeout=1m | |
| - --csi-address=$(ADDRESS) | |
| - --worker-threads=10 | |
| - --kubeconfig=/etc/kubernetes/kubeconfig/super-admin.svc | |
| env: | |
| - name: ADDRESS | |
| value: /csi/csi.sock | |
| image: registry.k8s.io/sig-storage/csi-snapshotter:v8.2.1 | |
| imagePullPolicy: IfNotPresent | |
| resources: {} | |
| securityContext: | |
| capabilities: | |
| drop: | |
| - ALL | |
| readOnlyRootFilesystem: true | |
| terminationMessagePath: /dev/termination-log | |
| terminationMessagePolicy: File | |
| volumeMounts: | |
| - mountPath: /csi | |
| name: socket-dir | |
| - mountPath: /etc/kubernetes/kubeconfig | |
| name: kubeconfig | |
| readOnly: true | |
| - name: csi-snapshotter | |
| args: | |
| - --timeout=1m | |
| - --csi-address=$(ADDRESS) | |
| - --worker-threads=10 | |
| - --kubeconfig=/etc/kubernetes/kubeconfig/super-admin.svc | |
| env: | |
| - name: ADDRESS | |
| value: /var/lib/csi/sockets/pluginproxy/csi.sock | |
| image: registry.k8s.io/sig-storage/csi-snapshotter:v8.2.1 | |
| imagePullPolicy: IfNotPresent | |
| resources: {} | |
| securityContext: | |
| capabilities: | |
| drop: | |
| - ALL | |
| readOnlyRootFilesystem: true | |
| terminationMessagePath: /dev/termination-log | |
| terminationMessagePolicy: File | |
| volumeMounts: | |
| - mountPath: /var/lib/csi/sockets/pluginproxy | |
| name: socket-dir | |
| - mountPath: /etc/kubernetes/kubeconfig | |
| name: kubeconfig | |
| readOnly: true |
🧰 Tools
🪛 YAMLlint (1.37.1)
[warning] 139-139: wrong indentation: expected 12 but found 10
(indentation)
[warning] 144-144: wrong indentation: expected 12 but found 10
(indentation)
[warning] 152-152: wrong indentation: expected 16 but found 14
(indentation)
[warning] 157-157: wrong indentation: expected 12 but found 10
(indentation)
🤖 Prompt for AI Agents
In packages/apps/kubernetes/templates/csi/deploy.yaml between lines 137 and 161,
fix the YAML indentation by reducing it by 2 spaces on the affected keys to
comply with kubectl requirements. Also, unify the socket volume mount path to
match other sidecars by choosing either /csi or /var/lib/csi/sockets/pluginproxy
consistently, avoiding duplicate mounts. Apply the same indentation and socket
path corrections to the snapshot-controller section following this block.
Finally, validate the fixed YAML by running kubectl apply --dry-run=client -f
deploy.yaml to ensure no structural errors remain.
| subresources: | ||
| status: {} | ||
| - additionalPrinterColumns: | ||
| - description: Indicates if the snapshot is ready to be used to restore a volume. | ||
| jsonPath: .status.readyToUse | ||
| name: ReadyToUse | ||
| type: boolean | ||
| - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. | ||
| jsonPath: .spec.source.persistentVolumeClaimName | ||
| name: SourcePVC | ||
| type: string | ||
| - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. | ||
| jsonPath: .spec.source.volumeSnapshotContentName | ||
| name: SourceSnapshotContent | ||
| type: string | ||
| - description: Represents the minimum size of volume required to rehydrate from this snapshot. | ||
| jsonPath: .status.restoreSize | ||
| name: RestoreSize | ||
| type: string | ||
| - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. | ||
| jsonPath: .spec.volumeSnapshotClassName | ||
| name: SnapshotClass | ||
| type: string | ||
| - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. | ||
| jsonPath: .status.boundVolumeSnapshotContentName | ||
| name: SnapshotContent | ||
| type: string | ||
| - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. | ||
| jsonPath: .status.creationTime | ||
| name: CreationTime | ||
| type: date | ||
| - jsonPath: .metadata.creationTimestamp | ||
| name: Age | ||
| type: date | ||
| name: v1beta1 | ||
| # This indicates the v1beta1 version of the custom resource is deprecated. | ||
| # API requests to this version receive a warning in the server response. | ||
| deprecated: true | ||
| # This overrides the default warning returned to clients making v1beta1 API requests. | ||
| deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshot" | ||
| schema: | ||
| openAPIV3Schema: | ||
| description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. | ||
| properties: | ||
| apiVersion: | ||
| description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' | ||
| type: string | ||
| kind: | ||
| description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' | ||
| type: string | ||
| spec: | ||
| description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' | ||
| properties: | ||
| source: | ||
| description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. | ||
| properties: | ||
| persistentVolumeClaimName: | ||
| description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. | ||
| type: string | ||
| volumeSnapshotContentName: | ||
| description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. | ||
| type: string | ||
| type: object | ||
| volumeSnapshotClassName: | ||
| description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' | ||
| type: string | ||
| required: | ||
| - source | ||
| type: object | ||
| status: | ||
| description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. | ||
| properties: | ||
| boundVolumeSnapshotContentName: | ||
| description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' | ||
| type: string | ||
| creationTime: | ||
| description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. | ||
| format: date-time | ||
| type: string | ||
| error: | ||
| description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurs during the snapshot creation. Upon success, this error field will be cleared. | ||
| properties: | ||
| message: | ||
| description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' | ||
| type: string | ||
| time: | ||
| description: time is the timestamp when the error was encountered. | ||
| format: date-time | ||
| type: string | ||
| type: object | ||
| readyToUse: | ||
| description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. | ||
| type: boolean | ||
| restoreSize: | ||
| type: string | ||
| description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. | ||
| pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ | ||
| x-kubernetes-int-or-string: true | ||
| type: object | ||
| required: | ||
| - spec | ||
| type: object | ||
| served: false | ||
| storage: false | ||
| subresources: | ||
| status: {} | ||
| status: | ||
| acceptedNames: | ||
| kind: "" | ||
| plural: "" | ||
| conditions: [] | ||
| storedVersions: [] |
There was a problem hiding this comment.
Remove the top-level status: block – CRD creation will be rejected
status is a read-only sub-resource that the API server populates; clients are forbidden to set it on create/update of the main resource. Including it in the manifest leads to:
invalid: must not set status for: CustomResourceDefinition …
Delete the entire status: section before applying.
- status:
- acceptedNames:
- kind: ""
- plural: ""
- conditions: []
- storedVersions: []🤖 Prompt for AI Agents
In
packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshots.yaml
between lines 240 and 351, remove the entire top-level status: block at the end
of the file. This block is not allowed in the CRD manifest because status is a
read-only subresource managed by the API server and must not be set by clients
during creation or update. Deleting this section will prevent the "invalid: must
not set status" error when applying the CRD.
| - message: both spec.volumeSnapshotRef.name and spec.volumeSnapshotRef.namespace | ||
| must be set | ||
| rule: has(self.name) && has(self.__namespace__) | ||
| required: |
There was a problem hiding this comment.
Fix CEL validation – self.__namespace__ is invalid
The rule references a non-existent attribute __namespace__.
The correct field name is namespace:
- rule: has(self.name) && has(self.__namespace__)
+ rule: has(self.name) && has(self.namespace)Broken CEL prevents the CRD from registering.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - message: both spec.volumeSnapshotRef.name and spec.volumeSnapshotRef.namespace | |
| must be set | |
| rule: has(self.name) && has(self.__namespace__) | |
| required: | |
| - message: both spec.volumeSnapshotRef.name and spec.volumeSnapshotRef.namespace | |
| must be set | |
| rule: has(self.name) && has(self.namespace) | |
| required: |
🤖 Prompt for AI Agents
In
packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshotcontents.yaml
around lines 220 to 223, the CEL validation rule incorrectly uses
`self.__namespace__`, which is not a valid attribute. Replace
`self.__namespace__` with `self.namespace` in the rule to correctly reference
the namespace field and fix the validation so the CRD can register properly.
| served: false | ||
| storage: false | ||
| subresources: | ||
| status: {} | ||
| status: | ||
| acceptedNames: | ||
| kind: "" | ||
| plural: "" | ||
| conditions: [] | ||
| storedVersions: [] |
There was a problem hiding this comment.
Strip the status: block from the manifest
As with the previous CRD, specifying status on creation is forbidden and will cause the apply to fail. Remove the block:
- status:
- acceptedNames:
- kind: ""
- plural: ""
- conditions: []
- storedVersions: []📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| served: false | |
| storage: false | |
| subresources: | |
| status: {} | |
| status: | |
| acceptedNames: | |
| kind: "" | |
| plural: "" | |
| conditions: [] | |
| storedVersions: [] | |
| served: false | |
| storage: false | |
| subresources: | |
| status: {} |
🤖 Prompt for AI Agents
In
packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshotcontents.yaml
around lines 448 to 457, remove the entire status: block including
acceptedNames, conditions, and storedVersions fields. This block should not be
specified on creation as it is forbidden and causes the apply operation to fail.
67b1b0a to
dd6d0b6
Compare
Signed-off-by: kklinch0 <kklinch0@gmail.com>
dd6d0b6 to
d201e03
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (3)
packages/apps/kubernetes/templates/csi/deploy.yaml (1)
157-185: Socket path drift – side-cars can’t talk to the driverThe new
csi-snapshotteruses/csi/csi.sock, while the driver and the other
side-cars mount/var/lib/csi/sockets/pluginproxy/csi.sock.
A mismatch causes gRPC connection failures and the snapshotter will crash-loop.- - --csi-address=$(ADDRESS) - ... - - name: ADDRESS - value: /csi/csi.sock - volumeMounts: - - mountPath: /csi - name: socket-dir + - --csi-address=$(ADDRESS) + ... + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + volumeMounts: + - mountPath: /var/lib/csi/sockets/pluginproxy + name: socket-dirMirror the same path in the liveness-probe (lines 139-145) or drop the
duplicate mount entirely.packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshotcontents.yaml (2)
220-223: Broken CEL expression – usenamespace, not__namespace__
self.__namespace__is not a valid field and the CRD will be rejected by the
API server. Replace with the standardnamespace.- rule: has(self.name) && has(self.__namespace__) + rule: has(self.name) && has(self.namespace)
452-457:status:must be stripped from CRD manifestsThe
statusstanza is cluster-managed and forbidden on create/update.
Leaving it in causesinvalid: status: Forbiddenerrors during installation.-status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: []
🧹 Nitpick comments (2)
packages/system/volumesnapshot-crd-for-tenant-k8s/Makefile (1)
6-8: Add.PHONY+ helper targets to satisfycheckmakeand avoid accidental file collisions
all/clean/testare missing, triggering the static-analysis warnings and making the Makefile harder to use from CI.+.PHONY: all update clean test + +all: update + +clean: + rm -rf templates + +test: + @echo "Nothing to test – ensure CRDs render" # stubpackages/apps/kubernetes/templates/helmreleases/volumesnapshot_crd.yaml (1)
4-4: Wrap template expressions in quotes to avoid YAML syntax errorsUnquoted
{{ ... }}renders to e.g.tenant-volumesnapshot-crd-for-tenant-k8s.
If the release name ever contains a colon or other special chars, YAML will break.
Quoting also silences the YAML-lint error you’re seeing.- name: {{ .Release.Name }}-volumesnapshot-crd-for-tenant-k8s + name: "{{ .Release.Name }}-volumesnapshot-crd-for-tenant-k8s"Apply the same quoting pattern to other unquoted template values (lines 20-26, 34-39).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
packages/apps/kubernetes/templates/csi/deploy.yaml(4 hunks)packages/apps/kubernetes/templates/helmreleases/volumesnapshot_crd.yaml(1 hunks)packages/system/volumesnapshot-crd-for-tenant-k8s/Chart.yaml(1 hunks)packages/system/volumesnapshot-crd-for-tenant-k8s/Makefile(1 hunks)packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshotclass.yaml(1 hunks)packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshotclasses.yaml(1 hunks)packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshotcontents.yaml(1 hunks)packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshots.yaml(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshotclass.yaml
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/system/volumesnapshot-crd-for-tenant-k8s/Chart.yaml
- packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshotclasses.yaml
- packages/system/volumesnapshot-crd-for-tenant-k8s/templates/volumesnapshots.yaml
🧰 Additional context used
🧠 Learnings (1)
packages/apps/kubernetes/templates/csi/deploy.yaml (1)
Learnt from: lllamnyp
PR: cozystack/cozystack#1160
File: packages/system/hetzner-robotlb/charts/robotlb/templates/role.yaml:6-8
Timestamp: 2025-07-11T06:28:13.696Z
Learning: In Helm templates, the `{{-` directive chomps all leading whitespace including newlines back to the previous content, so `{{- toYaml .Values.something | nindent 2 }}` will render correctly even with apparent indentation issues. However, for better style, it's cleaner to put the template directive on the same line as the parent key (e.g., `rules: {{- toYaml .Values.serviceAccount.permissions | nindent 2 }}`).
🪛 YAMLlint (1.37.1)
packages/apps/kubernetes/templates/csi/deploy.yaml
[warning] 75-75: wrong indentation: expected 16 but found 14
(indentation)
[warning] 89-89: wrong indentation: expected 16 but found 14
(indentation)
[warning] 134-134: wrong indentation: expected 16 but found 14
(indentation)
[warning] 155-155: wrong indentation: expected 16 but found 14
(indentation)
[warning] 159-159: wrong indentation: expected 12 but found 10
(indentation)
[warning] 164-164: wrong indentation: expected 12 but found 10
(indentation)
[warning] 178-178: wrong indentation: expected 16 but found 14
(indentation)
[warning] 181-181: wrong indentation: expected 12 but found 10
(indentation)
[warning] 202-202: wrong indentation: expected 16 but found 14
(indentation)
[warning] 205-205: wrong indentation: expected 12 but found 10
(indentation)
packages/apps/kubernetes/templates/helmreleases/volumesnapshot_crd.yaml
[error] 4-4: syntax error: expected , but found ''
(syntax)
🪛 checkmake (0.2.2)
packages/system/volumesnapshot-crd-for-tenant-k8s/Makefile
[warning] 1-1: Missing required phony target "all"
(minphony)
[warning] 1-1: Missing required phony target "clean"
(minphony)
[warning] 1-1: Missing required phony target "test"
(minphony)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Install Cozystack
🔇 Additional comments (1)
packages/apps/kubernetes/templates/csi/deploy.yaml (1)
166-188: Image tag v8.3.0 is available
Bothregistry.k8s.io/sig-storage/csi-snapshotter:v8.3.0andsnapshot-controller:v8.3.0exist in the upstream registry. No further changes are needed.
| wget -O ./templates/volumesnapshotclasses.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/refs/tags/v8.3.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml | ||
| wget -O ./templates/volumesnapshotcontents.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/refs/tags/v8.3.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml | ||
| wget -O ./templates/volumesnapshots.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/refs/tags/v8.3.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml |
There was a problem hiding this comment.
Broken download URLs – refs/tags/ path 404s on raw.githubusercontent.com
raw.githubusercontent.com expects the tag directly (e.g. /v8.3.0/…).
refs/tags/v8.3.0 is interpreted as a directory hierarchy and returns 404, so the CRDs never land in templates/.
-wget -O ./templates/volumesnapshotclasses.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/refs/tags/v8.3.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
+wget -O ./templates/volumesnapshotclasses.yaml https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/v8.3.0/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
# …same fix for the two lines below…Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In packages/system/volumesnapshot-crd-for-tenant-k8s/Makefile lines 9 to 11, the
wget URLs use 'refs/tags/v8.3.0' which causes 404 errors on
raw.githubusercontent.com. Replace 'refs/tags/v8.3.0' with just 'v8.3.0' in each
URL to correctly reference the tag and ensure the files download properly into
the templates directory.
| securityContext: | ||
| capabilities: | ||
| drop: | ||
| - ALL | ||
| readOnlyRootFilesystem: true | ||
| - name: csi-provisioner |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Indentation off by 2 spaces – fails kubectl apply
Several securityContext blocks are indented 14 instead of 16 spaces.
Kubernetes is strict: one wrong indent → whole manifest rejected.
Run yamllint or kubectl apply --dry-run=client after fixing:
- securityContext:
- capabilities:
- drop:
- - ALL
+ securityContext:
+ capabilities:
+ drop:
+ - ALLRepeat for every highlighted block.
Also applies to: 86-90, 131-135, 152-156, 175-180, 199-203
🧰 Tools
🪛 YAMLlint (1.37.1)
[warning] 75-75: wrong indentation: expected 16 but found 14
(indentation)
🤖 Prompt for AI Agents
In packages/apps/kubernetes/templates/csi/deploy.yaml at lines 72 to 77, the
securityContext block is indented 14 spaces instead of the required 16, causing
kubectl apply to fail. Adjust the indentation of the securityContext and its
nested fields to be exactly 16 spaces. Repeat this correction for the similar
blocks at lines 86-90, 131-135, 152-156, 175-180, and 199-203. After fixing,
validate the YAML with yamllint or kubectl apply --dry-run=client to ensure
correctness.
Signed-off-by: Andrei Kvapil <kvapss@gmail.com> <!-- Thank you for making a contribution! Here are some tips for you: - Start the PR title with the [label] of Cozystack component: - For system components: [platform], [system], [linstor], [cilium], [kube-ovn], [dashboard], [cluster-api], etc. - For managed apps: [apps], [tenant], [kubernetes], [postgres], [virtual-machine] etc. - For development and maintenance: [tests], [ci], [docs], [maintenance]. - If it's a work in progress, consider creating this PR as a draft. - Don't hesistate to ask for opinion and review in the community chats, even if it's still a draft. - Add the label `backport` if it's a bugfix that needs to be backported to a previous version. --> ## What this PR does This PR fixes regression introduced by #1203 error: ``` Helm install failed for release cozy-volumesnapshot-crd-for-tenant-k8s/volumesnapshot-crd-for-tenant-k8s with chart cozy-volumesnapshot-crd-for-tenant-k8s@0.34.0: unable to build kubernetes objects from release manifest: resource mapping not found for name: "kubevirt-snapshots" namespace: "" from "": no matches for kind "VolumeSnapshotClass" in version "snapshot.storage.k8s.io/v1"... ``` ### Release note <!-- Write a release note: - Explain what has changed internally and for users. - Start with the same [label] as in the PR title - Follow the guidelines at https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md. --> ```release-note [kubernetes] fix volumesnapshotclass installation ```
Signed-off-by: Andrei Kvapil <kvapss@gmail.com> <!-- Thank you for making a contribution! Here are some tips for you: - Start the PR title with the [label] of Cozystack component: - For system components: [platform], [system], [linstor], [cilium], [kube-ovn], [dashboard], [cluster-api], etc. - For managed apps: [apps], [tenant], [kubernetes], [postgres], [virtual-machine] etc. - For development and maintenance: [tests], [ci], [docs], [maintenance]. - If it's a work in progress, consider creating this PR as a draft. - Don't hesistate to ask for opinion and review in the community chats, even if it's still a draft. - Add the label `backport` if it's a bugfix that needs to be backported to a previous version. --> ## What this PR does This PR fixes regression introduced by #1203 error: ``` Helm install failed for release cozy-volumesnapshot-crd-for-tenant-k8s/volumesnapshot-crd-for-tenant-k8s with chart cozy-volumesnapshot-crd-for-tenant-k8s@0.34.0: unable to build kubernetes objects from release manifest: resource mapping not found for name: "kubevirt-snapshots" namespace: "" from "": no matches for kind "VolumeSnapshotClass" in version "snapshot.storage.k8s.io/v1"... ``` ### Release note <!-- Write a release note: - Explain what has changed internally and for users. - Start with the same [label] as in the PR title - Follow the guidelines at https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md. --> ```release-note [kubernetes] fix volumesnapshotclass installation ```
What this PR does
Release note
Summary by CodeRabbit
New Features
VolumeSnapshot,VolumeSnapshotContent, andVolumeSnapshotClass.Chores