Files
operator/src/resources/core/pvc/pvc.ts
Morten Olsen cfd2d76873 more
2025-08-20 22:45:30 +02:00

81 lines
2.6 KiB
TypeScript

import type { V1PersistentVolumeClaim } from '@kubernetes/client-node';
import { StorageClass } from '../storage-class/storage-class.ts';
import { PersistentVolume } from '../pv/pv.ts';
import { Resource, ResourceService, type ResourceOptions } from '#services/resources/resources.ts';
const PROVISIONER = 'homelab-operator';
class PVC extends Resource<V1PersistentVolumeClaim> {
public static readonly apiVersion = 'v1';
public static readonly kind = 'PersistentVolumeClaim';
constructor(options: ResourceOptions<V1PersistentVolumeClaim>) {
super(options);
this.on('changed', this.reconcile);
}
public reconcile = async () => {
const storageClassName = this.spec?.storageClassName;
console.log('PVC', this.name, storageClassName);
if (!storageClassName) {
return;
}
const resourceService = this.services.get(ResourceService);
const storageClass = resourceService.get(StorageClass, storageClassName);
if (!storageClass.exists || storageClass.manifest?.provisioner !== PROVISIONER) {
return;
}
if (this.status?.phase === 'Pending' && !this.spec?.volumeName) {
await this.#provisionVolume(storageClass);
}
};
#provisionVolume = async (storageClass: StorageClass) => {
const pvName = `pv-${this.namespace}-${this.name}`;
const storageLocation = storageClass.manifest?.parameters?.storageLocation || '/data/volumes';
const target = `${storageLocation}/${this.namespace}/${this.name}`;
const resourceService = this.services.get(ResourceService);
const pv = resourceService.get(PersistentVolume, pvName);
await pv.ensure({
metadata: {
name: pvName,
labels: {
provisioner: PROVISIONER,
'pvc-namespace': this.namespace || 'default',
'pvc-name': this.name || 'unknown',
},
annotations: {
'pv.kubernetes.io/provisioned-by': PROVISIONER,
},
},
spec: {
hostPath: {
path: target,
type: 'DirectoryOrCreate',
},
capacity: {
storage: this.spec?.resources?.requests?.storage ?? '1Gi',
},
persistentVolumeReclaimPolicy: 'Retain',
accessModes: this.spec?.accessModes ?? ['ReadWriteOnce'],
storageClassName: this.spec?.storageClassName,
claimRef: {
uid: this.metadata?.uid,
resourceVersion: this.metadata?.resourceVersion,
apiVersion: this.apiVersion,
kind: 'PersistentVolumeClaim',
name: this.name,
namespace: this.namespace,
},
},
});
};
}
export { PVC, PROVISIONER };