unity-builder/src/model/cloud-runner/kubernetes-storage.ts

67 lines
2.4 KiB
TypeScript

import waitUntil from 'async-wait-until';
import * as core from '@actions/core';
import * as k8s from '@kubernetes/client-node';
import BuildParameters from '../build-parameters';
class KubernetesStorage {
public static async getPVCPhase(kubeClient: k8s.CoreV1Api, name: string, namespace: string) {
return (await kubeClient.readNamespacedPersistentVolumeClaim(name, namespace)).body.status?.phase;
}
public static async watchUntilPVCNotPending(kubeClient: k8s.CoreV1Api, name: string, namespace: string) {
core.info(`watch Until PVC Not Pending ${name} ${namespace}`);
core.info(`${await this.getPVCPhase(kubeClient, name, namespace)}`);
await waitUntil(async () => (await this.getPVCPhase(kubeClient, name, namespace)) !== 'Pending', {
timeout: 500000,
intervalBetweenAttempts: 15000,
});
}
public static async createPersistentVolumeClaim(
buildParameters: BuildParameters,
pvcName: string,
kubeClient: k8s.CoreV1Api,
namespace: string,
) {
if (buildParameters.kubeVolume) {
core.info(buildParameters.kubeVolume);
pvcName = buildParameters.kubeVolume;
return;
}
const pvcList = (await kubeClient.listNamespacedPersistentVolumeClaim(namespace)).body.items.map(
(x) => x.metadata?.name,
);
core.info(`Current PVCs in namespace ${namespace}`);
core.info(JSON.stringify(pvcList, undefined, 4));
if (pvcList.includes(pvcName)) {
core.info(`pvc ${pvcName} already exists`);
core.setOutput('volume', pvcName);
return;
}
core.info(`Creating PVC ${pvcName} (does not exist)`);
const pvc = new k8s.V1PersistentVolumeClaim();
pvc.apiVersion = 'v1';
pvc.kind = 'PersistentVolumeClaim';
pvc.metadata = {
name: pvcName,
};
pvc.spec = {
accessModes: ['ReadWriteMany'],
volumeMode: 'Filesystem',
resources: {
requests: {
storage: buildParameters.kubeVolumeSize,
},
},
};
const result = await kubeClient.createNamespacedPersistentVolumeClaim(namespace, pvc);
const name = result.body.metadata?.name;
if (!name) throw new Error('failed to create PVC');
core.info(`PVC ${name} created`);
await this.watchUntilPVCNotPending(kubeClient, name, namespace);
core.info(`PVC ${name} is ready and not pending`);
core.setOutput('volume', pvcName);
}
}
export default KubernetesStorage;