k8s refactoring started, new k8s api client

pull/265/head
Frostebite 2021-05-23 15:26:57 +01:00
parent 5d41be7bc7
commit 5929a988d3
4 changed files with 662 additions and 461 deletions

637
dist/index.js vendored
View File

@ -732,8 +732,8 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
// @ts-ignore
const k8s = __importStar(__webpack_require__(89679));
const core = __webpack_require__(42186);
// const base64 = require('base-64');
// const pollInterval = 10000;
const base64 = __webpack_require__(85848);
const pollInterval = 10000;
class Kubernetes {
static runBuildJob(buildParameters, baseImage) {
return __awaiter(this, void 0, void 0, function* () {
@ -741,6 +741,7 @@ class Kubernetes {
const kc = new k8s.KubeConfig();
kc.loadFromDefault();
const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
const k8sBatchApi = kc.makeApiClient(k8s.BatchV1Api);
core.info('loaded from default');
// const kubeconfig = new KubeConfig();
// kubeconfig.loadFromString(base64.decode(buildParameters.kubeConfig));
@ -753,6 +754,7 @@ class Kubernetes {
const jobName = `unity-builder-job-${buildId}`;
const namespace = 'default';
this.kubeClient = k8sApi;
this.kubeClientBatch = k8sBatchApi;
this.buildId = buildId;
this.buildParameters = buildParameters;
this.baseImage = baseImage;
@ -760,240 +762,243 @@ class Kubernetes {
this.secretName = secretName;
this.jobName = jobName;
this.namespace = namespace;
// await Kubernetes.createSecret();
// await Kubernetes.createPersistentVolumeClaim();
yield Kubernetes.createSecret();
yield Kubernetes.createPersistentVolumeClaim();
// await Kubernetes.scheduleBuildJob();
// await Kubernetes.watchBuildJobUntilFinished();
// await Kubernetes.cleanup();
core.setOutput('volume', pvcName);
});
}
// static async createSecret() {
// //const secretManifest = {
// // apiVersion: 'v1',
// // kind: 'Secret',
// // metadata: {
// // name: this.secretName,
// // },
// // type: 'Opaque',
// // data: {
// // GITHUB_TOKEN: base64.encode(this.buildParameters.githubToken),
// // UNITY_LICENSE: base64.encode(process.env.UNITY_LICENSE),
// // ANDROID_KEYSTORE_BASE64: base64.encode(this.buildParameters.androidKeystoreBase64),
// // ANDROID_KEYSTORE_PASS: base64.encode(this.buildParameters.androidKeystorePass),
// // ANDROID_KEYALIAS_PASS: base64.encode(this.buildParameters.androidKeyaliasPass),
// // },
// //};
// //await this.kubeClient.api.v1.namespaces(this.namespace).secrets.post({ body: secretManifest });
// }
// static async createPersistentVolumeClaim() {
// if (this.buildParameters.kubeVolume) {
// core.info(this.buildParameters.kubeVolume);
// this.pvcName = this.buildParameters.kubeVolume;
// return;
// }
// const pvcManifest = {
// apiVersion: 'v1',
// kind: 'PersistentVolumeClaim',
// metadata: {
// name: this.pvcName,
// },
// spec: {
// accessModes: ['ReadWriteOnce'],
// volumeMode: 'Filesystem',
// resources: {
// requests: {
// storage: this.buildParameters.kubeVolumeSize,
// },
// },
// },
// };
// await this.kubeClient.api.v1.namespaces(this.namespace).persistentvolumeclaims.post({ body: pvcManifest });
// core.info('Persistent Volume created, waiting for ready state...');
// await Kubernetes.watchPersistentVolumeClaimUntilReady();
// core.info('Persistent Volume ready for claims');
// }
// static async watchPersistentVolumeClaimUntilReady() {
// await new Promise((resolve) => setTimeout(resolve, pollInterval));
// const queryResult = await this.kubeClient.api.v1
// .namespaces(this.namespace)
// .persistentvolumeclaims(this.pvcName)
// .get();
// if (queryResult.body.status.phase === 'Pending') {
// await Kubernetes.watchPersistentVolumeClaimUntilReady();
// }
// }
// static async scheduleBuildJob() {
// core.info('Creating build job');
// const jobManifest = {
// apiVersion: 'batch/v1',
// kind: 'Job',
// metadata: {
// name: this.jobName,
// labels: {
// app: 'unity-builder',
// },
// },
// spec: {
// template: {
// backoffLimit: 1,
// spec: {
// volumes: [
// {
// name: 'data',
// persistentVolumeClaim: {
// claimName: this.pvcName,
// },
// },
// {
// name: 'credentials',
// secret: {
// secretName: this.secretName,
// },
// },
// ],
// initContainers: [
// {
// name: 'clone',
// image: 'alpine/git',
// command: [
// '/bin/sh',
// '-c',
// `apk update;
// apk add git-lfs;
// export GITHUB_TOKEN=$(cat /credentials/GITHUB_TOKEN);
// cd /data;
// git clone https://github.com/${process.env.GITHUB_REPOSITORY}.git repo;
// git clone https://github.com/webbertakken/unity-builder.git builder;
// cd repo;
// git checkout $GITHUB_SHA;
// ls`,
// ],
// volumeMounts: [
// {
// name: 'data',
// mountPath: '/data',
// },
// {
// name: 'credentials',
// mountPath: '/credentials',
// readOnly: true,
// },
// ],
// env: [
// {
// name: 'GITHUB_SHA',
// value: this.buildId,
// },
// ],
// },
// ],
// containers: [
// {
// name: 'main',
// image: `${this.baseImage.toString()}`,
// command: [
// 'bin/bash',
// '-c',
// `for f in ./credentials/*; do export $(basename $f)="$(cat $f)"; done
// cp -r /data/builder/action/default-build-script /UnityBuilderAction
// cp -r /data/builder/action/entrypoint.sh /entrypoint.sh
// cp -r /data/builder/action/steps /steps
// chmod -R +x /entrypoint.sh;
// chmod -R +x /steps;
// /entrypoint.sh;
// `,
// ],
// resources: {
// requests: {
// memory: this.buildParameters.kubeContainerMemory,
// cpu: this.buildParameters.kubeContainerCPU,
// },
// },
// env: [
// {
// 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,
// },
// ],
// volumeMounts: [
// {
// name: 'data',
// mountPath: '/data',
// },
// {
// 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',
// },
// },
// },
// };
// await this.kubeClient.apis.batch.v1.namespaces(this.namespace).jobs.post({ body: jobManifest });
// core.info('Job created');
// }
static createSecret() {
return __awaiter(this, void 0, void 0, function* () {
const secret = new k8s.V1Secret();
secret.apiVersion = 'v1';
secret.kind = 'Secret';
secret.type = 'Opaque';
secret.metadata = {
name: this.secretName,
};
secret.data = {
GITHUB_TOKEN: base64.encode(this.buildParameters.githubToken),
UNITY_LICENSE: base64.encode(process.env.UNITY_LICENSE),
ANDROID_KEYSTORE_BASE64: base64.encode(this.buildParameters.androidKeystoreBase64),
ANDROID_KEYSTORE_PASS: base64.encode(this.buildParameters.androidKeystorePass),
ANDROID_KEYALIAS_PASS: base64.encode(this.buildParameters.androidKeyaliasPass),
};
yield this.kubeClient.createNamespacedSecret(this.namespace, secret);
});
}
static createPersistentVolumeClaim() {
return __awaiter(this, void 0, void 0, function* () {
if (this.buildParameters.kubeVolume) {
core.info(this.buildParameters.kubeVolume);
this.pvcName = this.buildParameters.kubeVolume;
return;
}
const pvc = new k8s.V1PersistentVolumeClaim();
pvc.apiVersion = 'v1';
pvc.kind = 'PersistentVolumeClaim';
pvc.metadata = {
name: this.pvcName,
};
pvc.spec = {
accessModes: ['ReadWriteOnce'],
volumeMode: 'Filesystem',
resources: {
requests: {
storage: this.buildParameters.kubeVolumeSize,
},
},
};
yield this.kubeClient.createNamespacedPersistentVolumeClaim(this.namespace, pvc);
core.info('Persistent Volume created, waiting for ready state...');
yield Kubernetes.watchPersistentVolumeClaimUntilReady();
core.info('Persistent Volume ready for claims');
});
}
static watchPersistentVolumeClaimUntilReady() {
var _a;
return __awaiter(this, void 0, void 0, function* () {
yield new Promise((resolve) => setTimeout(resolve, pollInterval));
const queryResult = yield this.kubeClient.readNamespacedPersistentVolumeClaim(this.pvcName, this.namespace);
if (((_a = queryResult.body.status) === null || _a === void 0 ? void 0 : _a.phase) === 'Pending') {
yield Kubernetes.watchPersistentVolumeClaimUntilReady();
}
});
}
static scheduleBuildJob() {
return __awaiter(this, void 0, void 0, function* () {
core.info('Creating build job');
const job = new k8s.V1Job();
job.apiVersion = 'batch/v1';
job.kind = 'Job';
job.metadata = {
name: this.jobName,
labels: {
app: 'unity-builder',
},
};
job.spec = {
template: {
spec: {
volumes: [
{
name: 'data',
persistentVolumeClaim: {
claimName: this.pvcName,
},
},
{
name: 'credentials',
secret: {
secretName: this.secretName,
},
},
],
initContainers: [
{
name: 'clone',
image: 'alpine/git',
command: [
'/bin/sh',
'-c',
`apk update;
apk add git-lfs;
export GITHUB_TOKEN=$(cat /credentials/GITHUB_TOKEN);
cd /data;
git clone https://github.com/${process.env.GITHUB_REPOSITORY}.git repo;
git clone https://github.com/webbertakken/unity-builder.git builder;
cd repo;
git checkout $GITHUB_SHA;
ls`,
],
volumeMounts: [
{
name: 'data',
mountPath: '/data',
},
{
name: 'credentials',
mountPath: '/credentials',
readOnly: true,
},
],
env: [
{
name: 'GITHUB_SHA',
value: this.buildId,
},
],
},
],
containers: [
{
name: 'main',
image: `${this.baseImage.toString()}`,
command: [
'bin/bash',
'-c',
`for f in ./credentials/*; do export $(basename $f)="$(cat $f)"; done
cp -r /data/builder/action/default-build-script /UnityBuilderAction
cp -r /data/builder/action/entrypoint.sh /entrypoint.sh
cp -r /data/builder/action/steps /steps
chmod -R +x /entrypoint.sh;
chmod -R +x /steps;
/entrypoint.sh;
`,
],
resources: {
requests: {
memory: this.buildParameters.remoteBuildMemory,
cpu: this.buildParameters.remoteBuildCpu,
},
},
env: [
{
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,
},
],
volumeMounts: [
{
name: 'data',
mountPath: '/data',
},
{
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',
},
},
};
job.spec.backoffLimit = 1;
yield this.kubeClientBatch.createNamespacedJob(this.namespace, job);
core.info('Job created');
});
}
// static async watchBuildJobUntilFinished() {
// let podname;
// let ready = false;
@ -167558,6 +167563,178 @@ function range(a, b, str) {
}
/***/ }),
/***/ 85848:
/***/ (function(module, exports, __webpack_require__) {
/* module decorator */ module = __webpack_require__.nmd(module);
/*! https://mths.be/base64 v1.0.0 by @mathias | MIT license */
;(function(root) {
// Detect free variables `exports`.
var freeExports = true && exports;
// Detect free variable `module`.
var freeModule = true && module &&
module.exports == freeExports && module;
// Detect free variable `global`, from Node.js or Browserified code, and use
// it as `root`.
var freeGlobal = typeof global == 'object' && global;
if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
root = freeGlobal;
}
/*--------------------------------------------------------------------------*/
var InvalidCharacterError = function(message) {
this.message = message;
};
InvalidCharacterError.prototype = new Error;
InvalidCharacterError.prototype.name = 'InvalidCharacterError';
var error = function(message) {
// Note: the error messages used throughout this file match those used by
// the native `atob`/`btoa` implementation in Chromium.
throw new InvalidCharacterError(message);
};
var TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
// http://whatwg.org/html/common-microsyntaxes.html#space-character
var REGEX_SPACE_CHARACTERS = /[\t\n\f\r ]/g;
// `decode` is designed to be fully compatible with `atob` as described in the
// HTML Standard. http://whatwg.org/html/webappapis.html#dom-windowbase64-atob
// The optimized base64-decoding algorithm used is based on @atks excellent
// implementation. https://gist.github.com/atk/1020396
var decode = function(input) {
input = String(input)
.replace(REGEX_SPACE_CHARACTERS, '');
var length = input.length;
if (length % 4 == 0) {
input = input.replace(/==?$/, '');
length = input.length;
}
if (
length % 4 == 1 ||
// http://whatwg.org/C#alphanumeric-ascii-characters
/[^+a-zA-Z0-9/]/.test(input)
) {
error(
'Invalid character: the string to be decoded is not correctly encoded.'
);
}
var bitCounter = 0;
var bitStorage;
var buffer;
var output = '';
var position = -1;
while (++position < length) {
buffer = TABLE.indexOf(input.charAt(position));
bitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer;
// Unless this is the first of a group of 4 characters…
if (bitCounter++ % 4) {
// …convert the first 8 bits to a single ASCII character.
output += String.fromCharCode(
0xFF & bitStorage >> (-2 * bitCounter & 6)
);
}
}
return output;
};
// `encode` is designed to be fully compatible with `btoa` as described in the
// HTML Standard: http://whatwg.org/html/webappapis.html#dom-windowbase64-btoa
var encode = function(input) {
input = String(input);
if (/[^\0-\xFF]/.test(input)) {
// Note: no need to special-case astral symbols here, as surrogates are
// matched, and the input is supposed to only contain ASCII anyway.
error(
'The string to be encoded contains characters outside of the ' +
'Latin1 range.'
);
}
var padding = input.length % 3;
var output = '';
var position = -1;
var a;
var b;
var c;
var buffer;
// Make sure any padding is handled outside of the loop.
var length = input.length - padding;
while (++position < length) {
// Read three bytes, i.e. 24 bits.
a = input.charCodeAt(position) << 16;
b = input.charCodeAt(++position) << 8;
c = input.charCodeAt(++position);
buffer = a + b + c;
// Turn the 24 bits into four chunks of 6 bits each, and append the
// matching character for each of them to the output.
output += (
TABLE.charAt(buffer >> 18 & 0x3F) +
TABLE.charAt(buffer >> 12 & 0x3F) +
TABLE.charAt(buffer >> 6 & 0x3F) +
TABLE.charAt(buffer & 0x3F)
);
}
if (padding == 2) {
a = input.charCodeAt(position) << 8;
b = input.charCodeAt(++position);
buffer = a + b;
output += (
TABLE.charAt(buffer >> 10) +
TABLE.charAt((buffer >> 4) & 0x3F) +
TABLE.charAt((buffer << 2) & 0x3F) +
'='
);
} else if (padding == 1) {
buffer = input.charCodeAt(position);
output += (
TABLE.charAt(buffer >> 2) +
TABLE.charAt((buffer << 4) & 0x3F) +
'=='
);
}
return output;
};
var base64 = {
'encode': encode,
'decode': decode,
'version': '1.0.0'
};
// Some AMD build optimizers, like r.js, check for specific condition patterns
// like the following:
if (
typeof define == 'function' &&
typeof define.amd == 'object' &&
define.amd
) {
define(function() {
return base64;
});
} else if (freeExports && !freeExports.nodeType) {
if (freeModule) { // in Node.js or RingoJS v0.8.0+
freeModule.exports = base64;
} else { // in Narwhal or RingoJS v0.7.0-
for (var key in base64) {
base64.hasOwnProperty(key) && (freeExports[key] = base64[key]);
}
}
} else { // in Rhino or a web browser
root.base64 = base64;
}
}(this));
/***/ }),
/***/ 45447:

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

24
dist/licenses.txt vendored
View File

@ -706,6 +706,30 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
base-64
MIT
Copyright Mathias Bynens <https://mathiasbynens.be/>
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.
bcrypt-pbkdf
BSD-3-Clause
The Blowfish portions are under the following license:

View File

@ -2,12 +2,13 @@
import * as k8s from '@kubernetes/client-node';
import { BuildParameters } from '.';
const core = require('@actions/core');
// const base64 = require('base-64');
const base64 = require('base-64');
// const pollInterval = 10000;
const pollInterval = 10000;
class Kubernetes {
private static kubeClient: k8s.CoreV1Api;
private static kubeClientBatch: k8s.BatchV1Api;
private static buildId: string;
private static buildParameters: BuildParameters;
private static baseImage: any;
@ -21,6 +22,7 @@ class Kubernetes {
const kc = new k8s.KubeConfig();
kc.loadFromDefault();
const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
const k8sBatchApi = kc.makeApiClient(k8s.BatchV1Api);
core.info('loaded from default');
// const kubeconfig = new KubeConfig();
@ -36,6 +38,7 @@ class Kubernetes {
const namespace = 'default';
this.kubeClient = k8sApi;
this.kubeClientBatch = k8sBatchApi;
this.buildId = buildId;
this.buildParameters = buildParameters;
this.baseImage = baseImage;
@ -44,8 +47,8 @@ class Kubernetes {
this.jobName = jobName;
this.namespace = namespace;
// await Kubernetes.createSecret();
// await Kubernetes.createPersistentVolumeClaim();
await Kubernetes.createSecret();
await Kubernetes.createPersistentVolumeClaim();
// await Kubernetes.scheduleBuildJob();
// await Kubernetes.watchBuildJobUntilFinished();
// await Kubernetes.cleanup();
@ -53,235 +56,232 @@ class Kubernetes {
core.setOutput('volume', pvcName);
}
// static async createSecret() {
// //const secretManifest = {
// // apiVersion: 'v1',
// // kind: 'Secret',
// // metadata: {
// // name: this.secretName,
// // },
// // type: 'Opaque',
// // data: {
// // GITHUB_TOKEN: base64.encode(this.buildParameters.githubToken),
// // UNITY_LICENSE: base64.encode(process.env.UNITY_LICENSE),
// // ANDROID_KEYSTORE_BASE64: base64.encode(this.buildParameters.androidKeystoreBase64),
// // ANDROID_KEYSTORE_PASS: base64.encode(this.buildParameters.androidKeystorePass),
// // ANDROID_KEYALIAS_PASS: base64.encode(this.buildParameters.androidKeyaliasPass),
// // },
// //};
// //await this.kubeClient.api.v1.namespaces(this.namespace).secrets.post({ body: secretManifest });
// }
static async createSecret() {
const secret = new k8s.V1Secret();
secret.apiVersion = 'v1';
secret.kind = 'Secret';
secret.type = 'Opaque';
secret.metadata = {
name: this.secretName,
};
// static async createPersistentVolumeClaim() {
// if (this.buildParameters.kubeVolume) {
// core.info(this.buildParameters.kubeVolume);
// this.pvcName = this.buildParameters.kubeVolume;
// return;
// }
// const pvcManifest = {
// apiVersion: 'v1',
// kind: 'PersistentVolumeClaim',
// metadata: {
// name: this.pvcName,
// },
// spec: {
// accessModes: ['ReadWriteOnce'],
// volumeMode: 'Filesystem',
// resources: {
// requests: {
// storage: this.buildParameters.kubeVolumeSize,
// },
// },
// },
// };
// await this.kubeClient.api.v1.namespaces(this.namespace).persistentvolumeclaims.post({ body: pvcManifest });
// core.info('Persistent Volume created, waiting for ready state...');
// await Kubernetes.watchPersistentVolumeClaimUntilReady();
// core.info('Persistent Volume ready for claims');
// }
secret.data = {
GITHUB_TOKEN: base64.encode(this.buildParameters.githubToken),
UNITY_LICENSE: base64.encode(process.env.UNITY_LICENSE),
ANDROID_KEYSTORE_BASE64: base64.encode(this.buildParameters.androidKeystoreBase64),
ANDROID_KEYSTORE_PASS: base64.encode(this.buildParameters.androidKeystorePass),
ANDROID_KEYALIAS_PASS: base64.encode(this.buildParameters.androidKeyaliasPass),
};
// static async watchPersistentVolumeClaimUntilReady() {
// await new Promise((resolve) => setTimeout(resolve, pollInterval));
// const queryResult = await this.kubeClient.api.v1
// .namespaces(this.namespace)
// .persistentvolumeclaims(this.pvcName)
// .get();
// if (queryResult.body.status.phase === 'Pending') {
// await Kubernetes.watchPersistentVolumeClaimUntilReady();
// }
// }
await this.kubeClient.createNamespacedSecret(this.namespace, secret);
}
// static async scheduleBuildJob() {
// core.info('Creating build job');
// const jobManifest = {
// apiVersion: 'batch/v1',
// kind: 'Job',
// metadata: {
// name: this.jobName,
// labels: {
// app: 'unity-builder',
// },
// },
// spec: {
// template: {
// backoffLimit: 1,
// spec: {
// volumes: [
// {
// name: 'data',
// persistentVolumeClaim: {
// claimName: this.pvcName,
// },
// },
// {
// name: 'credentials',
// secret: {
// secretName: this.secretName,
// },
// },
// ],
// initContainers: [
// {
// name: 'clone',
// image: 'alpine/git',
// command: [
// '/bin/sh',
// '-c',
// `apk update;
// apk add git-lfs;
// export GITHUB_TOKEN=$(cat /credentials/GITHUB_TOKEN);
// cd /data;
// git clone https://github.com/${process.env.GITHUB_REPOSITORY}.git repo;
// git clone https://github.com/webbertakken/unity-builder.git builder;
// cd repo;
// git checkout $GITHUB_SHA;
// ls`,
// ],
// volumeMounts: [
// {
// name: 'data',
// mountPath: '/data',
// },
// {
// name: 'credentials',
// mountPath: '/credentials',
// readOnly: true,
// },
// ],
// env: [
// {
// name: 'GITHUB_SHA',
// value: this.buildId,
// },
// ],
// },
// ],
// containers: [
// {
// name: 'main',
// image: `${this.baseImage.toString()}`,
// command: [
// 'bin/bash',
// '-c',
// `for f in ./credentials/*; do export $(basename $f)="$(cat $f)"; done
// cp -r /data/builder/action/default-build-script /UnityBuilderAction
// cp -r /data/builder/action/entrypoint.sh /entrypoint.sh
// cp -r /data/builder/action/steps /steps
// chmod -R +x /entrypoint.sh;
// chmod -R +x /steps;
// /entrypoint.sh;
// `,
// ],
// resources: {
// requests: {
// memory: this.buildParameters.kubeContainerMemory,
// cpu: this.buildParameters.kubeContainerCPU,
// },
// },
// env: [
// {
// 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,
// },
// ],
// volumeMounts: [
// {
// name: 'data',
// mountPath: '/data',
// },
// {
// 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',
// },
// },
// },
// };
// await this.kubeClient.apis.batch.v1.namespaces(this.namespace).jobs.post({ body: jobManifest });
// core.info('Job created');
// }
static async createPersistentVolumeClaim() {
if (this.buildParameters.kubeVolume) {
core.info(this.buildParameters.kubeVolume);
this.pvcName = this.buildParameters.kubeVolume;
return;
}
const pvc = new k8s.V1PersistentVolumeClaim();
pvc.apiVersion = 'v1';
pvc.kind = 'PersistentVolumeClaim';
pvc.metadata = {
name: this.pvcName,
};
pvc.spec = {
accessModes: ['ReadWriteOnce'],
volumeMode: 'Filesystem',
resources: {
requests: {
storage: this.buildParameters.kubeVolumeSize,
},
},
};
await this.kubeClient.createNamespacedPersistentVolumeClaim(this.namespace, pvc);
core.info('Persistent Volume created, waiting for ready state...');
await Kubernetes.watchPersistentVolumeClaimUntilReady();
core.info('Persistent Volume ready for claims');
}
static async watchPersistentVolumeClaimUntilReady() {
await new Promise((resolve) => setTimeout(resolve, pollInterval));
const queryResult = await this.kubeClient.readNamespacedPersistentVolumeClaim(this.pvcName, this.namespace);
if (queryResult.body.status?.phase === 'Pending') {
await Kubernetes.watchPersistentVolumeClaimUntilReady();
}
}
static async scheduleBuildJob() {
core.info('Creating build job');
const job = new k8s.V1Job();
job.apiVersion = 'batch/v1';
job.kind = 'Job';
job.metadata = {
name: this.jobName,
labels: {
app: 'unity-builder',
},
};
job.spec = {
template: {
spec: {
volumes: [
{
name: 'data',
persistentVolumeClaim: {
claimName: this.pvcName,
},
},
{
name: 'credentials',
secret: {
secretName: this.secretName,
},
},
],
initContainers: [
{
name: 'clone',
image: 'alpine/git',
command: [
'/bin/sh',
'-c',
`apk update;
apk add git-lfs;
export GITHUB_TOKEN=$(cat /credentials/GITHUB_TOKEN);
cd /data;
git clone https://github.com/${process.env.GITHUB_REPOSITORY}.git repo;
git clone https://github.com/webbertakken/unity-builder.git builder;
cd repo;
git checkout $GITHUB_SHA;
ls`,
],
volumeMounts: [
{
name: 'data',
mountPath: '/data',
},
{
name: 'credentials',
mountPath: '/credentials',
readOnly: true,
},
],
env: [
{
name: 'GITHUB_SHA',
value: this.buildId,
},
],
},
],
containers: [
{
name: 'main',
image: `${this.baseImage.toString()}`,
command: [
'bin/bash',
'-c',
`for f in ./credentials/*; do export $(basename $f)="$(cat $f)"; done
cp -r /data/builder/action/default-build-script /UnityBuilderAction
cp -r /data/builder/action/entrypoint.sh /entrypoint.sh
cp -r /data/builder/action/steps /steps
chmod -R +x /entrypoint.sh;
chmod -R +x /steps;
/entrypoint.sh;
`,
],
resources: {
requests: {
memory: this.buildParameters.remoteBuildMemory,
cpu: this.buildParameters.remoteBuildCpu,
},
},
env: [
{
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,
},
],
volumeMounts: [
{
name: 'data',
mountPath: '/data',
},
{
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',
},
},
};
job.spec.backoffLimit = 1;
await this.kubeClientBatch.createNamespacedJob(this.namespace, job);
core.info('Job created');
}
// static async watchBuildJobUntilFinished() {
// let podname;