cronjob
parent
f3cbb79e40
commit
ebfa50648e
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1078,6 +1078,31 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
IN THE SOFTWARE.
|
IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
cron-converter
|
||||||
|
MIT
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-2016 Rouslan Placella (https://github.com/roccivic)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
cross-spawn
|
cross-spawn
|
||||||
MIT
|
MIT
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
@ -2204,6 +2229,55 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
moment
|
||||||
|
MIT
|
||||||
|
Copyright (c) JS Foundation and other contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person
|
||||||
|
obtaining a copy of this software and associated documentation
|
||||||
|
files (the "Software"), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use,
|
||||||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
moment-timezone
|
||||||
|
MIT
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) JS Foundation and other contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
nanoid
|
nanoid
|
||||||
MIT
|
MIT
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
@ -2967,6 +3041,34 @@ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
sprintf-js
|
||||||
|
BSD-3-Clause
|
||||||
|
Copyright (c) 2007-present, Alexandru Mărășteanu <hello@alexei.ro>
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of this software nor the names of its contributors may be
|
||||||
|
used to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
sshpk
|
sshpk
|
||||||
MIT
|
MIT
|
||||||
Copyright Joyent, Inc. All rights reserved.
|
Copyright Joyent, Inc. All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
"async-wait-until": "^2.0.7",
|
"async-wait-until": "^2.0.7",
|
||||||
"aws-sdk": "^2.812.0",
|
"aws-sdk": "^2.812.0",
|
||||||
"base-64": "^1.0.0",
|
"base-64": "^1.0.0",
|
||||||
|
"cron-converter": "^1.0.1",
|
||||||
"nanoid": "3.1.20",
|
"nanoid": "3.1.20",
|
||||||
"semver": "^7.3.2"
|
"semver": "^7.3.2"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ import KubernetesLogging from './kubernetes-logging';
|
||||||
import KubernetesSecret from './kubernetes-secret';
|
import KubernetesSecret from './kubernetes-secret';
|
||||||
import KubernetesUtilities from './kubernetes-utils';
|
import KubernetesUtilities from './kubernetes-utils';
|
||||||
import waitUntil from 'async-wait-until';
|
import waitUntil from 'async-wait-until';
|
||||||
|
import KubernetesJobSpecFactory from './kubernetes-job-spec-factory';
|
||||||
|
import KubernetesCleanupCronJob from './kubernetes-cleanup-cronjob';
|
||||||
|
|
||||||
class Kubernetes implements RemoteBuilderProviderInterface {
|
class Kubernetes implements RemoteBuilderProviderInterface {
|
||||||
private kubeConfig: k8s.KubeConfig;
|
private kubeConfig: k8s.KubeConfig;
|
||||||
|
|
@ -22,18 +24,17 @@ class Kubernetes implements RemoteBuilderProviderInterface {
|
||||||
private namespace: string;
|
private namespace: string;
|
||||||
private podName: string = '';
|
private podName: string = '';
|
||||||
private containerName: string = '';
|
private containerName: string = '';
|
||||||
|
private cleanupCronJobName: string = '';
|
||||||
|
private kubeClientBatchBeta: k8s.BatchV1beta1Api;
|
||||||
|
|
||||||
constructor(buildParameters: BuildParameters) {
|
constructor(buildParameters: BuildParameters) {
|
||||||
const kc = new k8s.KubeConfig();
|
this.kubeConfig = new k8s.KubeConfig();
|
||||||
kc.loadFromDefault();
|
this.kubeConfig.loadFromDefault();
|
||||||
const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
|
this.kubeClient = this.kubeConfig.makeApiClient(k8s.CoreV1Api);
|
||||||
const k8sBatchApi = kc.makeApiClient(k8s.BatchV1Api);
|
this.kubeClientBatch = this.kubeConfig.makeApiClient(k8s.BatchV1Api);
|
||||||
|
this.kubeClientBatchBeta = this.kubeConfig.makeApiClient(k8s.BatchV1beta1Api);
|
||||||
core.info('Loaded default Kubernetes configuration for this environment');
|
core.info('Loaded default Kubernetes configuration for this environment');
|
||||||
|
|
||||||
this.kubeConfig = kc;
|
|
||||||
this.kubeClient = k8sApi;
|
|
||||||
this.kubeClientBatch = k8sBatchApi;
|
|
||||||
|
|
||||||
this.namespace = 'default';
|
this.namespace = 'default';
|
||||||
this.buildParameters = buildParameters;
|
this.buildParameters = buildParameters;
|
||||||
}
|
}
|
||||||
|
|
@ -45,9 +46,14 @@ class Kubernetes implements RemoteBuilderProviderInterface {
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[],
|
defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[],
|
||||||
) {
|
) {
|
||||||
const pvcName = `unity-builder-pvc-${buildUid}`;
|
this.pvcName = `unity-builder-pvc-${buildUid}`;
|
||||||
this.pvcName = pvcName;
|
this.cleanupCronJobName = `unity-builder-cronjob-${buildUid}`;
|
||||||
await KubernetesStorage.createPersistentVolumeClaim(buildParameters, this.pvcName, this.kubeClient, this.namespace);
|
await KubernetesStorage.createPersistentVolumeClaim(buildParameters, this.pvcName, this.kubeClient, this.namespace);
|
||||||
|
await KubernetesCleanupCronJob.createCleanupCronJob(
|
||||||
|
this.kubeClientBatchBeta,
|
||||||
|
this.cleanupCronJobName,
|
||||||
|
this.namespace,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async runBuildTask(
|
async runBuildTask(
|
||||||
|
|
@ -65,7 +71,19 @@ class Kubernetes implements RemoteBuilderProviderInterface {
|
||||||
this.secretName = `build-credentials-${buildId}`;
|
this.secretName = `build-credentials-${buildId}`;
|
||||||
this.jobName = `unity-builder-job-${buildId}`;
|
this.jobName = `unity-builder-job-${buildId}`;
|
||||||
await KubernetesSecret.createSecret(secrets, this.secretName, this.namespace, this.kubeClient);
|
await KubernetesSecret.createSecret(secrets, this.secretName, this.namespace, this.kubeClient);
|
||||||
const jobSpec = this.getJobSpec(commands, image, mountdir, workingdir, environment);
|
const jobSpec = KubernetesJobSpecFactory.getJobSpec(
|
||||||
|
commands,
|
||||||
|
image,
|
||||||
|
mountdir,
|
||||||
|
workingdir,
|
||||||
|
environment,
|
||||||
|
this.buildId,
|
||||||
|
this.buildParameters,
|
||||||
|
this.secretName,
|
||||||
|
this.pvcName,
|
||||||
|
this.jobName,
|
||||||
|
k8s,
|
||||||
|
);
|
||||||
|
|
||||||
//run
|
//run
|
||||||
core.info('Creating build job');
|
core.info('Creating build job');
|
||||||
|
|
@ -97,144 +115,6 @@ class Kubernetes implements RemoteBuilderProviderInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getJobSpec(
|
|
||||||
command: string[],
|
|
||||||
image: string,
|
|
||||||
mountdir: string,
|
|
||||||
workingDirectory: string,
|
|
||||||
environment: RemoteBuilderEnvironmentVariable[],
|
|
||||||
) {
|
|
||||||
environment.push(
|
|
||||||
...[
|
|
||||||
{
|
|
||||||
name: 'GITHUB_SHA',
|
|
||||||
value: this.buildId,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GITHUB_WORKSPACE',
|
|
||||||
value: '/data/repo',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'PROJECT_PATH',
|
|
||||||
value: this.buildParameters.projectPath,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_PATH',
|
|
||||||
value: this.buildParameters.buildPath,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_FILE',
|
|
||||||
value: this.buildParameters.buildFile,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_NAME',
|
|
||||||
value: this.buildParameters.buildName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_METHOD',
|
|
||||||
value: this.buildParameters.buildMethod,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'CUSTOM_PARAMETERS',
|
|
||||||
value: this.buildParameters.customParameters,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'CHOWN_FILES_TO',
|
|
||||||
value: this.buildParameters.chownFilesTo,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'BUILD_TARGET',
|
|
||||||
value: this.buildParameters.platform,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ANDROID_VERSION_CODE',
|
|
||||||
value: this.buildParameters.androidVersionCode.toString(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ANDROID_KEYSTORE_NAME',
|
|
||||||
value: this.buildParameters.androidKeystoreName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'ANDROID_KEYALIAS_NAME',
|
|
||||||
value: this.buildParameters.androidKeyaliasName,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
|
||||||
const job = new k8s.V1Job();
|
|
||||||
job.apiVersion = 'batch/v1';
|
|
||||||
job.kind = 'Job';
|
|
||||||
job.metadata = {
|
|
||||||
name: this.jobName,
|
|
||||||
labels: {
|
|
||||||
app: 'unity-builder',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
job.spec = {
|
|
||||||
backoffLimit: 1,
|
|
||||||
template: {
|
|
||||||
spec: {
|
|
||||||
volumes: [
|
|
||||||
{
|
|
||||||
name: 'build-mount',
|
|
||||||
persistentVolumeClaim: {
|
|
||||||
claimName: this.pvcName,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'credentials',
|
|
||||||
secret: {
|
|
||||||
secretName: this.secretName,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
containers: [
|
|
||||||
{
|
|
||||||
name: 'main',
|
|
||||||
image,
|
|
||||||
command: ['/bin/sh'],
|
|
||||||
args: ['-c', ...command],
|
|
||||||
|
|
||||||
workingDir: `/${workingDirectory}`,
|
|
||||||
resources: {
|
|
||||||
requests: {
|
|
||||||
memory: this.buildParameters.remoteBuildMemory,
|
|
||||||
cpu: this.buildParameters.remoteBuildCpu,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
env: environment,
|
|
||||||
volumeMounts: [
|
|
||||||
{
|
|
||||||
name: 'build-mount',
|
|
||||||
mountPath: `/${mountdir}`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'credentials',
|
|
||||||
mountPath: '/credentials',
|
|
||||||
readOnly: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
lifecycle: {
|
|
||||||
preStop: {
|
|
||||||
exec: {
|
|
||||||
command: [
|
|
||||||
'bin/bash',
|
|
||||||
'-c',
|
|
||||||
`cd /data/builder/action/steps;
|
|
||||||
chmod +x /return_license.sh;
|
|
||||||
/return_license.sh;`,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
restartPolicy: 'Never',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return job;
|
|
||||||
}
|
|
||||||
|
|
||||||
setPodNameAndContainerName(pod: k8s.V1Pod) {
|
setPodNameAndContainerName(pod: k8s.V1Pod) {
|
||||||
this.podName = pod.metadata?.name || '';
|
this.podName = pod.metadata?.name || '';
|
||||||
this.containerName = pod.status?.containerStatuses?.[0].name || '';
|
this.containerName = pod.status?.containerStatuses?.[0].name || '';
|
||||||
|
|
@ -270,6 +150,7 @@ class Kubernetes implements RemoteBuilderProviderInterface {
|
||||||
defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[],
|
defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[],
|
||||||
) {
|
) {
|
||||||
await this.kubeClient.deleteNamespacedPersistentVolumeClaim(this.pvcName, this.namespace);
|
await this.kubeClient.deleteNamespacedPersistentVolumeClaim(this.pvcName, this.namespace);
|
||||||
|
await KubernetesCleanupCronJob.cleanup(this.kubeClientBatchBeta, this.cleanupCronJobName, this.namespace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default Kubernetes;
|
export default Kubernetes;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { BatchV1beta1Api, V1beta1CronJob } from '@kubernetes/client-node';
|
||||||
|
import { Cron } from 'cron-converter';
|
||||||
|
class KubernetesCleanupCronJob {
|
||||||
|
static async cleanup(api: BatchV1beta1Api, name: string, namespace: string) {
|
||||||
|
await api.deleteNamespacedCronJob('name', namespace);
|
||||||
|
}
|
||||||
|
static createCleanupCronJob(kubeClientBatch: BatchV1beta1Api, name: string, namespace: string) {
|
||||||
|
const batchJob = new V1beta1CronJob();
|
||||||
|
batchJob.kind = 'CronJob';
|
||||||
|
batchJob.metadata = {
|
||||||
|
name,
|
||||||
|
labels: {
|
||||||
|
app: 'unity-builder',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const cronInstance = new Cron();
|
||||||
|
const date = Date.now() + 1000 * 60 * 60;
|
||||||
|
const spec = {
|
||||||
|
containers: [
|
||||||
|
{
|
||||||
|
name: 'main',
|
||||||
|
image: 'bitnami/kubectl',
|
||||||
|
imagePullPolicy: '',
|
||||||
|
command: ['/bin/sh'],
|
||||||
|
args: [
|
||||||
|
'-c',
|
||||||
|
`
|
||||||
|
echo "delete the kubernetes resources"
|
||||||
|
kubectl get pods
|
||||||
|
`,
|
||||||
|
],
|
||||||
|
restartPolicy: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
batchJob.spec = {
|
||||||
|
schedule: cronInstance.schedule(new Date(date)).toString(),
|
||||||
|
jobTemplate: {
|
||||||
|
spec: {
|
||||||
|
template: { spec },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
kubeClientBatch.createNamespacedCronJob(namespace, batchJob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default KubernetesCleanupCronJob;
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
import BuildParameters from '../build-parameters';
|
||||||
|
import RemoteBuilderEnvironmentVariable from './remote-builder-environment-variable';
|
||||||
|
|
||||||
|
class KubernetesJobSpecFactory {
|
||||||
|
static getJobSpec(
|
||||||
|
command: string[],
|
||||||
|
image: string,
|
||||||
|
mountdir: string,
|
||||||
|
workingDirectory: string,
|
||||||
|
environment: RemoteBuilderEnvironmentVariable[],
|
||||||
|
buildId: string,
|
||||||
|
buildParameters: BuildParameters,
|
||||||
|
secretName,
|
||||||
|
pvcName,
|
||||||
|
jobName,
|
||||||
|
k8s,
|
||||||
|
) {
|
||||||
|
environment.push(
|
||||||
|
...[
|
||||||
|
{
|
||||||
|
name: 'GITHUB_SHA',
|
||||||
|
value: buildId,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'GITHUB_WORKSPACE',
|
||||||
|
value: '/data/repo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PROJECT_PATH',
|
||||||
|
value: buildParameters.projectPath,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_PATH',
|
||||||
|
value: buildParameters.buildPath,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_FILE',
|
||||||
|
value: buildParameters.buildFile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_NAME',
|
||||||
|
value: buildParameters.buildName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_METHOD',
|
||||||
|
value: buildParameters.buildMethod,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CUSTOM_PARAMETERS',
|
||||||
|
value: buildParameters.customParameters,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CHOWN_FILES_TO',
|
||||||
|
value: buildParameters.chownFilesTo,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BUILD_TARGET',
|
||||||
|
value: buildParameters.platform,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ANDROID_VERSION_CODE',
|
||||||
|
value: buildParameters.androidVersionCode.toString(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ANDROID_KEYSTORE_NAME',
|
||||||
|
value: buildParameters.androidKeystoreName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ANDROID_KEYALIAS_NAME',
|
||||||
|
value: buildParameters.androidKeyaliasName,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
);
|
||||||
|
const job = new k8s.V1Job();
|
||||||
|
job.apiVersion = 'batch/v1';
|
||||||
|
job.kind = 'Job';
|
||||||
|
job.metadata = {
|
||||||
|
name: jobName,
|
||||||
|
labels: {
|
||||||
|
app: 'unity-builder',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
job.spec = {
|
||||||
|
backoffLimit: 1,
|
||||||
|
template: {
|
||||||
|
spec: {
|
||||||
|
volumes: [
|
||||||
|
{
|
||||||
|
name: 'build-mount',
|
||||||
|
persistentVolumeClaim: {
|
||||||
|
claimName: pvcName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'credentials',
|
||||||
|
secret: {
|
||||||
|
secretName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
containers: [
|
||||||
|
{
|
||||||
|
name: 'main',
|
||||||
|
image,
|
||||||
|
command: ['/bin/sh'],
|
||||||
|
args: ['-c', ...command],
|
||||||
|
|
||||||
|
workingDir: `/${workingDirectory}`,
|
||||||
|
resources: {
|
||||||
|
requests: {
|
||||||
|
memory: buildParameters.remoteBuildMemory,
|
||||||
|
cpu: buildParameters.remoteBuildCpu,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
env: environment,
|
||||||
|
volumeMounts: [
|
||||||
|
{
|
||||||
|
name: 'build-mount',
|
||||||
|
mountPath: `/${mountdir}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'credentials',
|
||||||
|
mountPath: '/credentials',
|
||||||
|
readOnly: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
lifecycle: {
|
||||||
|
preStop: {
|
||||||
|
exec: {
|
||||||
|
command: [
|
||||||
|
'bin/bash',
|
||||||
|
'-c',
|
||||||
|
`cd /data/builder/action/steps;
|
||||||
|
chmod +x /return_license.sh;
|
||||||
|
/return_license.sh;`,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
restartPolicy: 'Never',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return job;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default KubernetesJobSpecFactory;
|
||||||
25
yarn.lock
25
yarn.lock
|
|
@ -1723,6 +1723,14 @@ cosmiconfig@^7.0.0:
|
||||||
path-type "^4.0.0"
|
path-type "^4.0.0"
|
||||||
yaml "^1.10.0"
|
yaml "^1.10.0"
|
||||||
|
|
||||||
|
cron-converter@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/cron-converter/-/cron-converter-1.0.1.tgz#a7a13f49d69893523feef3c511280aab50f5e403"
|
||||||
|
integrity sha512-2GpOtd4lGs5kOspHprRUbChyDXmA59cgqcVvIqZgqTSSOJ1tMW9rKoOEGyc+UXYZDUWyrPtf7dvrYyFCjmo/QA==
|
||||||
|
dependencies:
|
||||||
|
moment-timezone "~0.5"
|
||||||
|
sprintf-js "~1"
|
||||||
|
|
||||||
cross-spawn@^6.0.0:
|
cross-spawn@^6.0.0:
|
||||||
version "6.0.5"
|
version "6.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||||
|
|
@ -4024,6 +4032,18 @@ mkdirp@1.x, mkdirp@^1.0.3:
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||||
|
|
||||||
|
moment-timezone@~0.5:
|
||||||
|
version "0.5.33"
|
||||||
|
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.33.tgz#b252fd6bb57f341c9b59a5ab61a8e51a73bbd22c"
|
||||||
|
integrity sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==
|
||||||
|
dependencies:
|
||||||
|
moment ">= 2.9.0"
|
||||||
|
|
||||||
|
"moment@>= 2.9.0":
|
||||||
|
version "2.29.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
|
||||||
|
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
|
||||||
|
|
||||||
ms@2.0.0:
|
ms@2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||||
|
|
@ -5073,6 +5093,11 @@ split-string@^3.0.1, split-string@^3.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
extend-shallow "^3.0.0"
|
extend-shallow "^3.0.0"
|
||||||
|
|
||||||
|
sprintf-js@~1:
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
|
||||||
|
integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
|
||||||
|
|
||||||
sprintf-js@~1.0.2:
|
sprintf-js@~1.0.2:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue