| 
									
										
										
										
											2021-05-23 13:31:02 +00:00
										 |  |  | import * as k8s from '@kubernetes/client-node'; | 
					
						
							| 
									
										
										
										
											2021-09-22 20:05:21 +00:00
										 |  |  | import { BuildParameters } from '../..'; | 
					
						
							| 
									
										
										
										
											2021-05-28 17:54:54 +00:00
										 |  |  | import * as core from '@actions/core'; | 
					
						
							| 
									
										
										
										
											2021-10-04 23:23:49 +00:00
										 |  |  | import { CloudRunnerProviderInterface } from '../services/cloud-runner-provider-interface'; | 
					
						
							|  |  |  | import CloudRunnerSecret from '../services/cloud-runner-secret'; | 
					
						
							| 
									
										
										
										
											2021-06-18 19:52:07 +00:00
										 |  |  | import KubernetesStorage from './kubernetes-storage'; | 
					
						
							| 
									
										
										
										
											2021-10-04 23:23:49 +00:00
										 |  |  | import CloudRunnerEnvironmentVariable from '../services/cloud-runner-environment-variable'; | 
					
						
							| 
									
										
										
										
											2021-06-19 23:06:44 +00:00
										 |  |  | import KubernetesLogging from './kubernetes-logging'; | 
					
						
							|  |  |  | import KubernetesSecret from './kubernetes-secret'; | 
					
						
							|  |  |  | import KubernetesUtilities from './kubernetes-utils'; | 
					
						
							| 
									
										
										
										
											2021-06-26 04:01:43 +00:00
										 |  |  | import waitUntil from 'async-wait-until'; | 
					
						
							| 
									
										
										
										
											2021-06-26 01:50:03 +00:00
										 |  |  | import KubernetesJobSpecFactory from './kubernetes-job-spec-factory'; | 
					
						
							| 
									
										
										
										
											2021-07-13 00:28:16 +00:00
										 |  |  | import KubernetesServiceAccount from './kubernetes-service-account'; | 
					
						
							| 
									
										
										
										
											2021-10-04 23:23:49 +00:00
										 |  |  | import CloudRunnerLogger from '../services/cloud-runner-logger'; | 
					
						
							| 
									
										
										
										
											2021-06-18 19:27:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-17 20:09:42 +00:00
										 |  |  | class Kubernetes implements CloudRunnerProviderInterface { | 
					
						
							| 
									
										
										
										
											2021-06-19 23:06:44 +00:00
										 |  |  |   private kubeConfig: k8s.KubeConfig; | 
					
						
							| 
									
										
										
										
											2021-06-06 19:39:06 +00:00
										 |  |  |   private kubeClient: k8s.CoreV1Api; | 
					
						
							|  |  |  |   private kubeClientBatch: k8s.BatchV1Api; | 
					
						
							| 
									
										
										
										
											2021-08-15 21:59:58 +00:00
										 |  |  |   private buildGuid: string = ''; | 
					
						
							| 
									
										
										
										
											2021-06-06 19:39:06 +00:00
										 |  |  |   private buildParameters: BuildParameters; | 
					
						
							| 
									
										
										
										
											2021-06-06 21:22:22 +00:00
										 |  |  |   private pvcName: string = ''; | 
					
						
							|  |  |  |   private secretName: string = ''; | 
					
						
							|  |  |  |   private jobName: string = ''; | 
					
						
							| 
									
										
										
										
											2021-06-06 19:39:06 +00:00
										 |  |  |   private namespace: string; | 
					
						
							| 
									
										
										
										
											2021-06-06 20:14:12 +00:00
										 |  |  |   private podName: string = ''; | 
					
						
							|  |  |  |   private containerName: string = ''; | 
					
						
							| 
									
										
										
										
											2021-06-26 01:50:03 +00:00
										 |  |  |   private cleanupCronJobName: string = ''; | 
					
						
							| 
									
										
										
										
											2021-07-13 00:28:16 +00:00
										 |  |  |   private serviceAccountName: string = ''; | 
					
						
							| 
									
										
										
										
											2021-06-26 01:50:03 +00:00
										 |  |  |   private kubeClientBatchBeta: k8s.BatchV1beta1Api; | 
					
						
							| 
									
										
										
										
											2021-03-13 23:44:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-19 20:35:22 +00:00
										 |  |  |   constructor(buildParameters: BuildParameters) { | 
					
						
							| 
									
										
										
										
											2021-06-26 01:50:03 +00:00
										 |  |  |     this.kubeConfig = new k8s.KubeConfig(); | 
					
						
							|  |  |  |     this.kubeConfig.loadFromDefault(); | 
					
						
							|  |  |  |     this.kubeClient = this.kubeConfig.makeApiClient(k8s.CoreV1Api); | 
					
						
							|  |  |  |     this.kubeClientBatch = this.kubeConfig.makeApiClient(k8s.BatchV1Api); | 
					
						
							|  |  |  |     this.kubeClientBatchBeta = this.kubeConfig.makeApiClient(k8s.BatchV1beta1Api); | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |     CloudRunnerLogger.log('Loaded default Kubernetes configuration for this environment'); | 
					
						
							| 
									
										
										
										
											2021-05-23 13:31:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-06 21:22:22 +00:00
										 |  |  |     this.namespace = 'default'; | 
					
						
							|  |  |  |     this.buildParameters = buildParameters; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-12-25 20:10:12 +00:00
										 |  |  |   public async setupSharedResources( | 
					
						
							| 
									
										
										
										
											2021-08-15 21:59:58 +00:00
										 |  |  |     buildGuid: string, | 
					
						
							| 
									
										
										
										
											2021-06-19 22:15:44 +00:00
										 |  |  |     buildParameters: BuildParameters, | 
					
						
							|  |  |  |     // eslint-disable-next-line no-unused-vars
 | 
					
						
							|  |  |  |     branchName: string, | 
					
						
							|  |  |  |     // eslint-disable-next-line no-unused-vars
 | 
					
						
							|  |  |  |     defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[], | 
					
						
							|  |  |  |   ) { | 
					
						
							| 
									
										
										
										
											2021-06-26 01:54:37 +00:00
										 |  |  |     try { | 
					
						
							| 
									
										
										
										
											2021-09-08 20:21:15 +00:00
										 |  |  |       this.pvcName = `unity-builder-pvc-${buildGuid}`; | 
					
						
							| 
									
										
										
										
											2021-08-15 21:59:58 +00:00
										 |  |  |       this.cleanupCronJobName = `unity-builder-cronjob-${buildGuid}`; | 
					
						
							|  |  |  |       this.serviceAccountName = `service-account-${buildGuid}`; | 
					
						
							| 
									
										
										
										
											2021-06-26 01:54:37 +00:00
										 |  |  |       await KubernetesStorage.createPersistentVolumeClaim( | 
					
						
							|  |  |  |         buildParameters, | 
					
						
							|  |  |  |         this.pvcName, | 
					
						
							|  |  |  |         this.kubeClient, | 
					
						
							|  |  |  |         this.namespace, | 
					
						
							|  |  |  |       ); | 
					
						
							| 
									
										
										
										
											2021-07-13 00:28:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       await KubernetesServiceAccount.createServiceAccount(this.serviceAccountName, this.namespace, this.kubeClient); | 
					
						
							| 
									
										
										
										
											2021-06-26 01:54:37 +00:00
										 |  |  |     } catch (error) { | 
					
						
							|  |  |  |       throw error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-19 22:15:44 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-25 20:10:12 +00:00
										 |  |  |   async runTask( | 
					
						
							| 
									
										
										
										
											2021-08-15 21:59:58 +00:00
										 |  |  |     buildGuid: string, | 
					
						
							| 
									
										
										
										
											2021-06-18 20:36:45 +00:00
										 |  |  |     image: string, | 
					
						
							| 
									
										
										
										
											2021-12-29 16:28:42 +00:00
										 |  |  |     commands: string, | 
					
						
							| 
									
										
										
										
											2021-06-18 20:36:45 +00:00
										 |  |  |     mountdir: string, | 
					
						
							|  |  |  |     workingdir: string, | 
					
						
							| 
									
										
										
										
											2021-08-17 22:13:46 +00:00
										 |  |  |     environment: CloudRunnerEnvironmentVariable[], | 
					
						
							|  |  |  |     secrets: CloudRunnerSecret[], | 
					
						
							| 
									
										
										
										
											2021-06-18 20:36:45 +00:00
										 |  |  |   ): Promise<void> { | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       // setup
 | 
					
						
							| 
									
										
										
										
											2021-08-15 21:59:58 +00:00
										 |  |  |       this.buildGuid = buildGuid; | 
					
						
							|  |  |  |       this.secretName = `build-credentials-${buildGuid}`; | 
					
						
							|  |  |  |       this.jobName = `unity-builder-job-${buildGuid}`; | 
					
						
							| 
									
										
										
										
											2021-09-15 03:35:57 +00:00
										 |  |  |       this.containerName = `main`; | 
					
						
							| 
									
										
										
										
											2021-06-19 23:06:44 +00:00
										 |  |  |       await KubernetesSecret.createSecret(secrets, this.secretName, this.namespace, this.kubeClient); | 
					
						
							| 
									
										
										
										
											2021-06-26 01:50:03 +00:00
										 |  |  |       const jobSpec = KubernetesJobSpecFactory.getJobSpec( | 
					
						
							|  |  |  |         commands, | 
					
						
							|  |  |  |         image, | 
					
						
							|  |  |  |         mountdir, | 
					
						
							|  |  |  |         workingdir, | 
					
						
							|  |  |  |         environment, | 
					
						
							| 
									
										
										
										
											2021-08-15 21:59:58 +00:00
										 |  |  |         this.buildGuid, | 
					
						
							| 
									
										
										
										
											2021-06-26 01:50:03 +00:00
										 |  |  |         this.buildParameters, | 
					
						
							|  |  |  |         this.secretName, | 
					
						
							|  |  |  |         this.pvcName, | 
					
						
							|  |  |  |         this.jobName, | 
					
						
							|  |  |  |         k8s, | 
					
						
							|  |  |  |       ); | 
					
						
							| 
									
										
										
										
											2021-06-18 20:36:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-19 04:27:24 +00:00
										 |  |  |       //run
 | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |       CloudRunnerLogger.log('Creating build job'); | 
					
						
							| 
									
										
										
										
											2021-06-19 04:27:24 +00:00
										 |  |  |       await this.kubeClientBatch.createNamespacedJob(this.namespace, jobSpec); | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |       CloudRunnerLogger.log('Job created'); | 
					
						
							| 
									
										
										
										
											2021-06-19 23:06:44 +00:00
										 |  |  |       this.setPodNameAndContainerName( | 
					
						
							|  |  |  |         await KubernetesUtilities.findPodFromJob(this.kubeClient, this.jobName, this.namespace), | 
					
						
							|  |  |  |       ); | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |       CloudRunnerLogger.log('Watching pod until running'); | 
					
						
							| 
									
										
										
										
											2021-06-19 23:06:44 +00:00
										 |  |  |       await KubernetesUtilities.watchUntilPodRunning(this.kubeClient, this.podName, this.namespace); | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |       CloudRunnerLogger.log('Pod running, streaming logs'); | 
					
						
							| 
									
										
										
										
											2021-06-19 23:06:44 +00:00
										 |  |  |       await KubernetesLogging.streamLogs( | 
					
						
							|  |  |  |         this.kubeConfig, | 
					
						
							|  |  |  |         this.kubeClient, | 
					
						
							|  |  |  |         this.jobName, | 
					
						
							|  |  |  |         this.podName, | 
					
						
							| 
									
										
										
										
											2021-09-15 04:35:56 +00:00
										 |  |  |         'main', | 
					
						
							| 
									
										
										
										
											2021-06-19 23:06:44 +00:00
										 |  |  |         this.namespace, | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |         CloudRunnerLogger.log, | 
					
						
							| 
									
										
										
										
											2021-06-19 23:06:44 +00:00
										 |  |  |       ); | 
					
						
							|  |  |  |       await this.cleanupTaskResources(); | 
					
						
							| 
									
										
										
										
											2021-06-18 20:36:45 +00:00
										 |  |  |     } catch (error) { | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |       CloudRunnerLogger.log('Running job failed'); | 
					
						
							| 
									
										
										
										
											2021-06-19 20:35:22 +00:00
										 |  |  |       core.error(JSON.stringify(error, undefined, 4)); | 
					
						
							| 
									
										
										
										
											2021-06-19 23:06:44 +00:00
										 |  |  |       await this.cleanupTaskResources(); | 
					
						
							| 
									
										
										
										
											2021-06-06 20:10:01 +00:00
										 |  |  |       throw error; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-05-23 14:26:57 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-06 21:22:22 +00:00
										 |  |  |   setPodNameAndContainerName(pod: k8s.V1Pod) { | 
					
						
							|  |  |  |     this.podName = pod.metadata?.name || ''; | 
					
						
							|  |  |  |     this.containerName = pod.status?.containerStatuses?.[0].name || ''; | 
					
						
							| 
									
										
										
										
											2021-05-28 17:37:30 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-19 23:06:44 +00:00
										 |  |  |   async cleanupTaskResources() { | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |     CloudRunnerLogger.log('cleaning up'); | 
					
						
							| 
									
										
										
										
											2021-06-18 22:20:04 +00:00
										 |  |  |     try { | 
					
						
							|  |  |  |       await this.kubeClientBatch.deleteNamespacedJob(this.jobName, this.namespace); | 
					
						
							|  |  |  |       await this.kubeClient.deleteNamespacedSecret(this.secretName, this.namespace); | 
					
						
							|  |  |  |     } catch (error) { | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |       CloudRunnerLogger.log('Failed to cleanup, error:'); | 
					
						
							| 
									
										
										
										
											2021-06-18 22:20:04 +00:00
										 |  |  |       core.error(JSON.stringify(error, undefined, 4)); | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |       CloudRunnerLogger.log('Abandoning cleanup, build error:'); | 
					
						
							| 
									
										
										
										
											2021-06-26 03:27:42 +00:00
										 |  |  |       throw error; | 
					
						
							| 
									
										
										
										
											2021-06-18 22:20:04 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-06-26 04:01:43 +00:00
										 |  |  |     try { | 
					
						
							|  |  |  |       await waitUntil( | 
					
						
							|  |  |  |         async () => (await this.kubeClientBatch.readNamespacedJob(this.jobName, this.namespace)).body === null, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           timeout: 500000, | 
					
						
							|  |  |  |           intervalBetweenAttempts: 15000, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } catch { | 
					
						
							| 
									
										
										
										
											2021-09-21 18:27:04 +00:00
										 |  |  |       CloudRunnerLogger.log('failed to read the state of the job while cleaning up?'); | 
					
						
							| 
									
										
										
										
											2021-06-26 04:01:43 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-05-23 15:08:32 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-06-19 23:06:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-25 20:10:12 +00:00
										 |  |  |   async cleanupSharedResources( | 
					
						
							| 
									
										
										
										
											2021-06-19 23:06:44 +00:00
										 |  |  |     // eslint-disable-next-line no-unused-vars
 | 
					
						
							| 
									
										
										
										
											2021-08-15 21:59:58 +00:00
										 |  |  |     buildGuid: string, | 
					
						
							| 
									
										
										
										
											2021-06-19 23:06:44 +00:00
										 |  |  |     // eslint-disable-next-line no-unused-vars
 | 
					
						
							|  |  |  |     buildParameters: BuildParameters, | 
					
						
							|  |  |  |     // eslint-disable-next-line no-unused-vars
 | 
					
						
							|  |  |  |     branchName: string, | 
					
						
							|  |  |  |     // eslint-disable-next-line no-unused-vars
 | 
					
						
							|  |  |  |     defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[], | 
					
						
							|  |  |  |   ) { | 
					
						
							|  |  |  |     await this.kubeClient.deleteNamespacedPersistentVolumeClaim(this.pvcName, this.namespace); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-09 19:27:47 +00:00
										 |  |  | } | 
					
						
							|  |  |  | export default Kubernetes; |