| 
									
										
										
										
											2021-06-18 19:52:07 +00:00
										 |  |  | import waitUntil from 'async-wait-until'; | 
					
						
							|  |  |  | import * as core from '@actions/core'; | 
					
						
							|  |  |  | import * as k8s from '@kubernetes/client-node'; | 
					
						
							| 
									
										
										
										
											2021-09-22 20:05:21 +00:00
										 |  |  | import BuildParameters from '../../build-parameters'; | 
					
						
							| 
									
										
										
										
											2021-10-04 23:23:49 +00:00
										 |  |  | import CloudRunnerLogger from '../services/cloud-runner-logger'; | 
					
						
							| 
									
										
										
										
											2021-06-18 19:52:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | class KubernetesStorage { | 
					
						
							| 
									
										
										
										
											2021-06-18 20:12:06 +00:00
										 |  |  |   public static async createPersistentVolumeClaim( | 
					
						
							|  |  |  |     buildParameters: BuildParameters, | 
					
						
							|  |  |  |     pvcName: string, | 
					
						
							|  |  |  |     kubeClient: k8s.CoreV1Api, | 
					
						
							|  |  |  |     namespace: string, | 
					
						
							|  |  |  |   ) { | 
					
						
							| 
									
										
										
										
											2021-06-18 19:52:07 +00:00
										 |  |  |     if (buildParameters.kubeVolume) { | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |       CloudRunnerLogger.log(buildParameters.kubeVolume); | 
					
						
							| 
									
										
										
										
											2021-06-18 19:52:07 +00:00
										 |  |  |       pvcName = buildParameters.kubeVolume; | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-17 17:12:13 +00:00
										 |  |  |     const pvcList = (await kubeClient.listNamespacedPersistentVolumeClaim(namespace)).body.items.map( | 
					
						
							|  |  |  |       (x) => x.metadata?.name, | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |     CloudRunnerLogger.log(`Current PVCs in namespace ${namespace}`); | 
					
						
							|  |  |  |     CloudRunnerLogger.log(JSON.stringify(pvcList, undefined, 4)); | 
					
						
							| 
									
										
										
										
											2021-08-20 03:19:00 +00:00
										 |  |  |     if (pvcList.includes(pvcName)) { | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |       CloudRunnerLogger.log(`pvc ${pvcName} already exists`); | 
					
						
							| 
									
										
										
										
											2021-08-17 17:12:13 +00:00
										 |  |  |       core.setOutput('volume', pvcName); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |     CloudRunnerLogger.log(`Creating PVC ${pvcName} (does not exist)`); | 
					
						
							| 
									
										
										
										
											2021-08-21 19:49:52 +00:00
										 |  |  |     const result = await KubernetesStorage.createPVC(pvcName, buildParameters, kubeClient, namespace); | 
					
						
							|  |  |  |     await KubernetesStorage.handleResult(result, kubeClient, namespace, pvcName); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public static async getPVCPhase(kubeClient: k8s.CoreV1Api, name: string, namespace: string) { | 
					
						
							| 
									
										
										
										
											2021-09-15 03:20:04 +00:00
										 |  |  |     try { | 
					
						
							|  |  |  |       return (await kubeClient.readNamespacedPersistentVolumeClaim(name, namespace)).body.status?.phase; | 
					
						
							|  |  |  |     } catch (error) { | 
					
						
							|  |  |  |       core.error('Failed to get PVC phase'); | 
					
						
							|  |  |  |       core.error(JSON.stringify(error, undefined, 4)); | 
					
						
							|  |  |  |       throw error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-21 19:49:52 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public static async watchUntilPVCNotPending(kubeClient: k8s.CoreV1Api, name: string, namespace: string) { | 
					
						
							| 
									
										
										
										
											2021-09-15 03:20:04 +00:00
										 |  |  |     try { | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |       CloudRunnerLogger.log(`watch Until PVC Not Pending ${name} ${namespace}`); | 
					
						
							|  |  |  |       CloudRunnerLogger.log(`${await this.getPVCPhase(kubeClient, name, namespace)}`); | 
					
						
							| 
									
										
										
										
											2021-09-15 03:20:04 +00:00
										 |  |  |       await waitUntil( | 
					
						
							|  |  |  |         async () => { | 
					
						
							|  |  |  |           return (await this.getPVCPhase(kubeClient, name, namespace)) !== 'Pending'; | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           timeout: 500000, | 
					
						
							|  |  |  |           intervalBetweenAttempts: 15000, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } catch (error) { | 
					
						
							|  |  |  |       core.error('Failed to watch PVC'); | 
					
						
							|  |  |  |       core.error(JSON.stringify(error, undefined, 4)); | 
					
						
							|  |  |  |       core.error( | 
					
						
							|  |  |  |         `PVC Body: ${JSON.stringify( | 
					
						
							|  |  |  |           (await kubeClient.readNamespacedPersistentVolumeClaim(name, namespace)).body, | 
					
						
							|  |  |  |           undefined, | 
					
						
							|  |  |  |           4, | 
					
						
							|  |  |  |         )}`,
 | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |       throw error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-21 19:49:52 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private static async createPVC( | 
					
						
							|  |  |  |     pvcName: string, | 
					
						
							|  |  |  |     buildParameters: BuildParameters, | 
					
						
							|  |  |  |     kubeClient: k8s.CoreV1Api, | 
					
						
							|  |  |  |     namespace: string, | 
					
						
							|  |  |  |   ) { | 
					
						
							| 
									
										
										
										
											2021-06-18 19:52:07 +00:00
										 |  |  |     const pvc = new k8s.V1PersistentVolumeClaim(); | 
					
						
							|  |  |  |     pvc.apiVersion = 'v1'; | 
					
						
							|  |  |  |     pvc.kind = 'PersistentVolumeClaim'; | 
					
						
							|  |  |  |     pvc.metadata = { | 
					
						
							|  |  |  |       name: pvcName, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     pvc.spec = { | 
					
						
							| 
									
										
										
										
											2021-09-08 20:21:15 +00:00
										 |  |  |       accessModes: ['ReadWriteOnce'], | 
					
						
							| 
									
										
										
										
											2021-09-15 03:20:04 +00:00
										 |  |  |       storageClassName: process.env.K8s_STORAGE_CLASS || 'standard', | 
					
						
							| 
									
										
										
										
											2021-06-18 19:52:07 +00:00
										 |  |  |       resources: { | 
					
						
							|  |  |  |         requests: { | 
					
						
							|  |  |  |           storage: buildParameters.kubeVolumeSize, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2021-06-18 22:55:48 +00:00
										 |  |  |     const result = await kubeClient.createNamespacedPersistentVolumeClaim(namespace, pvc); | 
					
						
							| 
									
										
										
										
											2021-08-21 19:49:52 +00:00
										 |  |  |     return result; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private static async handleResult( | 
					
						
							|  |  |  |     result: { response: import('http').IncomingMessage; body: k8s.V1PersistentVolumeClaim }, | 
					
						
							|  |  |  |     kubeClient: k8s.CoreV1Api, | 
					
						
							|  |  |  |     namespace: string, | 
					
						
							|  |  |  |     pvcName: string, | 
					
						
							|  |  |  |   ) { | 
					
						
							| 
									
										
										
										
											2021-12-29 15:33:07 +00:00
										 |  |  |     const name = result.body.metadata?.name || ''; | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |     CloudRunnerLogger.log(`PVC ${name} created`); | 
					
						
							| 
									
										
										
										
											2021-08-21 19:14:17 +00:00
										 |  |  |     await this.watchUntilPVCNotPending(kubeClient, name, namespace); | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |     CloudRunnerLogger.log(`PVC ${name} is ready and not pending`); | 
					
						
							| 
									
										
										
										
											2021-06-19 20:06:11 +00:00
										 |  |  |     core.setOutput('volume', pvcName); | 
					
						
							| 
									
										
										
										
											2021-06-18 19:52:07 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default KubernetesStorage; |