Logging cleanup

pull/310/head
Frostebite 2021-09-21 19:27:04 +01:00
parent 9712dddf10
commit e802849d30
10 changed files with 206 additions and 214 deletions

252
dist/index.js vendored
View File

@ -355,6 +355,7 @@ const fs = __importStar(__webpack_require__(35747));
const core = __importStar(__webpack_require__(42186)); const core = __importStar(__webpack_require__(42186));
const cloud_runner_constants_1 = __importDefault(__webpack_require__(28394)); const cloud_runner_constants_1 = __importDefault(__webpack_require__(28394));
const aws_build_runner_1 = __importDefault(__webpack_require__(83230)); const aws_build_runner_1 = __importDefault(__webpack_require__(83230));
const cloud_runner_logger_1 = __importDefault(__webpack_require__(49899));
const crypto = __webpack_require__(33373); const crypto = __webpack_require__(33373);
class AWSBuildEnvironment { class AWSBuildEnvironment {
constructor(buildParameters) { constructor(buildParameters) {
@ -388,16 +389,16 @@ class AWSBuildEnvironment {
let t2; let t2;
try { try {
const t1 = Date.now(); const t1 = Date.now();
core.info(`Setup job time: ${Math.floor((t1 - t0) / 1000)}s`); cloud_runner_logger_1.default.log(`Setup job time: ${Math.floor((t1 - t0) / 1000)}s`);
yield aws_build_runner_1.default.runTask(taskDef, ECS, CF, environment, buildId, commands); yield aws_build_runner_1.default.runTask(taskDef, ECS, CF, environment, buildId, commands);
t2 = Date.now(); t2 = Date.now();
core.info(`Run job time: ${Math.floor((t2 - t1) / 1000)}s`); cloud_runner_logger_1.default.log(`Run job time: ${Math.floor((t2 - t1) / 1000)}s`);
} }
finally { finally {
yield this.cleanupResources(CF, taskDef); yield this.cleanupResources(CF, taskDef);
const t3 = Date.now(); const t3 = Date.now();
if (t2 !== undefined) if (t2 !== undefined)
core.info(`Cleanup job time: ${Math.floor((t3 - t2) / 1000)}s`); cloud_runner_logger_1.default.log(`Cleanup job time: ${Math.floor((t3 - t2) / 1000)}s`);
} }
}); });
} }
@ -495,7 +496,7 @@ class AWSBuildEnvironment {
...secretsMappedToCloudFormationParameters, ...secretsMappedToCloudFormationParameters,
], ],
}).promise(); }).promise();
core.info('Creating cloud runner job'); cloud_runner_logger_1.default.log('Creating cloud runner job');
yield CF.createStack({ yield CF.createStack({
StackName: cleanupTaskDefStackName, StackName: cleanupTaskDefStackName,
TemplateBody: cleanupCloudFormation, TemplateBody: cleanupCloudFormation,
@ -523,7 +524,7 @@ class AWSBuildEnvironment {
}, },
], ],
}).promise(); }).promise();
// Side effect: core.info('Creating cleanup double checker cron job...'); // Side effect: CloudRunnerLogger.log('Creating cleanup double checker cron job...');
yield CF.waitFor('stackCreateComplete', { StackName: taskDefStackName }).promise(); yield CF.waitFor('stackCreateComplete', { StackName: taskDefStackName }).promise();
} }
catch (error) { catch (error) {
@ -586,9 +587,9 @@ class AWSBuildEnvironment {
}); });
try { try {
if (!stackExists) { if (!stackExists) {
core.info(`${baseStackName} stack does not exist (${JSON.stringify(stacks)})`); cloud_runner_logger_1.default.log(`${baseStackName} stack does not exist (${JSON.stringify(stacks)})`);
yield CF.createStack(createStackInput).promise(); yield CF.createStack(createStackInput).promise();
core.info(`created stack (version: ${hash})`); cloud_runner_logger_1.default.log(`created stack (version: ${hash})`);
} }
const CFState = yield describeStack(); const CFState = yield describeStack();
let stack = (_b = CFState.Stacks) === null || _b === void 0 ? void 0 : _b[0]; let stack = (_b = CFState.Stacks) === null || _b === void 0 ? void 0 : _b[0];
@ -600,13 +601,13 @@ class AWSBuildEnvironment {
yield CF.waitFor('stackCreateComplete', describeStackInput).promise(); yield CF.waitFor('stackCreateComplete', describeStackInput).promise();
} }
if (stackExists) { if (stackExists) {
core.info(`Base stack exists (version: ${stackVersion}, local version: ${hash})`); cloud_runner_logger_1.default.log(`Base stack exists (version: ${stackVersion}, local version: ${hash})`);
if (hash !== stackVersion) { if (hash !== stackVersion) {
core.info(`Updating`); cloud_runner_logger_1.default.log(`Updating`);
yield CF.updateStack(updateInput).promise(); yield CF.updateStack(updateInput).promise();
} }
else { else {
core.info(`No update required`); cloud_runner_logger_1.default.log(`No update required`);
} }
stack = (_e = (yield describeStack()).Stacks) === null || _e === void 0 ? void 0 : _e[0]; stack = (_e = (yield describeStack()).Stacks) === null || _e === void 0 ? void 0 : _e[0];
if (!stack) { if (!stack) {
@ -616,7 +617,7 @@ class AWSBuildEnvironment {
yield CF.waitFor('stackUpdateComplete', describeStackInput).promise(); yield CF.waitFor('stackUpdateComplete', describeStackInput).promise();
} }
} }
core.info('base stack is ready'); cloud_runner_logger_1.default.log('base stack is ready');
} }
catch (error) { catch (error) {
core.error(JSON.stringify(yield describeStack(), undefined, 4)); core.error(JSON.stringify(yield describeStack(), undefined, 4));
@ -626,14 +627,14 @@ class AWSBuildEnvironment {
} }
handleStackCreationFailure(error, CF, taskDefStackName, taskDefCloudFormation, secrets) { handleStackCreationFailure(error, CF, taskDefStackName, taskDefCloudFormation, secrets) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
core.info(JSON.stringify(secrets, undefined, 4)); cloud_runner_logger_1.default.log(JSON.stringify(secrets, undefined, 4));
core.info(taskDefCloudFormation); cloud_runner_logger_1.default.log(taskDefCloudFormation);
core.error(error); core.error(error);
core.info('Getting events and resources for task stack'); cloud_runner_logger_1.default.log('Getting events and resources for task stack');
const events = (yield CF.describeStackEvents({ StackName: taskDefStackName }).promise()).StackEvents; const events = (yield CF.describeStackEvents({ StackName: taskDefStackName }).promise()).StackEvents;
const resources = (yield CF.describeStackResources({ StackName: taskDefStackName }).promise()).StackResources; const resources = (yield CF.describeStackResources({ StackName: taskDefStackName }).promise()).StackResources;
core.info(JSON.stringify(events, undefined, 4)); cloud_runner_logger_1.default.log(JSON.stringify(events, undefined, 4));
core.info(JSON.stringify(resources, undefined, 4)); cloud_runner_logger_1.default.log(JSON.stringify(resources, undefined, 4));
}); });
} }
readTaskCloudFormationTemplate() { readTaskCloudFormationTemplate() {
@ -642,7 +643,7 @@ class AWSBuildEnvironment {
cleanupResources(CF, taskDef) { cleanupResources(CF, taskDef) {
var _a; var _a;
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
core.info('Cleanup starting'); cloud_runner_logger_1.default.log('Cleanup starting');
yield CF.deleteStack({ yield CF.deleteStack({
StackName: taskDef.taskDefStackName, StackName: taskDef.taskDefStackName,
}).promise(); }).promise();
@ -656,9 +657,9 @@ class AWSBuildEnvironment {
StackName: taskDef.taskDefStackNameTTL, StackName: taskDef.taskDefStackNameTTL,
}).promise(); }).promise();
const stacks = (_a = (yield CF.listStacks().promise()).StackSummaries) === null || _a === void 0 ? void 0 : _a.filter((x) => x.StackStatus !== 'DELETE_COMPLETE'); const stacks = (_a = (yield CF.listStacks().promise()).StackSummaries) === null || _a === void 0 ? void 0 : _a.filter((x) => x.StackStatus !== 'DELETE_COMPLETE');
core.info(`Deleted Stacks: ${taskDef.taskDefStackName}, ${taskDef.taskDefStackNameTTL}`); cloud_runner_logger_1.default.log(`Deleted Stacks: ${taskDef.taskDefStackName}, ${taskDef.taskDefStackNameTTL}`);
core.info(`Stacks: ${JSON.stringify(stacks, undefined, 4)}`); cloud_runner_logger_1.default.log(`Stacks: ${JSON.stringify(stacks, undefined, 4)}`);
core.info('Cleanup complete'); cloud_runner_logger_1.default.log('Cleanup complete');
}); });
} }
} }
@ -700,10 +701,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
step((generator = generator.apply(thisArg, _arguments || [])).next()); step((generator = generator.apply(thisArg, _arguments || [])).next());
}); });
}; };
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const AWS = __importStar(__webpack_require__(71786)); const AWS = __importStar(__webpack_require__(71786));
const core = __importStar(__webpack_require__(42186)); const core = __importStar(__webpack_require__(42186));
const zlib = __importStar(__webpack_require__(78761)); const zlib = __importStar(__webpack_require__(78761));
const cloud_runner_logger_1 = __importDefault(__webpack_require__(49899));
class AWSBuildRunner { class AWSBuildRunner {
static runTask(taskDef, ECS, CF, environment, buildGuid, commands) { static runTask(taskDef, ECS, CF, environment, buildGuid, commands) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q; var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
@ -736,7 +741,7 @@ class AWSBuildRunner {
}, },
}, },
}).promise(); }).promise();
core.info('Cloud runner job is starting'); cloud_runner_logger_1.default.log('Cloud runner job is starting');
const taskArn = ((_o = task.tasks) === null || _o === void 0 ? void 0 : _o[0].taskArn) || ''; const taskArn = ((_o = task.tasks) === null || _o === void 0 ? void 0 : _o[0].taskArn) || '';
try { try {
yield ECS.waitFor('tasksRunning', { tasks: [taskArn], cluster }).promise(); yield ECS.waitFor('tasksRunning', { tasks: [taskArn], cluster }).promise();
@ -744,20 +749,20 @@ class AWSBuildRunner {
catch (error_) { catch (error_) {
const error = error_; const error = error_;
yield new Promise((resolve) => setTimeout(resolve, 3000)); yield new Promise((resolve) => setTimeout(resolve, 3000));
core.info(`Cloud runner job has ended ${(_p = (yield AWSBuildRunner.describeTasks(ECS, cluster, taskArn)).containers) === null || _p === void 0 ? void 0 : _p[0].lastStatus}`); cloud_runner_logger_1.default.log(`Cloud runner job has ended ${(_p = (yield AWSBuildRunner.describeTasks(ECS, cluster, taskArn)).containers) === null || _p === void 0 ? void 0 : _p[0].lastStatus}`);
core.setFailed(error); core.setFailed(error);
core.error(error); core.error(error);
} }
core.info(`Cloud runner job is running`); cloud_runner_logger_1.default.log(`Cloud runner job is running`);
yield this.streamLogsUntilTaskStops(ECS, CF, taskDef, cluster, taskArn, streamName); yield this.streamLogsUntilTaskStops(ECS, CF, taskDef, cluster, taskArn, streamName);
const exitCode = (_q = (yield AWSBuildRunner.describeTasks(ECS, cluster, taskArn)).containers) === null || _q === void 0 ? void 0 : _q[0].exitCode; const exitCode = (_q = (yield AWSBuildRunner.describeTasks(ECS, cluster, taskArn)).containers) === null || _q === void 0 ? void 0 : _q[0].exitCode;
core.info(`Cloud runner job exit code ${exitCode}`); cloud_runner_logger_1.default.log(`Cloud runner job exit code ${exitCode}`);
if (exitCode !== 0) { if (exitCode !== 0) {
core.error(`job failed with exit code ${exitCode} ${JSON.stringify(yield ECS.describeTasks({ tasks: [taskArn], cluster }).promise(), undefined, 4)}`); core.error(`job failed with exit code ${exitCode} ${JSON.stringify(yield ECS.describeTasks({ tasks: [taskArn], cluster }).promise(), undefined, 4)}`);
throw new Error(`job failed with exit code ${exitCode}`); throw new Error(`job failed with exit code ${exitCode}`);
} }
else { else {
core.info(`Cloud runner job has finished successfully`); cloud_runner_logger_1.default.log(`Cloud runner job has finished successfully`);
} }
}); });
} }
@ -782,9 +787,9 @@ class AWSBuildRunner {
const kinesis = new AWS.Kinesis(); const kinesis = new AWS.Kinesis();
const stream = yield AWSBuildRunner.getLogStream(kinesis, kinesisStreamName); const stream = yield AWSBuildRunner.getLogStream(kinesis, kinesisStreamName);
let iterator = yield AWSBuildRunner.getLogIterator(kinesis, stream); let iterator = yield AWSBuildRunner.getLogIterator(kinesis, stream);
core.info(`Cloud runner job status is ${(_a = (yield AWSBuildRunner.describeTasks(ECS, clusterName, taskArn))) === null || _a === void 0 ? void 0 : _a.lastStatus}`); cloud_runner_logger_1.default.log(`Cloud runner job status is ${(_a = (yield AWSBuildRunner.describeTasks(ECS, clusterName, taskArn))) === null || _a === void 0 ? void 0 : _a.lastStatus}`);
const logBaseUrl = `https://${AWS.config.region}.console.aws.amazon.com/cloudwatch/home?region=${AWS.config.region}#logsV2:log-groups/log-group/${taskDef.taskDefStackName}`; const logBaseUrl = `https://${AWS.config.region}.console.aws.amazon.com/cloudwatch/home?region=${AWS.config.region}#logsV2:log-groups/log-group/${taskDef.taskDefStackName}`;
core.info(`You can also see the logs at AWS Cloud Watch: ${logBaseUrl}`); cloud_runner_logger_1.default.log(`You can also see the logs at AWS Cloud Watch: ${logBaseUrl}`);
let readingLogs = true; let readingLogs = true;
let timestamp = 0; let timestamp = 0;
while (readingLogs) { while (readingLogs) {
@ -810,14 +815,14 @@ class AWSBuildRunner {
static checkStreamingShouldContinue(taskData, timestamp, readingLogs) { static checkStreamingShouldContinue(taskData, timestamp, readingLogs) {
if ((taskData === null || taskData === void 0 ? void 0 : taskData.lastStatus) !== 'RUNNING') { if ((taskData === null || taskData === void 0 ? void 0 : taskData.lastStatus) !== 'RUNNING') {
if (timestamp === 0) { if (timestamp === 0) {
core.info('Cloud runner job stopped, streaming end of logs'); cloud_runner_logger_1.default.log('Cloud runner job stopped, streaming end of logs');
timestamp = Date.now(); timestamp = Date.now();
} }
if (timestamp !== 0 && Date.now() - timestamp < 30000) { if (timestamp !== 0 && Date.now() - timestamp < 30000) {
core.info('Cloud runner status is not RUNNING for 30 seconds, last query for logs'); cloud_runner_logger_1.default.log('Cloud runner status is not RUNNING for 30 seconds, last query for logs');
readingLogs = false; readingLogs = false;
} }
core.info(`Status of job: ${taskData.lastStatus}`); cloud_runner_logger_1.default.log(`Status of job: ${taskData.lastStatus}`);
} }
return { timestamp, readingLogs }; return { timestamp, readingLogs };
} }
@ -828,7 +833,7 @@ class AWSBuildRunner {
if (json.messageType === 'DATA_MESSAGE') { if (json.messageType === 'DATA_MESSAGE') {
for (let logEventsIndex = 0; logEventsIndex < json.logEvents.length; logEventsIndex++) { for (let logEventsIndex = 0; logEventsIndex < json.logEvents.length; logEventsIndex++) {
if (json.logEvents[logEventsIndex].message.includes(taskDef.logid)) { if (json.logEvents[logEventsIndex].message.includes(taskDef.logid)) {
core.info('End of cloud runner job logs'); cloud_runner_logger_1.default.log('End of cloud runner job logs');
readingLogs = false; readingLogs = false;
} }
else { else {
@ -836,7 +841,7 @@ class AWSBuildRunner {
if (message.includes('Rebuilding Library because the asset database could not be found!')) { if (message.includes('Rebuilding Library because the asset database could not be found!')) {
core.warning('LIBRARY NOT FOUND!'); core.warning('LIBRARY NOT FOUND!');
} }
core.info(message); cloud_runner_logger_1.default.log(message);
} }
} }
} }
@ -884,29 +889,7 @@ exports.default = CloudRunnerConstants;
/***/ }), /***/ }),
/***/ 93487: /***/ 49899:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const nanoid_1 = __webpack_require__(39140);
const cloud_runner_constants_1 = __importDefault(__webpack_require__(28394));
class CloudRunnerNamespace {
static generateBuildName(runNumber, platform) {
const nanoid = nanoid_1.customAlphabet(cloud_runner_constants_1.default.alphabet, 4);
return `${runNumber}-${platform.toLowerCase().replace('standalone', '')}-${nanoid()}`;
}
}
exports.default = CloudRunnerNamespace;
/***/ }),
/***/ 1669:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) { /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict"; "use strict";
@ -932,11 +915,17 @@ var __importStar = (this && this.__importStar) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const core = __importStar(__webpack_require__(42186)); const core = __importStar(__webpack_require__(42186));
class CloudRunnerTimerLogger { class CloudRunnerLogger {
static setup() { static setup() {
this.timestamp = this.createTimestamp(); this.timestamp = this.createTimestamp();
this.globalTimestamp = this.timestamp; this.globalTimestamp = this.timestamp;
} }
static log(message) {
core.info(message);
}
static error(message) {
core.error(message);
}
static logWithTime(message) { static logWithTime(message) {
const newTimestamp = this.createTimestamp(); const newTimestamp = this.createTimestamp();
core.info(`${message} (Since previous: ${this.calculateTimeDiff(newTimestamp, this.timestamp)}, Total time: ${this.calculateTimeDiff(newTimestamp, this.globalTimestamp)})`); core.info(`${message} (Since previous: ${this.calculateTimeDiff(newTimestamp, this.timestamp)}, Total time: ${this.calculateTimeDiff(newTimestamp, this.globalTimestamp)})`);
@ -949,7 +938,29 @@ class CloudRunnerTimerLogger {
return Date.now(); return Date.now();
} }
} }
exports.default = CloudRunnerTimerLogger; exports.default = CloudRunnerLogger;
/***/ }),
/***/ 93487:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const nanoid_1 = __webpack_require__(39140);
const cloud_runner_constants_1 = __importDefault(__webpack_require__(28394));
class CloudRunnerNamespace {
static generateBuildName(runNumber, platform) {
const nanoid = nanoid_1.customAlphabet(cloud_runner_constants_1.default.alphabet, 4);
return `${runNumber}-${platform.toLowerCase().replace('standalone', '')}-${nanoid()}`;
}
}
exports.default = CloudRunnerNamespace;
/***/ }), /***/ }),
@ -997,13 +1008,13 @@ const cloud_runner_namespace_1 = __importDefault(__webpack_require__(93487));
const kubernetes_build_platform_1 = __importDefault(__webpack_require__(75944)); const kubernetes_build_platform_1 = __importDefault(__webpack_require__(75944));
const image_environment_factory_1 = __importDefault(__webpack_require__(25145)); const image_environment_factory_1 = __importDefault(__webpack_require__(25145));
const yaml_1 = __importDefault(__webpack_require__(13552)); const yaml_1 = __importDefault(__webpack_require__(13552));
const cloud_runner_timer_logger_1 = __importDefault(__webpack_require__(1669)); const cloud_runner_logger_1 = __importDefault(__webpack_require__(49899));
const repositoryFolder = 'repo'; const repositoryFolder = 'repo';
const buildVolumeFolder = 'data'; const buildVolumeFolder = 'data';
const cacheFolder = 'cache'; const cacheFolder = 'cache';
class CloudRunner { class CloudRunner {
static setup(buildParameters) { static setup(buildParameters) {
cloud_runner_timer_logger_1.default.setup(); cloud_runner_logger_1.default.setup();
CloudRunner.buildGuid = cloud_runner_namespace_1.default.generateBuildName(CloudRunner.readRunNumber(), buildParameters.platform); CloudRunner.buildGuid = cloud_runner_namespace_1.default.generateBuildName(CloudRunner.readRunNumber(), buildParameters.platform);
CloudRunner.buildParams = buildParameters; CloudRunner.buildParams = buildParameters;
CloudRunner.setupBranchName(); CloudRunner.setupBranchName();
@ -1057,12 +1068,12 @@ class CloudRunner {
static setupBuildPlatform() { static setupBuildPlatform() {
switch (this.buildParams.cloudRunnerCluster) { switch (this.buildParams.cloudRunnerCluster) {
case 'aws': case 'aws':
core.info('Building with AWS'); cloud_runner_logger_1.default.log('Building with AWS');
this.CloudRunnerProviderPlatform = new aws_build_platform_1.default(this.buildParams); this.CloudRunnerProviderPlatform = new aws_build_platform_1.default(this.buildParams);
break; break;
default: default:
case 'k8s': case 'k8s':
core.info('Building with Kubernetes'); cloud_runner_logger_1.default.log('Building with Kubernetes');
this.CloudRunnerProviderPlatform = new kubernetes_build_platform_1.default(this.buildParams); this.CloudRunnerProviderPlatform = new kubernetes_build_platform_1.default(this.buildParams);
break; break;
} }
@ -1193,26 +1204,26 @@ class CloudRunner {
static runMainJob(baseImage) { static runMainJob(baseImage) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
if (this.buildParams.customBuildSteps !== '') { if (this.buildParams.customBuildSteps !== '') {
core.info(`Cloud Runner is running in standard build automation mode`); cloud_runner_logger_1.default.log(`Cloud Runner is running in standard build automation mode`);
yield CloudRunner.standardBuildAutomation(baseImage); yield CloudRunner.standardBuildAutomation(baseImage);
} }
else { else {
core.info(`Cloud Runner is running in custom job mode`); cloud_runner_logger_1.default.log(`Cloud Runner is running in custom job mode`);
yield CloudRunner.runCustomJob(this.buildParams.customBuildSteps); yield CloudRunner.runCustomJob(this.buildParams.customBuildSteps);
} }
}); });
} }
static standardBuildAutomation(baseImage) { static standardBuildAutomation(baseImage) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
cloud_runner_timer_logger_1.default.logWithTime('Pre build steps time'); cloud_runner_logger_1.default.logWithTime('Pre build steps time');
yield this.runCustomJob(this.buildParams.preBuildSteps); yield this.runCustomJob(this.buildParams.preBuildSteps);
cloud_runner_timer_logger_1.default.logWithTime('Setup time'); cloud_runner_logger_1.default.logWithTime('Setup time');
yield CloudRunner.BuildStep(baseImage); yield CloudRunner.BuildStep(baseImage);
cloud_runner_timer_logger_1.default.logWithTime('Build time'); cloud_runner_logger_1.default.logWithTime('Build time');
yield CloudRunner.CompressionStep(); yield CloudRunner.CompressionStep();
cloud_runner_timer_logger_1.default.logWithTime('Compression time'); cloud_runner_logger_1.default.logWithTime('Compression time');
yield this.runCustomJob(this.buildParams.postBuildSteps); yield this.runCustomJob(this.buildParams.postBuildSteps);
cloud_runner_timer_logger_1.default.logWithTime('Post build steps time'); cloud_runner_logger_1.default.logWithTime('Post build steps time');
}); });
} }
static runCustomJob(buildSteps) { static runCustomJob(buildSteps) {
@ -1233,7 +1244,7 @@ class CloudRunner {
} }
static setupStep() { static setupStep() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
core.info('Starting step 1/4 clone and restore cache)'); cloud_runner_logger_1.default.log('Starting step 1/4 clone and restore cache)');
yield this.CloudRunnerProviderPlatform.runBuildTask(this.buildGuid, 'alpine/git', [ yield this.CloudRunnerProviderPlatform.runBuildTask(this.buildGuid, 'alpine/git', [
` printenv ` printenv
apk update -q apk update -q
@ -1255,7 +1266,7 @@ class CloudRunner {
} }
static BuildStep(baseImage) { static BuildStep(baseImage) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
core.info('Starting part 2/4 (build unity project)'); cloud_runner_logger_1.default.log('Starting part 2/4 (build unity project)');
yield this.CloudRunnerProviderPlatform.runBuildTask(this.buildGuid, baseImage.toString(), [ yield this.CloudRunnerProviderPlatform.runBuildTask(this.buildGuid, baseImage.toString(), [
` `
printenv printenv
@ -1274,7 +1285,7 @@ class CloudRunner {
} }
static CompressionStep() { static CompressionStep() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
core.info('Starting step 3/4 build compression'); cloud_runner_logger_1.default.log('Starting step 3/4 build compression');
// Cleanup // Cleanup
yield this.CloudRunnerProviderPlatform.runBuildTask(this.buildGuid, 'alpine', [ yield this.CloudRunnerProviderPlatform.runBuildTask(this.buildGuid, 'alpine', [
` `
@ -1304,7 +1315,7 @@ class CloudRunner {
}, },
], ],
], this.defaultSecrets); ], this.defaultSecrets);
core.info('compression step complete'); cloud_runner_logger_1.default.log('compression step complete');
}); });
} }
static cleanupSharedBuildResources() { static cleanupSharedBuildResources() {
@ -1314,7 +1325,7 @@ class CloudRunner {
} }
static handleException(error) { static handleException(error) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
core.error(JSON.stringify(error, undefined, 4)); cloud_runner_logger_1.default.error(JSON.stringify(error, undefined, 4));
core.setFailed('Remote Builder failed'); core.setFailed('Remote Builder failed');
yield this.CloudRunnerProviderPlatform.cleanupSharedBuildResources(this.buildGuid, this.buildParams, this.branchName, this.defaultSecrets); yield this.CloudRunnerProviderPlatform.cleanupSharedBuildResources(this.buildGuid, this.buildParams, this.branchName, this.defaultSecrets);
}); });
@ -1377,6 +1388,7 @@ const kubernetes_utils_1 = __importDefault(__webpack_require__(35306));
const async_wait_until_1 = __importDefault(__webpack_require__(41299)); const async_wait_until_1 = __importDefault(__webpack_require__(41299));
const kubernetes_job_spec_factory_1 = __importDefault(__webpack_require__(24418)); const kubernetes_job_spec_factory_1 = __importDefault(__webpack_require__(24418));
const kubernetes_service_account_1 = __importDefault(__webpack_require__(12871)); const kubernetes_service_account_1 = __importDefault(__webpack_require__(12871));
const cloud_runner_logger_1 = __importDefault(__webpack_require__(49899));
class Kubernetes { class Kubernetes {
constructor(buildParameters) { constructor(buildParameters) {
this.buildGuid = ''; this.buildGuid = '';
@ -1392,7 +1404,7 @@ class Kubernetes {
this.kubeClient = this.kubeConfig.makeApiClient(k8s.CoreV1Api); this.kubeClient = this.kubeConfig.makeApiClient(k8s.CoreV1Api);
this.kubeClientBatch = this.kubeConfig.makeApiClient(k8s.BatchV1Api); this.kubeClientBatch = this.kubeConfig.makeApiClient(k8s.BatchV1Api);
this.kubeClientBatchBeta = this.kubeConfig.makeApiClient(k8s.BatchV1beta1Api); this.kubeClientBatchBeta = this.kubeConfig.makeApiClient(k8s.BatchV1beta1Api);
core.info('Loaded default Kubernetes configuration for this environment'); cloud_runner_logger_1.default.log('Loaded default Kubernetes configuration for this environment');
this.namespace = 'default'; this.namespace = 'default';
this.buildParameters = buildParameters; this.buildParameters = buildParameters;
} }
@ -1425,18 +1437,18 @@ class Kubernetes {
yield kubernetes_secret_1.default.createSecret(secrets, this.secretName, this.namespace, this.kubeClient); yield kubernetes_secret_1.default.createSecret(secrets, this.secretName, this.namespace, this.kubeClient);
const jobSpec = kubernetes_job_spec_factory_1.default.getJobSpec(commands, image, mountdir, workingdir, environment, this.buildGuid, this.buildParameters, this.secretName, this.pvcName, this.jobName, k8s); const jobSpec = kubernetes_job_spec_factory_1.default.getJobSpec(commands, image, mountdir, workingdir, environment, this.buildGuid, this.buildParameters, this.secretName, this.pvcName, this.jobName, k8s);
//run //run
core.info('Creating build job'); cloud_runner_logger_1.default.log('Creating build job');
yield this.kubeClientBatch.createNamespacedJob(this.namespace, jobSpec); yield this.kubeClientBatch.createNamespacedJob(this.namespace, jobSpec);
core.info('Job created'); cloud_runner_logger_1.default.log('Job created');
this.setPodNameAndContainerName(yield kubernetes_utils_1.default.findPodFromJob(this.kubeClient, this.jobName, this.namespace)); this.setPodNameAndContainerName(yield kubernetes_utils_1.default.findPodFromJob(this.kubeClient, this.jobName, this.namespace));
core.info('Watching pod until running'); cloud_runner_logger_1.default.log('Watching pod until running');
yield kubernetes_utils_1.default.watchUntilPodRunning(this.kubeClient, this.podName, this.namespace); yield kubernetes_utils_1.default.watchUntilPodRunning(this.kubeClient, this.podName, this.namespace);
core.info('Pod running, streaming logs'); cloud_runner_logger_1.default.log('Pod running, streaming logs');
yield kubernetes_logging_1.default.streamLogs(this.kubeConfig, this.kubeClient, this.jobName, this.podName, 'main', this.namespace, core.info); yield kubernetes_logging_1.default.streamLogs(this.kubeConfig, this.kubeClient, this.jobName, this.podName, 'main', this.namespace, cloud_runner_logger_1.default.log);
yield this.cleanupTaskResources(); yield this.cleanupTaskResources();
} }
catch (error) { catch (error) {
core.info('Running job failed'); cloud_runner_logger_1.default.log('Running job failed');
core.error(JSON.stringify(error, undefined, 4)); core.error(JSON.stringify(error, undefined, 4));
yield this.cleanupTaskResources(); yield this.cleanupTaskResources();
throw error; throw error;
@ -1450,15 +1462,15 @@ class Kubernetes {
} }
cleanupTaskResources() { cleanupTaskResources() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
core.info('cleaning up'); cloud_runner_logger_1.default.log('cleaning up');
try { try {
yield this.kubeClientBatch.deleteNamespacedJob(this.jobName, this.namespace); yield this.kubeClientBatch.deleteNamespacedJob(this.jobName, this.namespace);
yield this.kubeClient.deleteNamespacedSecret(this.secretName, this.namespace); yield this.kubeClient.deleteNamespacedSecret(this.secretName, this.namespace);
} }
catch (error) { catch (error) {
core.info('Failed to cleanup, error:'); cloud_runner_logger_1.default.log('Failed to cleanup, error:');
core.error(JSON.stringify(error, undefined, 4)); core.error(JSON.stringify(error, undefined, 4));
core.info('Abandoning cleanup, build error:'); cloud_runner_logger_1.default.log('Abandoning cleanup, build error:');
throw error; throw error;
} }
try { try {
@ -1468,7 +1480,7 @@ class Kubernetes {
}); });
} }
catch (_a) { catch (_a) {
core.info('failed to read the state of the job while cleaning up?'); cloud_runner_logger_1.default.log('failed to read the state of the job while cleaning up?');
} }
}); });
} }
@ -1644,25 +1656,6 @@ exports.default = KubernetesJobSpecFactory;
"use strict"; "use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) { return new (P || (P = Promise))(function (resolve, reject) {
@ -1672,14 +1665,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
step((generator = generator.apply(thisArg, _arguments || [])).next()); step((generator = generator.apply(thisArg, _arguments || [])).next());
}); });
}; };
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const client_node_1 = __webpack_require__(89679); const client_node_1 = __webpack_require__(89679);
const stream_1 = __webpack_require__(92413); const stream_1 = __webpack_require__(92413);
const core = __importStar(__webpack_require__(42186)); const cloud_runner_logger_1 = __importDefault(__webpack_require__(49899));
class KubernetesLogging { class KubernetesLogging {
static streamLogs(kubeConfig, kubeClient, jobName, podName, containerName, namespace, logCallback) { static streamLogs(kubeConfig, kubeClient, jobName, podName, containerName, namespace, logCallback) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
core.info(`Streaming logs from pod: ${podName} container: ${containerName} namespace: ${namespace}`); cloud_runner_logger_1.default.log(`Streaming logs from pod: ${podName} container: ${containerName} namespace: ${namespace}`);
const stream = new stream_1.Writable(); const stream = new stream_1.Writable();
let didStreamAnyLogs = false; let didStreamAnyLogs = false;
stream._write = (chunk, encoding, next) => { stream._write = (chunk, encoding, next) => {
@ -1717,7 +1713,7 @@ class KubernetesLogging {
catch (error) { catch (error) {
throw error; throw error;
} }
core.info('end of log stream'); cloud_runner_logger_1.default.log('end of log stream');
}); });
} }
} }
@ -1890,23 +1886,24 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
const async_wait_until_1 = __importDefault(__webpack_require__(41299)); const async_wait_until_1 = __importDefault(__webpack_require__(41299));
const core = __importStar(__webpack_require__(42186)); const core = __importStar(__webpack_require__(42186));
const k8s = __importStar(__webpack_require__(89679)); const k8s = __importStar(__webpack_require__(89679));
const cloud_runner_logger_1 = __importDefault(__webpack_require__(49899));
class KubernetesStorage { class KubernetesStorage {
static createPersistentVolumeClaim(buildParameters, pvcName, kubeClient, namespace) { static createPersistentVolumeClaim(buildParameters, pvcName, kubeClient, namespace) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
if (buildParameters.kubeVolume) { if (buildParameters.kubeVolume) {
core.info(buildParameters.kubeVolume); cloud_runner_logger_1.default.log(buildParameters.kubeVolume);
pvcName = buildParameters.kubeVolume; pvcName = buildParameters.kubeVolume;
return; return;
} }
const pvcList = (yield kubeClient.listNamespacedPersistentVolumeClaim(namespace)).body.items.map((x) => { var _a; return (_a = x.metadata) === null || _a === void 0 ? void 0 : _a.name; }); const pvcList = (yield kubeClient.listNamespacedPersistentVolumeClaim(namespace)).body.items.map((x) => { var _a; return (_a = x.metadata) === null || _a === void 0 ? void 0 : _a.name; });
core.info(`Current PVCs in namespace ${namespace}`); cloud_runner_logger_1.default.log(`Current PVCs in namespace ${namespace}`);
core.info(JSON.stringify(pvcList, undefined, 4)); cloud_runner_logger_1.default.log(JSON.stringify(pvcList, undefined, 4));
if (pvcList.includes(pvcName)) { if (pvcList.includes(pvcName)) {
core.info(`pvc ${pvcName} already exists`); cloud_runner_logger_1.default.log(`pvc ${pvcName} already exists`);
core.setOutput('volume', pvcName); core.setOutput('volume', pvcName);
return; return;
} }
core.info(`Creating PVC ${pvcName} (does not exist)`); cloud_runner_logger_1.default.log(`Creating PVC ${pvcName} (does not exist)`);
const result = yield KubernetesStorage.createPVC(pvcName, buildParameters, kubeClient, namespace); const result = yield KubernetesStorage.createPVC(pvcName, buildParameters, kubeClient, namespace);
yield KubernetesStorage.handleResult(result, kubeClient, namespace, pvcName); yield KubernetesStorage.handleResult(result, kubeClient, namespace, pvcName);
}); });
@ -1927,8 +1924,8 @@ class KubernetesStorage {
static watchUntilPVCNotPending(kubeClient, name, namespace) { static watchUntilPVCNotPending(kubeClient, name, namespace) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
try { try {
core.info(`watch Until PVC Not Pending ${name} ${namespace}`); cloud_runner_logger_1.default.log(`watch Until PVC Not Pending ${name} ${namespace}`);
core.info(`${yield this.getPVCPhase(kubeClient, name, namespace)}`); cloud_runner_logger_1.default.log(`${yield this.getPVCPhase(kubeClient, name, namespace)}`);
yield async_wait_until_1.default(() => __awaiter(this, void 0, void 0, function* () { yield async_wait_until_1.default(() => __awaiter(this, void 0, void 0, function* () {
return (yield this.getPVCPhase(kubeClient, name, namespace)) !== 'Pending'; return (yield this.getPVCPhase(kubeClient, name, namespace)) !== 'Pending';
}), { }), {
@ -1972,10 +1969,10 @@ class KubernetesStorage {
const name = (_a = result.body.metadata) === null || _a === void 0 ? void 0 : _a.name; const name = (_a = result.body.metadata) === null || _a === void 0 ? void 0 : _a.name;
if (!name) if (!name)
throw new Error('failed to create PVC'); throw new Error('failed to create PVC');
core.info(JSON.stringify(yield kubeClient.readNamespacedPersistentVolumeClaim(name, namespace), undefined, 4)); cloud_runner_logger_1.default.log(JSON.stringify(yield kubeClient.readNamespacedPersistentVolumeClaim(name, namespace), undefined, 4));
core.info(`PVC ${name} created`); cloud_runner_logger_1.default.log(`PVC ${name} created`);
yield this.watchUntilPVCNotPending(kubeClient, name, namespace); yield this.watchUntilPVCNotPending(kubeClient, name, namespace);
core.info(`PVC ${name} is ready and not pending`); cloud_runner_logger_1.default.log(`PVC ${name} is ready and not pending`);
core.setOutput('volume', pvcName); core.setOutput('volume', pvcName);
}); });
} }
@ -1990,25 +1987,6 @@ exports.default = KubernetesStorage;
"use strict"; "use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) { return new (P || (P = Promise))(function (resolve, reject) {
@ -2023,7 +2001,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const async_wait_until_1 = __importDefault(__webpack_require__(41299)); const async_wait_until_1 = __importDefault(__webpack_require__(41299));
const core = __importStar(__webpack_require__(42186)); const cloud_runner_logger_1 = __importDefault(__webpack_require__(49899));
class KubernetesUtilities { class KubernetesUtilities {
static findPodFromJob(kubeClient, jobName, namespace) { static findPodFromJob(kubeClient, jobName, namespace) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
@ -2037,7 +2015,7 @@ class KubernetesUtilities {
static watchUntilPodRunning(kubeClient, podName, namespace) { static watchUntilPodRunning(kubeClient, podName, namespace) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
let success = false; let success = false;
core.info(`Watching ${podName} ${namespace}`); cloud_runner_logger_1.default.log(`Watching ${podName} ${namespace}`);
yield async_wait_until_1.default(() => __awaiter(this, void 0, void 0, function* () { yield async_wait_until_1.default(() => __awaiter(this, void 0, void 0, function* () {
var _a, _b; var _a, _b;
const phase = (_b = (_a = (yield kubeClient.readNamespacedPodStatus(podName, namespace))) === null || _a === void 0 ? void 0 : _a.body.status) === null || _b === void 0 ? void 0 : _b.phase; const phase = (_b = (_a = (yield kubeClient.readNamespacedPodStatus(podName, namespace))) === null || _a === void 0 ? void 0 : _a.body.status) === null || _b === void 0 ? void 0 : _b.phase;

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -9,6 +9,7 @@ import CloudRunnerConstants from './cloud-runner-constants';
import AWSBuildRunner from './aws-build-runner'; import AWSBuildRunner from './aws-build-runner';
import { CloudRunnerProviderInterface } from './cloud-runner-provider-interface'; import { CloudRunnerProviderInterface } from './cloud-runner-provider-interface';
import BuildParameters from '../build-parameters'; import BuildParameters from '../build-parameters';
import CloudRunnerLogger from './cloud-runner-logger';
const crypto = require('crypto'); const crypto = require('crypto');
class AWSBuildEnvironment implements CloudRunnerProviderInterface { class AWSBuildEnvironment implements CloudRunnerProviderInterface {
@ -65,14 +66,14 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
let t2; let t2;
try { try {
const t1 = Date.now(); const t1 = Date.now();
core.info(`Setup job time: ${Math.floor((t1 - t0) / 1000)}s`); CloudRunnerLogger.log(`Setup job time: ${Math.floor((t1 - t0) / 1000)}s`);
await AWSBuildRunner.runTask(taskDef, ECS, CF, environment, buildId, commands); await AWSBuildRunner.runTask(taskDef, ECS, CF, environment, buildId, commands);
t2 = Date.now(); t2 = Date.now();
core.info(`Run job time: ${Math.floor((t2 - t1) / 1000)}s`); CloudRunnerLogger.log(`Run job time: ${Math.floor((t2 - t1) / 1000)}s`);
} finally { } finally {
await this.cleanupResources(CF, taskDef); await this.cleanupResources(CF, taskDef);
const t3 = Date.now(); const t3 = Date.now();
if (t2 !== undefined) core.info(`Cleanup job time: ${Math.floor((t3 - t2) / 1000)}s`); if (t2 !== undefined) CloudRunnerLogger.log(`Cleanup job time: ${Math.floor((t3 - t2) / 1000)}s`);
} }
} }
@ -196,7 +197,7 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
...secretsMappedToCloudFormationParameters, ...secretsMappedToCloudFormationParameters,
], ],
}).promise(); }).promise();
core.info('Creating cloud runner job'); CloudRunnerLogger.log('Creating cloud runner job');
await CF.createStack({ await CF.createStack({
StackName: cleanupTaskDefStackName, StackName: cleanupTaskDefStackName,
TemplateBody: cleanupCloudFormation, TemplateBody: cleanupCloudFormation,
@ -224,7 +225,7 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
}, },
], ],
}).promise(); }).promise();
// Side effect: core.info('Creating cleanup double checker cron job...'); // Side effect: CloudRunnerLogger.log('Creating cleanup double checker cron job...');
await CF.waitFor('stackCreateComplete', { StackName: taskDefStackName }).promise(); await CF.waitFor('stackCreateComplete', { StackName: taskDefStackName }).promise();
} catch (error) { } catch (error) {
@ -296,9 +297,9 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
}; };
try { try {
if (!stackExists) { if (!stackExists) {
core.info(`${baseStackName} stack does not exist (${JSON.stringify(stacks)})`); CloudRunnerLogger.log(`${baseStackName} stack does not exist (${JSON.stringify(stacks)})`);
await CF.createStack(createStackInput).promise(); await CF.createStack(createStackInput).promise();
core.info(`created stack (version: ${hash})`); CloudRunnerLogger.log(`created stack (version: ${hash})`);
} }
const CFState = await describeStack(); const CFState = await describeStack();
let stack = CFState.Stacks?.[0]; let stack = CFState.Stacks?.[0];
@ -312,12 +313,12 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
} }
if (stackExists) { if (stackExists) {
core.info(`Base stack exists (version: ${stackVersion}, local version: ${hash})`); CloudRunnerLogger.log(`Base stack exists (version: ${stackVersion}, local version: ${hash})`);
if (hash !== stackVersion) { if (hash !== stackVersion) {
core.info(`Updating`); CloudRunnerLogger.log(`Updating`);
await CF.updateStack(updateInput).promise(); await CF.updateStack(updateInput).promise();
} else { } else {
core.info(`No update required`); CloudRunnerLogger.log(`No update required`);
} }
stack = (await describeStack()).Stacks?.[0]; stack = (await describeStack()).Stacks?.[0];
if (!stack) { if (!stack) {
@ -329,7 +330,7 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
await CF.waitFor('stackUpdateComplete', describeStackInput).promise(); await CF.waitFor('stackUpdateComplete', describeStackInput).promise();
} }
} }
core.info('base stack is ready'); CloudRunnerLogger.log('base stack is ready');
} catch (error) { } catch (error) {
core.error(JSON.stringify(await describeStack(), undefined, 4)); core.error(JSON.stringify(await describeStack(), undefined, 4));
throw error; throw error;
@ -343,14 +344,14 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
taskDefCloudFormation: string, taskDefCloudFormation: string,
secrets: CloudRunnerSecret[], secrets: CloudRunnerSecret[],
) { ) {
core.info(JSON.stringify(secrets, undefined, 4)); CloudRunnerLogger.log(JSON.stringify(secrets, undefined, 4));
core.info(taskDefCloudFormation); CloudRunnerLogger.log(taskDefCloudFormation);
core.error(error); core.error(error);
core.info('Getting events and resources for task stack'); CloudRunnerLogger.log('Getting events and resources for task stack');
const events = (await CF.describeStackEvents({ StackName: taskDefStackName }).promise()).StackEvents; const events = (await CF.describeStackEvents({ StackName: taskDefStackName }).promise()).StackEvents;
const resources = (await CF.describeStackResources({ StackName: taskDefStackName }).promise()).StackResources; const resources = (await CF.describeStackResources({ StackName: taskDefStackName }).promise()).StackResources;
core.info(JSON.stringify(events, undefined, 4)); CloudRunnerLogger.log(JSON.stringify(events, undefined, 4));
core.info(JSON.stringify(resources, undefined, 4)); CloudRunnerLogger.log(JSON.stringify(resources, undefined, 4));
} }
readTaskCloudFormationTemplate(): string { readTaskCloudFormationTemplate(): string {
@ -358,7 +359,7 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
} }
async cleanupResources(CF: SDK.CloudFormation, taskDef: CloudRunnerTaskDef) { async cleanupResources(CF: SDK.CloudFormation, taskDef: CloudRunnerTaskDef) {
core.info('Cleanup starting'); CloudRunnerLogger.log('Cleanup starting');
await CF.deleteStack({ await CF.deleteStack({
StackName: taskDef.taskDefStackName, StackName: taskDef.taskDefStackName,
}).promise(); }).promise();
@ -375,10 +376,10 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
const stacks = (await CF.listStacks().promise()).StackSummaries?.filter((x) => x.StackStatus !== 'DELETE_COMPLETE'); const stacks = (await CF.listStacks().promise()).StackSummaries?.filter((x) => x.StackStatus !== 'DELETE_COMPLETE');
core.info(`Deleted Stacks: ${taskDef.taskDefStackName}, ${taskDef.taskDefStackNameTTL}`); CloudRunnerLogger.log(`Deleted Stacks: ${taskDef.taskDefStackName}, ${taskDef.taskDefStackNameTTL}`);
core.info(`Stacks: ${JSON.stringify(stacks, undefined, 4)}`); CloudRunnerLogger.log(`Stacks: ${JSON.stringify(stacks, undefined, 4)}`);
core.info('Cleanup complete'); CloudRunnerLogger.log('Cleanup complete');
} }
} }
export default AWSBuildEnvironment; export default AWSBuildEnvironment;

View File

@ -3,6 +3,7 @@ import CloudRunnerEnvironmentVariable from './cloud-runner-environment-variable'
import * as core from '@actions/core'; import * as core from '@actions/core';
import CloudRunnerTaskDef from './cloud-runner-task-def'; import CloudRunnerTaskDef from './cloud-runner-task-def';
import * as zlib from 'zlib'; import * as zlib from 'zlib';
import CloudRunnerLogger from './cloud-runner-logger';
class AWSBuildRunner { class AWSBuildRunner {
static async runTask( static async runTask(
@ -48,7 +49,7 @@ class AWSBuildRunner {
}, },
}).promise(); }).promise();
core.info('Cloud runner job is starting'); CloudRunnerLogger.log('Cloud runner job is starting');
const taskArn = task.tasks?.[0].taskArn || ''; const taskArn = task.tasks?.[0].taskArn || '';
try { try {
@ -56,7 +57,7 @@ class AWSBuildRunner {
} catch (error_) { } catch (error_) {
const error = error_ as Error; const error = error_ as Error;
await new Promise((resolve) => setTimeout(resolve, 3000)); await new Promise((resolve) => setTimeout(resolve, 3000));
core.info( CloudRunnerLogger.log(
`Cloud runner job has ended ${ `Cloud runner job has ended ${
(await AWSBuildRunner.describeTasks(ECS, cluster, taskArn)).containers?.[0].lastStatus (await AWSBuildRunner.describeTasks(ECS, cluster, taskArn)).containers?.[0].lastStatus
}`, }`,
@ -65,10 +66,10 @@ class AWSBuildRunner {
core.setFailed(error); core.setFailed(error);
core.error(error); core.error(error);
} }
core.info(`Cloud runner job is running`); CloudRunnerLogger.log(`Cloud runner job is running`);
await this.streamLogsUntilTaskStops(ECS, CF, taskDef, cluster, taskArn, streamName); await this.streamLogsUntilTaskStops(ECS, CF, taskDef, cluster, taskArn, streamName);
const exitCode = (await AWSBuildRunner.describeTasks(ECS, cluster, taskArn)).containers?.[0].exitCode; const exitCode = (await AWSBuildRunner.describeTasks(ECS, cluster, taskArn)).containers?.[0].exitCode;
core.info(`Cloud runner job exit code ${exitCode}`); CloudRunnerLogger.log(`Cloud runner job exit code ${exitCode}`);
if (exitCode !== 0) { if (exitCode !== 0) {
core.error( core.error(
`job failed with exit code ${exitCode} ${JSON.stringify( `job failed with exit code ${exitCode} ${JSON.stringify(
@ -79,7 +80,7 @@ class AWSBuildRunner {
); );
throw new Error(`job failed with exit code ${exitCode}`); throw new Error(`job failed with exit code ${exitCode}`);
} else { } else {
core.info(`Cloud runner job has finished successfully`); CloudRunnerLogger.log(`Cloud runner job has finished successfully`);
} }
} }
@ -107,12 +108,12 @@ class AWSBuildRunner {
const stream = await AWSBuildRunner.getLogStream(kinesis, kinesisStreamName); const stream = await AWSBuildRunner.getLogStream(kinesis, kinesisStreamName);
let iterator = await AWSBuildRunner.getLogIterator(kinesis, stream); let iterator = await AWSBuildRunner.getLogIterator(kinesis, stream);
core.info( CloudRunnerLogger.log(
`Cloud runner job status is ${(await AWSBuildRunner.describeTasks(ECS, clusterName, taskArn))?.lastStatus}`, `Cloud runner job status is ${(await AWSBuildRunner.describeTasks(ECS, clusterName, taskArn))?.lastStatus}`,
); );
const logBaseUrl = `https://${AWS.config.region}.console.aws.amazon.com/cloudwatch/home?region=${AWS.config.region}#logsV2:log-groups/log-group/${taskDef.taskDefStackName}`; const logBaseUrl = `https://${AWS.config.region}.console.aws.amazon.com/cloudwatch/home?region=${AWS.config.region}#logsV2:log-groups/log-group/${taskDef.taskDefStackName}`;
core.info(`You can also see the logs at AWS Cloud Watch: ${logBaseUrl}`); CloudRunnerLogger.log(`You can also see the logs at AWS Cloud Watch: ${logBaseUrl}`);
let readingLogs = true; let readingLogs = true;
let timestamp: number = 0; let timestamp: number = 0;
while (readingLogs) { while (readingLogs) {
@ -147,14 +148,14 @@ class AWSBuildRunner {
private static checkStreamingShouldContinue(taskData: AWS.ECS.Task, timestamp: number, readingLogs: boolean) { private static checkStreamingShouldContinue(taskData: AWS.ECS.Task, timestamp: number, readingLogs: boolean) {
if (taskData?.lastStatus !== 'RUNNING') { if (taskData?.lastStatus !== 'RUNNING') {
if (timestamp === 0) { if (timestamp === 0) {
core.info('Cloud runner job stopped, streaming end of logs'); CloudRunnerLogger.log('Cloud runner job stopped, streaming end of logs');
timestamp = Date.now(); timestamp = Date.now();
} }
if (timestamp !== 0 && Date.now() - timestamp < 30000) { if (timestamp !== 0 && Date.now() - timestamp < 30000) {
core.info('Cloud runner status is not RUNNING for 30 seconds, last query for logs'); CloudRunnerLogger.log('Cloud runner status is not RUNNING for 30 seconds, last query for logs');
readingLogs = false; readingLogs = false;
} }
core.info(`Status of job: ${taskData.lastStatus}`); CloudRunnerLogger.log(`Status of job: ${taskData.lastStatus}`);
} }
return { timestamp, readingLogs }; return { timestamp, readingLogs };
} }
@ -168,14 +169,14 @@ class AWSBuildRunner {
if (json.messageType === 'DATA_MESSAGE') { if (json.messageType === 'DATA_MESSAGE') {
for (let logEventsIndex = 0; logEventsIndex < json.logEvents.length; logEventsIndex++) { for (let logEventsIndex = 0; logEventsIndex < json.logEvents.length; logEventsIndex++) {
if (json.logEvents[logEventsIndex].message.includes(taskDef.logid)) { if (json.logEvents[logEventsIndex].message.includes(taskDef.logid)) {
core.info('End of cloud runner job logs'); CloudRunnerLogger.log('End of cloud runner job logs');
readingLogs = false; readingLogs = false;
} else { } else {
const message = json.logEvents[logEventsIndex].message; const message = json.logEvents[logEventsIndex].message;
if (message.includes('Rebuilding Library because the asset database could not be found!')) { if (message.includes('Rebuilding Library because the asset database could not be found!')) {
core.warning('LIBRARY NOT FOUND!'); core.warning('LIBRARY NOT FOUND!');
} }
core.info(message); CloudRunnerLogger.log(message);
} }
} }
} }

View File

@ -1,6 +1,6 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
class CloudRunnerTimerLogger { class CloudRunnerLogger {
private static timestamp: number; private static timestamp: number;
private static globalTimestamp: number; private static globalTimestamp: number;
@ -9,6 +9,14 @@ class CloudRunnerTimerLogger {
this.globalTimestamp = this.timestamp; this.globalTimestamp = this.timestamp;
} }
public static log(message: string) {
core.info(message);
}
public static error(message: string) {
core.error(message);
}
public static logWithTime(message: string) { public static logWithTime(message: string) {
const newTimestamp = this.createTimestamp(); const newTimestamp = this.createTimestamp();
core.info( core.info(
@ -28,4 +36,4 @@ class CloudRunnerTimerLogger {
return Date.now(); return Date.now();
} }
} }
export default CloudRunnerTimerLogger; export default CloudRunnerLogger;

View File

@ -8,7 +8,7 @@ import Kubernetes from './kubernetes-build-platform';
import CloudRunnerEnvironmentVariable from './cloud-runner-environment-variable'; import CloudRunnerEnvironmentVariable from './cloud-runner-environment-variable';
import ImageEnvironmentFactory from '../image-environment-factory'; import ImageEnvironmentFactory from '../image-environment-factory';
import YAML from 'yaml'; import YAML from 'yaml';
import CloudRunnerTimerLogger from './cloud-runner-timer-logger'; import CloudRunnerLogger from './cloud-runner-logger';
const repositoryFolder = 'repo'; const repositoryFolder = 'repo';
const buildVolumeFolder = 'data'; const buildVolumeFolder = 'data';
const cacheFolder = 'cache'; const cacheFolder = 'cache';
@ -39,7 +39,7 @@ class CloudRunner {
]; ];
private static setup(buildParameters: BuildParameters) { private static setup(buildParameters: BuildParameters) {
CloudRunnerTimerLogger.setup(); CloudRunnerLogger.setup();
CloudRunner.buildGuid = CloudRunnerNamespace.generateBuildName( CloudRunner.buildGuid = CloudRunnerNamespace.generateBuildName(
CloudRunner.readRunNumber(), CloudRunner.readRunNumber(),
buildParameters.platform, buildParameters.platform,
@ -103,12 +103,12 @@ class CloudRunner {
private static setupBuildPlatform() { private static setupBuildPlatform() {
switch (this.buildParams.cloudRunnerCluster) { switch (this.buildParams.cloudRunnerCluster) {
case 'aws': case 'aws':
core.info('Building with AWS'); CloudRunnerLogger.log('Building with AWS');
this.CloudRunnerProviderPlatform = new AWSBuildPlatform(this.buildParams); this.CloudRunnerProviderPlatform = new AWSBuildPlatform(this.buildParams);
break; break;
default: default:
case 'k8s': case 'k8s':
core.info('Building with Kubernetes'); CloudRunnerLogger.log('Building with Kubernetes');
this.CloudRunnerProviderPlatform = new Kubernetes(this.buildParams); this.CloudRunnerProviderPlatform = new Kubernetes(this.buildParams);
break; break;
} }
@ -247,24 +247,24 @@ class CloudRunner {
private static async runMainJob(baseImage: any) { private static async runMainJob(baseImage: any) {
if (this.buildParams.customBuildSteps !== '') { if (this.buildParams.customBuildSteps !== '') {
core.info(`Cloud Runner is running in standard build automation mode`); CloudRunnerLogger.log(`Cloud Runner is running in standard build automation mode`);
await CloudRunner.standardBuildAutomation(baseImage); await CloudRunner.standardBuildAutomation(baseImage);
} else { } else {
core.info(`Cloud Runner is running in custom job mode`); CloudRunnerLogger.log(`Cloud Runner is running in custom job mode`);
await CloudRunner.runCustomJob(this.buildParams.customBuildSteps); await CloudRunner.runCustomJob(this.buildParams.customBuildSteps);
} }
} }
private static async standardBuildAutomation(baseImage: any) { private static async standardBuildAutomation(baseImage: any) {
CloudRunnerTimerLogger.logWithTime('Pre build steps time'); CloudRunnerLogger.logWithTime('Pre build steps time');
await this.runCustomJob(this.buildParams.preBuildSteps); await this.runCustomJob(this.buildParams.preBuildSteps);
CloudRunnerTimerLogger.logWithTime('Setup time'); CloudRunnerLogger.logWithTime('Setup time');
await CloudRunner.BuildStep(baseImage); await CloudRunner.BuildStep(baseImage);
CloudRunnerTimerLogger.logWithTime('Build time'); CloudRunnerLogger.logWithTime('Build time');
await CloudRunner.CompressionStep(); await CloudRunner.CompressionStep();
CloudRunnerTimerLogger.logWithTime('Compression time'); CloudRunnerLogger.logWithTime('Compression time');
await this.runCustomJob(this.buildParams.postBuildSteps); await this.runCustomJob(this.buildParams.postBuildSteps);
CloudRunnerTimerLogger.logWithTime('Post build steps time'); CloudRunnerLogger.logWithTime('Post build steps time');
} }
private static async runCustomJob(buildSteps) { private static async runCustomJob(buildSteps) {
@ -291,7 +291,7 @@ class CloudRunner {
} }
private static async setupStep() { private static async setupStep() {
core.info('Starting step 1/4 clone and restore cache)'); CloudRunnerLogger.log('Starting step 1/4 clone and restore cache)');
await this.CloudRunnerProviderPlatform.runBuildTask( await this.CloudRunnerProviderPlatform.runBuildTask(
this.buildGuid, this.buildGuid,
'alpine/git', 'alpine/git',
@ -320,7 +320,7 @@ class CloudRunner {
} }
private static async BuildStep(baseImage: any) { private static async BuildStep(baseImage: any) {
core.info('Starting part 2/4 (build unity project)'); CloudRunnerLogger.log('Starting part 2/4 (build unity project)');
await this.CloudRunnerProviderPlatform.runBuildTask( await this.CloudRunnerProviderPlatform.runBuildTask(
this.buildGuid, this.buildGuid,
baseImage.toString(), baseImage.toString(),
@ -346,7 +346,7 @@ class CloudRunner {
} }
private static async CompressionStep() { private static async CompressionStep() {
core.info('Starting step 3/4 build compression'); CloudRunnerLogger.log('Starting step 3/4 build compression');
// Cleanup // Cleanup
await this.CloudRunnerProviderPlatform.runBuildTask( await this.CloudRunnerProviderPlatform.runBuildTask(
this.buildGuid, this.buildGuid,
@ -384,7 +384,7 @@ class CloudRunner {
], ],
this.defaultSecrets, this.defaultSecrets,
); );
core.info('compression step complete'); CloudRunnerLogger.log('compression step complete');
} }
private static async cleanupSharedBuildResources() { private static async cleanupSharedBuildResources() {
@ -397,7 +397,7 @@ class CloudRunner {
} }
private static async handleException(error: unknown) { private static async handleException(error: unknown) {
core.error(JSON.stringify(error, undefined, 4)); CloudRunnerLogger.error(JSON.stringify(error, undefined, 4));
core.setFailed('Remote Builder failed'); core.setFailed('Remote Builder failed');
await this.CloudRunnerProviderPlatform.cleanupSharedBuildResources( await this.CloudRunnerProviderPlatform.cleanupSharedBuildResources(
this.buildGuid, this.buildGuid,

View File

@ -11,6 +11,7 @@ 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 KubernetesJobSpecFactory from './kubernetes-job-spec-factory';
import KubernetesServiceAccount from './kubernetes-service-account'; import KubernetesServiceAccount from './kubernetes-service-account';
import CloudRunnerLogger from './cloud-runner-logger';
class Kubernetes implements CloudRunnerProviderInterface { class Kubernetes implements CloudRunnerProviderInterface {
private kubeConfig: k8s.KubeConfig; private kubeConfig: k8s.KubeConfig;
@ -34,7 +35,7 @@ class Kubernetes implements CloudRunnerProviderInterface {
this.kubeClient = this.kubeConfig.makeApiClient(k8s.CoreV1Api); this.kubeClient = this.kubeConfig.makeApiClient(k8s.CoreV1Api);
this.kubeClientBatch = this.kubeConfig.makeApiClient(k8s.BatchV1Api); this.kubeClientBatch = this.kubeConfig.makeApiClient(k8s.BatchV1Api);
this.kubeClientBatchBeta = this.kubeConfig.makeApiClient(k8s.BatchV1beta1Api); this.kubeClientBatchBeta = this.kubeConfig.makeApiClient(k8s.BatchV1beta1Api);
core.info('Loaded default Kubernetes configuration for this environment'); CloudRunnerLogger.log('Loaded default Kubernetes configuration for this environment');
this.namespace = 'default'; this.namespace = 'default';
this.buildParameters = buildParameters; this.buildParameters = buildParameters;
@ -95,15 +96,15 @@ class Kubernetes implements CloudRunnerProviderInterface {
); );
//run //run
core.info('Creating build job'); CloudRunnerLogger.log('Creating build job');
await this.kubeClientBatch.createNamespacedJob(this.namespace, jobSpec); await this.kubeClientBatch.createNamespacedJob(this.namespace, jobSpec);
core.info('Job created'); CloudRunnerLogger.log('Job created');
this.setPodNameAndContainerName( this.setPodNameAndContainerName(
await KubernetesUtilities.findPodFromJob(this.kubeClient, this.jobName, this.namespace), await KubernetesUtilities.findPodFromJob(this.kubeClient, this.jobName, this.namespace),
); );
core.info('Watching pod until running'); CloudRunnerLogger.log('Watching pod until running');
await KubernetesUtilities.watchUntilPodRunning(this.kubeClient, this.podName, this.namespace); await KubernetesUtilities.watchUntilPodRunning(this.kubeClient, this.podName, this.namespace);
core.info('Pod running, streaming logs'); CloudRunnerLogger.log('Pod running, streaming logs');
await KubernetesLogging.streamLogs( await KubernetesLogging.streamLogs(
this.kubeConfig, this.kubeConfig,
this.kubeClient, this.kubeClient,
@ -111,11 +112,11 @@ class Kubernetes implements CloudRunnerProviderInterface {
this.podName, this.podName,
'main', 'main',
this.namespace, this.namespace,
core.info, CloudRunnerLogger.log,
); );
await this.cleanupTaskResources(); await this.cleanupTaskResources();
} catch (error) { } catch (error) {
core.info('Running job failed'); CloudRunnerLogger.log('Running job failed');
core.error(JSON.stringify(error, undefined, 4)); core.error(JSON.stringify(error, undefined, 4));
await this.cleanupTaskResources(); await this.cleanupTaskResources();
throw error; throw error;
@ -128,14 +129,14 @@ class Kubernetes implements CloudRunnerProviderInterface {
} }
async cleanupTaskResources() { async cleanupTaskResources() {
core.info('cleaning up'); CloudRunnerLogger.log('cleaning up');
try { try {
await this.kubeClientBatch.deleteNamespacedJob(this.jobName, this.namespace); await this.kubeClientBatch.deleteNamespacedJob(this.jobName, this.namespace);
await this.kubeClient.deleteNamespacedSecret(this.secretName, this.namespace); await this.kubeClient.deleteNamespacedSecret(this.secretName, this.namespace);
} catch (error) { } catch (error) {
core.info('Failed to cleanup, error:'); CloudRunnerLogger.log('Failed to cleanup, error:');
core.error(JSON.stringify(error, undefined, 4)); core.error(JSON.stringify(error, undefined, 4));
core.info('Abandoning cleanup, build error:'); CloudRunnerLogger.log('Abandoning cleanup, build error:');
throw error; throw error;
} }
try { try {
@ -147,7 +148,7 @@ class Kubernetes implements CloudRunnerProviderInterface {
}, },
); );
} catch { } catch {
core.info('failed to read the state of the job while cleaning up?'); CloudRunnerLogger.log('failed to read the state of the job while cleaning up?');
} }
} }

View File

@ -1,6 +1,6 @@
import { CoreV1Api, KubeConfig, Log } from '@kubernetes/client-node'; import { CoreV1Api, KubeConfig, Log } from '@kubernetes/client-node';
import { Writable } from 'stream'; import { Writable } from 'stream';
import * as core from '@actions/core'; import CloudRunnerLogger from './cloud-runner-logger';
class KubernetesLogging { class KubernetesLogging {
static async streamLogs( static async streamLogs(
@ -12,7 +12,7 @@ class KubernetesLogging {
namespace: string, namespace: string,
logCallback: any, logCallback: any,
) { ) {
core.info(`Streaming logs from pod: ${podName} container: ${containerName} namespace: ${namespace}`); CloudRunnerLogger.log(`Streaming logs from pod: ${podName} container: ${containerName} namespace: ${namespace}`);
const stream = new Writable(); const stream = new Writable();
let didStreamAnyLogs: boolean = false; let didStreamAnyLogs: boolean = false;
stream._write = (chunk, encoding, next) => { stream._write = (chunk, encoding, next) => {
@ -57,7 +57,7 @@ class KubernetesLogging {
} catch (error) { } catch (error) {
throw error; throw error;
} }
core.info('end of log stream'); CloudRunnerLogger.log('end of log stream');
} }
} }

View File

@ -2,6 +2,7 @@ import waitUntil from 'async-wait-until';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as k8s from '@kubernetes/client-node'; import * as k8s from '@kubernetes/client-node';
import BuildParameters from '../build-parameters'; import BuildParameters from '../build-parameters';
import CloudRunnerLogger from './cloud-runner-logger';
class KubernetesStorage { class KubernetesStorage {
public static async createPersistentVolumeClaim( public static async createPersistentVolumeClaim(
@ -11,21 +12,21 @@ class KubernetesStorage {
namespace: string, namespace: string,
) { ) {
if (buildParameters.kubeVolume) { if (buildParameters.kubeVolume) {
core.info(buildParameters.kubeVolume); CloudRunnerLogger.log(buildParameters.kubeVolume);
pvcName = buildParameters.kubeVolume; pvcName = buildParameters.kubeVolume;
return; return;
} }
const pvcList = (await kubeClient.listNamespacedPersistentVolumeClaim(namespace)).body.items.map( const pvcList = (await kubeClient.listNamespacedPersistentVolumeClaim(namespace)).body.items.map(
(x) => x.metadata?.name, (x) => x.metadata?.name,
); );
core.info(`Current PVCs in namespace ${namespace}`); CloudRunnerLogger.log(`Current PVCs in namespace ${namespace}`);
core.info(JSON.stringify(pvcList, undefined, 4)); CloudRunnerLogger.log(JSON.stringify(pvcList, undefined, 4));
if (pvcList.includes(pvcName)) { if (pvcList.includes(pvcName)) {
core.info(`pvc ${pvcName} already exists`); CloudRunnerLogger.log(`pvc ${pvcName} already exists`);
core.setOutput('volume', pvcName); core.setOutput('volume', pvcName);
return; return;
} }
core.info(`Creating PVC ${pvcName} (does not exist)`); CloudRunnerLogger.log(`Creating PVC ${pvcName} (does not exist)`);
const result = await KubernetesStorage.createPVC(pvcName, buildParameters, kubeClient, namespace); const result = await KubernetesStorage.createPVC(pvcName, buildParameters, kubeClient, namespace);
await KubernetesStorage.handleResult(result, kubeClient, namespace, pvcName); await KubernetesStorage.handleResult(result, kubeClient, namespace, pvcName);
} }
@ -42,8 +43,8 @@ class KubernetesStorage {
public static async watchUntilPVCNotPending(kubeClient: k8s.CoreV1Api, name: string, namespace: string) { public static async watchUntilPVCNotPending(kubeClient: k8s.CoreV1Api, name: string, namespace: string) {
try { try {
core.info(`watch Until PVC Not Pending ${name} ${namespace}`); CloudRunnerLogger.log(`watch Until PVC Not Pending ${name} ${namespace}`);
core.info(`${await this.getPVCPhase(kubeClient, name, namespace)}`); CloudRunnerLogger.log(`${await this.getPVCPhase(kubeClient, name, namespace)}`);
await waitUntil( await waitUntil(
async () => { async () => {
return (await this.getPVCPhase(kubeClient, name, namespace)) !== 'Pending'; return (await this.getPVCPhase(kubeClient, name, namespace)) !== 'Pending';
@ -101,10 +102,12 @@ class KubernetesStorage {
) { ) {
const name = result.body.metadata?.name; const name = result.body.metadata?.name;
if (!name) throw new Error('failed to create PVC'); if (!name) throw new Error('failed to create PVC');
core.info(JSON.stringify(await kubeClient.readNamespacedPersistentVolumeClaim(name, namespace), undefined, 4)); CloudRunnerLogger.log(
core.info(`PVC ${name} created`); JSON.stringify(await kubeClient.readNamespacedPersistentVolumeClaim(name, namespace), undefined, 4),
);
CloudRunnerLogger.log(`PVC ${name} created`);
await this.watchUntilPVCNotPending(kubeClient, name, namespace); await this.watchUntilPVCNotPending(kubeClient, name, namespace);
core.info(`PVC ${name} is ready and not pending`); CloudRunnerLogger.log(`PVC ${name} is ready and not pending`);
core.setOutput('volume', pvcName); core.setOutput('volume', pvcName);
} }
} }

View File

@ -1,6 +1,6 @@
import { CoreV1Api } from '@kubernetes/client-node'; import { CoreV1Api } from '@kubernetes/client-node';
import waitUntil from 'async-wait-until'; import waitUntil from 'async-wait-until';
import * as core from '@actions/core'; import CloudRunnerLogger from './cloud-runner-logger';
class KubernetesUtilities { class KubernetesUtilities {
static async findPodFromJob(kubeClient: CoreV1Api, jobName: string, namespace: string) { static async findPodFromJob(kubeClient: CoreV1Api, jobName: string, namespace: string) {
@ -15,7 +15,7 @@ class KubernetesUtilities {
static async watchUntilPodRunning(kubeClient: CoreV1Api, podName: string, namespace: string) { static async watchUntilPodRunning(kubeClient: CoreV1Api, podName: string, namespace: string) {
let success: boolean = false; let success: boolean = false;
core.info(`Watching ${podName} ${namespace}`); CloudRunnerLogger.log(`Watching ${podName} ${namespace}`);
await waitUntil( await waitUntil(
async () => { async () => {
const phase = (await kubeClient.readNamespacedPodStatus(podName, namespace))?.body.status?.phase; const phase = (await kubeClient.readNamespacedPodStatus(podName, namespace))?.body.status?.phase;