Logging cleanup
parent
9712dddf10
commit
e802849d30
|
|
@ -355,6 +355,7 @@ const fs = __importStar(__webpack_require__(35747));
|
|||
const core = __importStar(__webpack_require__(42186));
|
||||
const cloud_runner_constants_1 = __importDefault(__webpack_require__(28394));
|
||||
const aws_build_runner_1 = __importDefault(__webpack_require__(83230));
|
||||
const cloud_runner_logger_1 = __importDefault(__webpack_require__(49899));
|
||||
const crypto = __webpack_require__(33373);
|
||||
class AWSBuildEnvironment {
|
||||
constructor(buildParameters) {
|
||||
|
|
@ -388,16 +389,16 @@ class AWSBuildEnvironment {
|
|||
let t2;
|
||||
try {
|
||||
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);
|
||||
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 {
|
||||
yield this.cleanupResources(CF, taskDef);
|
||||
const t3 = Date.now();
|
||||
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,
|
||||
],
|
||||
}).promise();
|
||||
core.info('Creating cloud runner job');
|
||||
cloud_runner_logger_1.default.log('Creating cloud runner job');
|
||||
yield CF.createStack({
|
||||
StackName: cleanupTaskDefStackName,
|
||||
TemplateBody: cleanupCloudFormation,
|
||||
|
|
@ -523,7 +524,7 @@ class AWSBuildEnvironment {
|
|||
},
|
||||
],
|
||||
}).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();
|
||||
}
|
||||
catch (error) {
|
||||
|
|
@ -586,9 +587,9 @@ class AWSBuildEnvironment {
|
|||
});
|
||||
try {
|
||||
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();
|
||||
core.info(`created stack (version: ${hash})`);
|
||||
cloud_runner_logger_1.default.log(`created stack (version: ${hash})`);
|
||||
}
|
||||
const CFState = yield describeStack();
|
||||
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();
|
||||
}
|
||||
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) {
|
||||
core.info(`Updating`);
|
||||
cloud_runner_logger_1.default.log(`Updating`);
|
||||
yield CF.updateStack(updateInput).promise();
|
||||
}
|
||||
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];
|
||||
if (!stack) {
|
||||
|
|
@ -616,7 +617,7 @@ class AWSBuildEnvironment {
|
|||
yield CF.waitFor('stackUpdateComplete', describeStackInput).promise();
|
||||
}
|
||||
}
|
||||
core.info('base stack is ready');
|
||||
cloud_runner_logger_1.default.log('base stack is ready');
|
||||
}
|
||||
catch (error) {
|
||||
core.error(JSON.stringify(yield describeStack(), undefined, 4));
|
||||
|
|
@ -626,14 +627,14 @@ class AWSBuildEnvironment {
|
|||
}
|
||||
handleStackCreationFailure(error, CF, taskDefStackName, taskDefCloudFormation, secrets) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
core.info(JSON.stringify(secrets, undefined, 4));
|
||||
core.info(taskDefCloudFormation);
|
||||
cloud_runner_logger_1.default.log(JSON.stringify(secrets, undefined, 4));
|
||||
cloud_runner_logger_1.default.log(taskDefCloudFormation);
|
||||
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 resources = (yield CF.describeStackResources({ StackName: taskDefStackName }).promise()).StackResources;
|
||||
core.info(JSON.stringify(events, undefined, 4));
|
||||
core.info(JSON.stringify(resources, undefined, 4));
|
||||
cloud_runner_logger_1.default.log(JSON.stringify(events, undefined, 4));
|
||||
cloud_runner_logger_1.default.log(JSON.stringify(resources, undefined, 4));
|
||||
});
|
||||
}
|
||||
readTaskCloudFormationTemplate() {
|
||||
|
|
@ -642,7 +643,7 @@ class AWSBuildEnvironment {
|
|||
cleanupResources(CF, taskDef) {
|
||||
var _a;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
core.info('Cleanup starting');
|
||||
cloud_runner_logger_1.default.log('Cleanup starting');
|
||||
yield CF.deleteStack({
|
||||
StackName: taskDef.taskDefStackName,
|
||||
}).promise();
|
||||
|
|
@ -656,9 +657,9 @@ class AWSBuildEnvironment {
|
|||
StackName: taskDef.taskDefStackNameTTL,
|
||||
}).promise();
|
||||
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}`);
|
||||
core.info(`Stacks: ${JSON.stringify(stacks, undefined, 4)}`);
|
||||
core.info('Cleanup complete');
|
||||
cloud_runner_logger_1.default.log(`Deleted Stacks: ${taskDef.taskDefStackName}, ${taskDef.taskDefStackNameTTL}`);
|
||||
cloud_runner_logger_1.default.log(`Stacks: ${JSON.stringify(stacks, undefined, 4)}`);
|
||||
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());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
const AWS = __importStar(__webpack_require__(71786));
|
||||
const core = __importStar(__webpack_require__(42186));
|
||||
const zlib = __importStar(__webpack_require__(78761));
|
||||
const cloud_runner_logger_1 = __importDefault(__webpack_require__(49899));
|
||||
class AWSBuildRunner {
|
||||
static runTask(taskDef, ECS, CF, environment, buildGuid, commands) {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
||||
|
|
@ -736,7 +741,7 @@ class AWSBuildRunner {
|
|||
},
|
||||
},
|
||||
}).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) || '';
|
||||
try {
|
||||
yield ECS.waitFor('tasksRunning', { tasks: [taskArn], cluster }).promise();
|
||||
|
|
@ -744,20 +749,20 @@ class AWSBuildRunner {
|
|||
catch (error_) {
|
||||
const error = error_;
|
||||
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.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);
|
||||
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) {
|
||||
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}`);
|
||||
}
|
||||
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 stream = yield AWSBuildRunner.getLogStream(kinesis, kinesisStreamName);
|
||||
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}`;
|
||||
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 timestamp = 0;
|
||||
while (readingLogs) {
|
||||
|
|
@ -810,14 +815,14 @@ class AWSBuildRunner {
|
|||
static checkStreamingShouldContinue(taskData, timestamp, readingLogs) {
|
||||
if ((taskData === null || taskData === void 0 ? void 0 : taskData.lastStatus) !== 'RUNNING') {
|
||||
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();
|
||||
}
|
||||
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;
|
||||
}
|
||||
core.info(`Status of job: ${taskData.lastStatus}`);
|
||||
cloud_runner_logger_1.default.log(`Status of job: ${taskData.lastStatus}`);
|
||||
}
|
||||
return { timestamp, readingLogs };
|
||||
}
|
||||
|
|
@ -828,7 +833,7 @@ class AWSBuildRunner {
|
|||
if (json.messageType === 'DATA_MESSAGE') {
|
||||
for (let logEventsIndex = 0; logEventsIndex < json.logEvents.length; logEventsIndex++) {
|
||||
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;
|
||||
}
|
||||
else {
|
||||
|
|
@ -836,7 +841,7 @@ class AWSBuildRunner {
|
|||
if (message.includes('Rebuilding Library because the asset database could not be found!')) {
|
||||
core.warning('LIBRARY NOT FOUND!');
|
||||
}
|
||||
core.info(message);
|
||||
cloud_runner_logger_1.default.log(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -884,29 +889,7 @@ exports.default = CloudRunnerConstants;
|
|||
|
||||
/***/ }),
|
||||
|
||||
/***/ 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;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 1669:
|
||||
/***/ 49899:
|
||||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
|
@ -932,11 +915,17 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
const core = __importStar(__webpack_require__(42186));
|
||||
class CloudRunnerTimerLogger {
|
||||
class CloudRunnerLogger {
|
||||
static setup() {
|
||||
this.timestamp = this.createTimestamp();
|
||||
this.globalTimestamp = this.timestamp;
|
||||
}
|
||||
static log(message) {
|
||||
core.info(message);
|
||||
}
|
||||
static error(message) {
|
||||
core.error(message);
|
||||
}
|
||||
static logWithTime(message) {
|
||||
const newTimestamp = this.createTimestamp();
|
||||
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();
|
||||
}
|
||||
}
|
||||
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 image_environment_factory_1 = __importDefault(__webpack_require__(25145));
|
||||
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 buildVolumeFolder = 'data';
|
||||
const cacheFolder = 'cache';
|
||||
class CloudRunner {
|
||||
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.buildParams = buildParameters;
|
||||
CloudRunner.setupBranchName();
|
||||
|
|
@ -1057,12 +1068,12 @@ class CloudRunner {
|
|||
static setupBuildPlatform() {
|
||||
switch (this.buildParams.cloudRunnerCluster) {
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1193,26 +1204,26 @@ class CloudRunner {
|
|||
static runMainJob(baseImage) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
static standardBuildAutomation(baseImage) {
|
||||
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);
|
||||
cloud_runner_timer_logger_1.default.logWithTime('Setup time');
|
||||
cloud_runner_logger_1.default.logWithTime('Setup time');
|
||||
yield CloudRunner.BuildStep(baseImage);
|
||||
cloud_runner_timer_logger_1.default.logWithTime('Build time');
|
||||
cloud_runner_logger_1.default.logWithTime('Build time');
|
||||
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);
|
||||
cloud_runner_timer_logger_1.default.logWithTime('Post build steps time');
|
||||
cloud_runner_logger_1.default.logWithTime('Post build steps time');
|
||||
});
|
||||
}
|
||||
static runCustomJob(buildSteps) {
|
||||
|
|
@ -1233,7 +1244,7 @@ class CloudRunner {
|
|||
}
|
||||
static setupStep() {
|
||||
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', [
|
||||
` printenv
|
||||
apk update -q
|
||||
|
|
@ -1255,7 +1266,7 @@ class CloudRunner {
|
|||
}
|
||||
static BuildStep(baseImage) {
|
||||
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(), [
|
||||
`
|
||||
printenv
|
||||
|
|
@ -1274,7 +1285,7 @@ class CloudRunner {
|
|||
}
|
||||
static CompressionStep() {
|
||||
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
|
||||
yield this.CloudRunnerProviderPlatform.runBuildTask(this.buildGuid, 'alpine', [
|
||||
`
|
||||
|
|
@ -1304,7 +1315,7 @@ class CloudRunner {
|
|||
},
|
||||
],
|
||||
], this.defaultSecrets);
|
||||
core.info('compression step complete');
|
||||
cloud_runner_logger_1.default.log('compression step complete');
|
||||
});
|
||||
}
|
||||
static cleanupSharedBuildResources() {
|
||||
|
|
@ -1314,7 +1325,7 @@ class CloudRunner {
|
|||
}
|
||||
static handleException(error) {
|
||||
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');
|
||||
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 kubernetes_job_spec_factory_1 = __importDefault(__webpack_require__(24418));
|
||||
const kubernetes_service_account_1 = __importDefault(__webpack_require__(12871));
|
||||
const cloud_runner_logger_1 = __importDefault(__webpack_require__(49899));
|
||||
class Kubernetes {
|
||||
constructor(buildParameters) {
|
||||
this.buildGuid = '';
|
||||
|
|
@ -1392,7 +1404,7 @@ class Kubernetes {
|
|||
this.kubeClient = this.kubeConfig.makeApiClient(k8s.CoreV1Api);
|
||||
this.kubeClientBatch = this.kubeConfig.makeApiClient(k8s.BatchV1Api);
|
||||
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.buildParameters = buildParameters;
|
||||
}
|
||||
|
|
@ -1425,18 +1437,18 @@ class Kubernetes {
|
|||
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);
|
||||
//run
|
||||
core.info('Creating build job');
|
||||
cloud_runner_logger_1.default.log('Creating build job');
|
||||
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));
|
||||
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);
|
||||
core.info('Pod running, streaming logs');
|
||||
yield kubernetes_logging_1.default.streamLogs(this.kubeConfig, this.kubeClient, this.jobName, this.podName, 'main', this.namespace, core.info);
|
||||
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, cloud_runner_logger_1.default.log);
|
||||
yield this.cleanupTaskResources();
|
||||
}
|
||||
catch (error) {
|
||||
core.info('Running job failed');
|
||||
cloud_runner_logger_1.default.log('Running job failed');
|
||||
core.error(JSON.stringify(error, undefined, 4));
|
||||
yield this.cleanupTaskResources();
|
||||
throw error;
|
||||
|
|
@ -1450,15 +1462,15 @@ class Kubernetes {
|
|||
}
|
||||
cleanupTaskResources() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
core.info('cleaning up');
|
||||
cloud_runner_logger_1.default.log('cleaning up');
|
||||
try {
|
||||
yield this.kubeClientBatch.deleteNamespacedJob(this.jobName, this.namespace);
|
||||
yield this.kubeClient.deleteNamespacedSecret(this.secretName, this.namespace);
|
||||
}
|
||||
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.info('Abandoning cleanup, build error:');
|
||||
cloud_runner_logger_1.default.log('Abandoning cleanup, build error:');
|
||||
throw error;
|
||||
}
|
||||
try {
|
||||
|
|
@ -1468,7 +1480,7 @@ class Kubernetes {
|
|||
});
|
||||
}
|
||||
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";
|
||||
|
||||
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) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
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());
|
||||
});
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
const client_node_1 = __webpack_require__(89679);
|
||||
const stream_1 = __webpack_require__(92413);
|
||||
const core = __importStar(__webpack_require__(42186));
|
||||
const cloud_runner_logger_1 = __importDefault(__webpack_require__(49899));
|
||||
class KubernetesLogging {
|
||||
static streamLogs(kubeConfig, kubeClient, jobName, podName, containerName, namespace, logCallback) {
|
||||
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();
|
||||
let didStreamAnyLogs = false;
|
||||
stream._write = (chunk, encoding, next) => {
|
||||
|
|
@ -1717,7 +1713,7 @@ class KubernetesLogging {
|
|||
catch (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 core = __importStar(__webpack_require__(42186));
|
||||
const k8s = __importStar(__webpack_require__(89679));
|
||||
const cloud_runner_logger_1 = __importDefault(__webpack_require__(49899));
|
||||
class KubernetesStorage {
|
||||
static createPersistentVolumeClaim(buildParameters, pvcName, kubeClient, namespace) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (buildParameters.kubeVolume) {
|
||||
core.info(buildParameters.kubeVolume);
|
||||
cloud_runner_logger_1.default.log(buildParameters.kubeVolume);
|
||||
pvcName = buildParameters.kubeVolume;
|
||||
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; });
|
||||
core.info(`Current PVCs in namespace ${namespace}`);
|
||||
core.info(JSON.stringify(pvcList, undefined, 4));
|
||||
cloud_runner_logger_1.default.log(`Current PVCs in namespace ${namespace}`);
|
||||
cloud_runner_logger_1.default.log(JSON.stringify(pvcList, undefined, 4));
|
||||
if (pvcList.includes(pvcName)) {
|
||||
core.info(`pvc ${pvcName} already exists`);
|
||||
cloud_runner_logger_1.default.log(`pvc ${pvcName} already exists`);
|
||||
core.setOutput('volume', pvcName);
|
||||
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);
|
||||
yield KubernetesStorage.handleResult(result, kubeClient, namespace, pvcName);
|
||||
});
|
||||
|
|
@ -1927,8 +1924,8 @@ class KubernetesStorage {
|
|||
static watchUntilPVCNotPending(kubeClient, name, namespace) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
core.info(`watch Until PVC Not Pending ${name} ${namespace}`);
|
||||
core.info(`${yield this.getPVCPhase(kubeClient, name, namespace)}`);
|
||||
cloud_runner_logger_1.default.log(`watch Until PVC Not Pending ${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* () {
|
||||
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;
|
||||
if (!name)
|
||||
throw new Error('failed to create PVC');
|
||||
core.info(JSON.stringify(yield kubeClient.readNamespacedPersistentVolumeClaim(name, namespace), undefined, 4));
|
||||
core.info(`PVC ${name} created`);
|
||||
cloud_runner_logger_1.default.log(JSON.stringify(yield kubeClient.readNamespacedPersistentVolumeClaim(name, namespace), undefined, 4));
|
||||
cloud_runner_logger_1.default.log(`PVC ${name} created`);
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
|
@ -1990,25 +1987,6 @@ exports.default = KubernetesStorage;
|
|||
|
||||
"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) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
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 }));
|
||||
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 {
|
||||
static findPodFromJob(kubeClient, jobName, namespace) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
|
|
@ -2037,7 +2015,7 @@ class KubernetesUtilities {
|
|||
static watchUntilPodRunning(kubeClient, podName, namespace) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
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* () {
|
||||
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;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -9,6 +9,7 @@ import CloudRunnerConstants from './cloud-runner-constants';
|
|||
import AWSBuildRunner from './aws-build-runner';
|
||||
import { CloudRunnerProviderInterface } from './cloud-runner-provider-interface';
|
||||
import BuildParameters from '../build-parameters';
|
||||
import CloudRunnerLogger from './cloud-runner-logger';
|
||||
const crypto = require('crypto');
|
||||
|
||||
class AWSBuildEnvironment implements CloudRunnerProviderInterface {
|
||||
|
|
@ -65,14 +66,14 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
|
|||
let t2;
|
||||
try {
|
||||
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);
|
||||
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 {
|
||||
await this.cleanupResources(CF, taskDef);
|
||||
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,
|
||||
],
|
||||
}).promise();
|
||||
core.info('Creating cloud runner job');
|
||||
CloudRunnerLogger.log('Creating cloud runner job');
|
||||
await CF.createStack({
|
||||
StackName: cleanupTaskDefStackName,
|
||||
TemplateBody: cleanupCloudFormation,
|
||||
|
|
@ -224,7 +225,7 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
|
|||
},
|
||||
],
|
||||
}).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();
|
||||
} catch (error) {
|
||||
|
|
@ -296,9 +297,9 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
|
|||
};
|
||||
try {
|
||||
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();
|
||||
core.info(`created stack (version: ${hash})`);
|
||||
CloudRunnerLogger.log(`created stack (version: ${hash})`);
|
||||
}
|
||||
const CFState = await describeStack();
|
||||
let stack = CFState.Stacks?.[0];
|
||||
|
|
@ -312,12 +313,12 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
|
|||
}
|
||||
|
||||
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) {
|
||||
core.info(`Updating`);
|
||||
CloudRunnerLogger.log(`Updating`);
|
||||
await CF.updateStack(updateInput).promise();
|
||||
} else {
|
||||
core.info(`No update required`);
|
||||
CloudRunnerLogger.log(`No update required`);
|
||||
}
|
||||
stack = (await describeStack()).Stacks?.[0];
|
||||
if (!stack) {
|
||||
|
|
@ -329,7 +330,7 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
|
|||
await CF.waitFor('stackUpdateComplete', describeStackInput).promise();
|
||||
}
|
||||
}
|
||||
core.info('base stack is ready');
|
||||
CloudRunnerLogger.log('base stack is ready');
|
||||
} catch (error) {
|
||||
core.error(JSON.stringify(await describeStack(), undefined, 4));
|
||||
throw error;
|
||||
|
|
@ -343,14 +344,14 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
|
|||
taskDefCloudFormation: string,
|
||||
secrets: CloudRunnerSecret[],
|
||||
) {
|
||||
core.info(JSON.stringify(secrets, undefined, 4));
|
||||
core.info(taskDefCloudFormation);
|
||||
CloudRunnerLogger.log(JSON.stringify(secrets, undefined, 4));
|
||||
CloudRunnerLogger.log(taskDefCloudFormation);
|
||||
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 resources = (await CF.describeStackResources({ StackName: taskDefStackName }).promise()).StackResources;
|
||||
core.info(JSON.stringify(events, undefined, 4));
|
||||
core.info(JSON.stringify(resources, undefined, 4));
|
||||
CloudRunnerLogger.log(JSON.stringify(events, undefined, 4));
|
||||
CloudRunnerLogger.log(JSON.stringify(resources, undefined, 4));
|
||||
}
|
||||
|
||||
readTaskCloudFormationTemplate(): string {
|
||||
|
|
@ -358,7 +359,7 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
|
|||
}
|
||||
|
||||
async cleanupResources(CF: SDK.CloudFormation, taskDef: CloudRunnerTaskDef) {
|
||||
core.info('Cleanup starting');
|
||||
CloudRunnerLogger.log('Cleanup starting');
|
||||
await CF.deleteStack({
|
||||
StackName: taskDef.taskDefStackName,
|
||||
}).promise();
|
||||
|
|
@ -375,10 +376,10 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface {
|
|||
|
||||
const stacks = (await CF.listStacks().promise()).StackSummaries?.filter((x) => x.StackStatus !== 'DELETE_COMPLETE');
|
||||
|
||||
core.info(`Deleted Stacks: ${taskDef.taskDefStackName}, ${taskDef.taskDefStackNameTTL}`);
|
||||
core.info(`Stacks: ${JSON.stringify(stacks, undefined, 4)}`);
|
||||
CloudRunnerLogger.log(`Deleted Stacks: ${taskDef.taskDefStackName}, ${taskDef.taskDefStackNameTTL}`);
|
||||
CloudRunnerLogger.log(`Stacks: ${JSON.stringify(stacks, undefined, 4)}`);
|
||||
|
||||
core.info('Cleanup complete');
|
||||
CloudRunnerLogger.log('Cleanup complete');
|
||||
}
|
||||
}
|
||||
export default AWSBuildEnvironment;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import CloudRunnerEnvironmentVariable from './cloud-runner-environment-variable'
|
|||
import * as core from '@actions/core';
|
||||
import CloudRunnerTaskDef from './cloud-runner-task-def';
|
||||
import * as zlib from 'zlib';
|
||||
import CloudRunnerLogger from './cloud-runner-logger';
|
||||
|
||||
class AWSBuildRunner {
|
||||
static async runTask(
|
||||
|
|
@ -48,7 +49,7 @@ class AWSBuildRunner {
|
|||
},
|
||||
}).promise();
|
||||
|
||||
core.info('Cloud runner job is starting');
|
||||
CloudRunnerLogger.log('Cloud runner job is starting');
|
||||
const taskArn = task.tasks?.[0].taskArn || '';
|
||||
|
||||
try {
|
||||
|
|
@ -56,7 +57,7 @@ class AWSBuildRunner {
|
|||
} catch (error_) {
|
||||
const error = error_ as Error;
|
||||
await new Promise((resolve) => setTimeout(resolve, 3000));
|
||||
core.info(
|
||||
CloudRunnerLogger.log(
|
||||
`Cloud runner job has ended ${
|
||||
(await AWSBuildRunner.describeTasks(ECS, cluster, taskArn)).containers?.[0].lastStatus
|
||||
}`,
|
||||
|
|
@ -65,10 +66,10 @@ class AWSBuildRunner {
|
|||
core.setFailed(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);
|
||||
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) {
|
||||
core.error(
|
||||
`job failed with exit code ${exitCode} ${JSON.stringify(
|
||||
|
|
@ -79,7 +80,7 @@ class AWSBuildRunner {
|
|||
);
|
||||
throw new Error(`job failed with exit code ${exitCode}`);
|
||||
} 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);
|
||||
let iterator = await AWSBuildRunner.getLogIterator(kinesis, stream);
|
||||
|
||||
core.info(
|
||||
CloudRunnerLogger.log(
|
||||
`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}`;
|
||||
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 timestamp: number = 0;
|
||||
while (readingLogs) {
|
||||
|
|
@ -147,14 +148,14 @@ class AWSBuildRunner {
|
|||
private static checkStreamingShouldContinue(taskData: AWS.ECS.Task, timestamp: number, readingLogs: boolean) {
|
||||
if (taskData?.lastStatus !== 'RUNNING') {
|
||||
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();
|
||||
}
|
||||
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;
|
||||
}
|
||||
core.info(`Status of job: ${taskData.lastStatus}`);
|
||||
CloudRunnerLogger.log(`Status of job: ${taskData.lastStatus}`);
|
||||
}
|
||||
return { timestamp, readingLogs };
|
||||
}
|
||||
|
|
@ -168,14 +169,14 @@ class AWSBuildRunner {
|
|||
if (json.messageType === 'DATA_MESSAGE') {
|
||||
for (let logEventsIndex = 0; logEventsIndex < json.logEvents.length; logEventsIndex++) {
|
||||
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;
|
||||
} else {
|
||||
const message = json.logEvents[logEventsIndex].message;
|
||||
if (message.includes('Rebuilding Library because the asset database could not be found!')) {
|
||||
core.warning('LIBRARY NOT FOUND!');
|
||||
}
|
||||
core.info(message);
|
||||
CloudRunnerLogger.log(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import * as core from '@actions/core';
|
||||
|
||||
class CloudRunnerTimerLogger {
|
||||
class CloudRunnerLogger {
|
||||
private static timestamp: number;
|
||||
private static globalTimestamp: number;
|
||||
|
||||
|
|
@ -9,6 +9,14 @@ class CloudRunnerTimerLogger {
|
|||
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) {
|
||||
const newTimestamp = this.createTimestamp();
|
||||
core.info(
|
||||
|
|
@ -28,4 +36,4 @@ class CloudRunnerTimerLogger {
|
|||
return Date.now();
|
||||
}
|
||||
}
|
||||
export default CloudRunnerTimerLogger;
|
||||
export default CloudRunnerLogger;
|
||||
|
|
@ -8,7 +8,7 @@ import Kubernetes from './kubernetes-build-platform';
|
|||
import CloudRunnerEnvironmentVariable from './cloud-runner-environment-variable';
|
||||
import ImageEnvironmentFactory from '../image-environment-factory';
|
||||
import YAML from 'yaml';
|
||||
import CloudRunnerTimerLogger from './cloud-runner-timer-logger';
|
||||
import CloudRunnerLogger from './cloud-runner-logger';
|
||||
const repositoryFolder = 'repo';
|
||||
const buildVolumeFolder = 'data';
|
||||
const cacheFolder = 'cache';
|
||||
|
|
@ -39,7 +39,7 @@ class CloudRunner {
|
|||
];
|
||||
|
||||
private static setup(buildParameters: BuildParameters) {
|
||||
CloudRunnerTimerLogger.setup();
|
||||
CloudRunnerLogger.setup();
|
||||
CloudRunner.buildGuid = CloudRunnerNamespace.generateBuildName(
|
||||
CloudRunner.readRunNumber(),
|
||||
buildParameters.platform,
|
||||
|
|
@ -103,12 +103,12 @@ class CloudRunner {
|
|||
private static setupBuildPlatform() {
|
||||
switch (this.buildParams.cloudRunnerCluster) {
|
||||
case 'aws':
|
||||
core.info('Building with AWS');
|
||||
CloudRunnerLogger.log('Building with AWS');
|
||||
this.CloudRunnerProviderPlatform = new AWSBuildPlatform(this.buildParams);
|
||||
break;
|
||||
default:
|
||||
case 'k8s':
|
||||
core.info('Building with Kubernetes');
|
||||
CloudRunnerLogger.log('Building with Kubernetes');
|
||||
this.CloudRunnerProviderPlatform = new Kubernetes(this.buildParams);
|
||||
break;
|
||||
}
|
||||
|
|
@ -247,24 +247,24 @@ class CloudRunner {
|
|||
|
||||
private static async runMainJob(baseImage: any) {
|
||||
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);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
private static async standardBuildAutomation(baseImage: any) {
|
||||
CloudRunnerTimerLogger.logWithTime('Pre build steps time');
|
||||
CloudRunnerLogger.logWithTime('Pre build steps time');
|
||||
await this.runCustomJob(this.buildParams.preBuildSteps);
|
||||
CloudRunnerTimerLogger.logWithTime('Setup time');
|
||||
CloudRunnerLogger.logWithTime('Setup time');
|
||||
await CloudRunner.BuildStep(baseImage);
|
||||
CloudRunnerTimerLogger.logWithTime('Build time');
|
||||
CloudRunnerLogger.logWithTime('Build time');
|
||||
await CloudRunner.CompressionStep();
|
||||
CloudRunnerTimerLogger.logWithTime('Compression time');
|
||||
CloudRunnerLogger.logWithTime('Compression time');
|
||||
await this.runCustomJob(this.buildParams.postBuildSteps);
|
||||
CloudRunnerTimerLogger.logWithTime('Post build steps time');
|
||||
CloudRunnerLogger.logWithTime('Post build steps time');
|
||||
}
|
||||
|
||||
private static async runCustomJob(buildSteps) {
|
||||
|
|
@ -291,7 +291,7 @@ class CloudRunner {
|
|||
}
|
||||
|
||||
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(
|
||||
this.buildGuid,
|
||||
'alpine/git',
|
||||
|
|
@ -320,7 +320,7 @@ class CloudRunner {
|
|||
}
|
||||
|
||||
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(
|
||||
this.buildGuid,
|
||||
baseImage.toString(),
|
||||
|
|
@ -346,7 +346,7 @@ class CloudRunner {
|
|||
}
|
||||
|
||||
private static async CompressionStep() {
|
||||
core.info('Starting step 3/4 build compression');
|
||||
CloudRunnerLogger.log('Starting step 3/4 build compression');
|
||||
// Cleanup
|
||||
await this.CloudRunnerProviderPlatform.runBuildTask(
|
||||
this.buildGuid,
|
||||
|
|
@ -384,7 +384,7 @@ class CloudRunner {
|
|||
],
|
||||
this.defaultSecrets,
|
||||
);
|
||||
core.info('compression step complete');
|
||||
CloudRunnerLogger.log('compression step complete');
|
||||
}
|
||||
|
||||
private static async cleanupSharedBuildResources() {
|
||||
|
|
@ -397,7 +397,7 @@ class CloudRunner {
|
|||
}
|
||||
|
||||
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');
|
||||
await this.CloudRunnerProviderPlatform.cleanupSharedBuildResources(
|
||||
this.buildGuid,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import KubernetesUtilities from './kubernetes-utils';
|
|||
import waitUntil from 'async-wait-until';
|
||||
import KubernetesJobSpecFactory from './kubernetes-job-spec-factory';
|
||||
import KubernetesServiceAccount from './kubernetes-service-account';
|
||||
import CloudRunnerLogger from './cloud-runner-logger';
|
||||
|
||||
class Kubernetes implements CloudRunnerProviderInterface {
|
||||
private kubeConfig: k8s.KubeConfig;
|
||||
|
|
@ -34,7 +35,7 @@ class Kubernetes implements CloudRunnerProviderInterface {
|
|||
this.kubeClient = this.kubeConfig.makeApiClient(k8s.CoreV1Api);
|
||||
this.kubeClientBatch = this.kubeConfig.makeApiClient(k8s.BatchV1Api);
|
||||
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.buildParameters = buildParameters;
|
||||
|
|
@ -95,15 +96,15 @@ class Kubernetes implements CloudRunnerProviderInterface {
|
|||
);
|
||||
|
||||
//run
|
||||
core.info('Creating build job');
|
||||
CloudRunnerLogger.log('Creating build job');
|
||||
await this.kubeClientBatch.createNamespacedJob(this.namespace, jobSpec);
|
||||
core.info('Job created');
|
||||
CloudRunnerLogger.log('Job created');
|
||||
this.setPodNameAndContainerName(
|
||||
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);
|
||||
core.info('Pod running, streaming logs');
|
||||
CloudRunnerLogger.log('Pod running, streaming logs');
|
||||
await KubernetesLogging.streamLogs(
|
||||
this.kubeConfig,
|
||||
this.kubeClient,
|
||||
|
|
@ -111,11 +112,11 @@ class Kubernetes implements CloudRunnerProviderInterface {
|
|||
this.podName,
|
||||
'main',
|
||||
this.namespace,
|
||||
core.info,
|
||||
CloudRunnerLogger.log,
|
||||
);
|
||||
await this.cleanupTaskResources();
|
||||
} catch (error) {
|
||||
core.info('Running job failed');
|
||||
CloudRunnerLogger.log('Running job failed');
|
||||
core.error(JSON.stringify(error, undefined, 4));
|
||||
await this.cleanupTaskResources();
|
||||
throw error;
|
||||
|
|
@ -128,14 +129,14 @@ class Kubernetes implements CloudRunnerProviderInterface {
|
|||
}
|
||||
|
||||
async cleanupTaskResources() {
|
||||
core.info('cleaning up');
|
||||
CloudRunnerLogger.log('cleaning up');
|
||||
try {
|
||||
await this.kubeClientBatch.deleteNamespacedJob(this.jobName, this.namespace);
|
||||
await this.kubeClient.deleteNamespacedSecret(this.secretName, this.namespace);
|
||||
} catch (error) {
|
||||
core.info('Failed to cleanup, error:');
|
||||
CloudRunnerLogger.log('Failed to cleanup, error:');
|
||||
core.error(JSON.stringify(error, undefined, 4));
|
||||
core.info('Abandoning cleanup, build error:');
|
||||
CloudRunnerLogger.log('Abandoning cleanup, build error:');
|
||||
throw error;
|
||||
}
|
||||
try {
|
||||
|
|
@ -147,7 +148,7 @@ class Kubernetes implements CloudRunnerProviderInterface {
|
|||
},
|
||||
);
|
||||
} 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?');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { CoreV1Api, KubeConfig, Log } from '@kubernetes/client-node';
|
||||
import { Writable } from 'stream';
|
||||
import * as core from '@actions/core';
|
||||
import CloudRunnerLogger from './cloud-runner-logger';
|
||||
|
||||
class KubernetesLogging {
|
||||
static async streamLogs(
|
||||
|
|
@ -12,7 +12,7 @@ class KubernetesLogging {
|
|||
namespace: string,
|
||||
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();
|
||||
let didStreamAnyLogs: boolean = false;
|
||||
stream._write = (chunk, encoding, next) => {
|
||||
|
|
@ -57,7 +57,7 @@ class KubernetesLogging {
|
|||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
core.info('end of log stream');
|
||||
CloudRunnerLogger.log('end of log stream');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import waitUntil from 'async-wait-until';
|
|||
import * as core from '@actions/core';
|
||||
import * as k8s from '@kubernetes/client-node';
|
||||
import BuildParameters from '../build-parameters';
|
||||
import CloudRunnerLogger from './cloud-runner-logger';
|
||||
|
||||
class KubernetesStorage {
|
||||
public static async createPersistentVolumeClaim(
|
||||
|
|
@ -11,21 +12,21 @@ class KubernetesStorage {
|
|||
namespace: string,
|
||||
) {
|
||||
if (buildParameters.kubeVolume) {
|
||||
core.info(buildParameters.kubeVolume);
|
||||
CloudRunnerLogger.log(buildParameters.kubeVolume);
|
||||
pvcName = buildParameters.kubeVolume;
|
||||
return;
|
||||
}
|
||||
const pvcList = (await kubeClient.listNamespacedPersistentVolumeClaim(namespace)).body.items.map(
|
||||
(x) => x.metadata?.name,
|
||||
);
|
||||
core.info(`Current PVCs in namespace ${namespace}`);
|
||||
core.info(JSON.stringify(pvcList, undefined, 4));
|
||||
CloudRunnerLogger.log(`Current PVCs in namespace ${namespace}`);
|
||||
CloudRunnerLogger.log(JSON.stringify(pvcList, undefined, 4));
|
||||
if (pvcList.includes(pvcName)) {
|
||||
core.info(`pvc ${pvcName} already exists`);
|
||||
CloudRunnerLogger.log(`pvc ${pvcName} already exists`);
|
||||
core.setOutput('volume', pvcName);
|
||||
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);
|
||||
await KubernetesStorage.handleResult(result, kubeClient, namespace, pvcName);
|
||||
}
|
||||
|
|
@ -42,8 +43,8 @@ class KubernetesStorage {
|
|||
|
||||
public static async watchUntilPVCNotPending(kubeClient: k8s.CoreV1Api, name: string, namespace: string) {
|
||||
try {
|
||||
core.info(`watch Until PVC Not Pending ${name} ${namespace}`);
|
||||
core.info(`${await this.getPVCPhase(kubeClient, name, namespace)}`);
|
||||
CloudRunnerLogger.log(`watch Until PVC Not Pending ${name} ${namespace}`);
|
||||
CloudRunnerLogger.log(`${await this.getPVCPhase(kubeClient, name, namespace)}`);
|
||||
await waitUntil(
|
||||
async () => {
|
||||
return (await this.getPVCPhase(kubeClient, name, namespace)) !== 'Pending';
|
||||
|
|
@ -101,10 +102,12 @@ class KubernetesStorage {
|
|||
) {
|
||||
const name = result.body.metadata?.name;
|
||||
if (!name) throw new Error('failed to create PVC');
|
||||
core.info(JSON.stringify(await kubeClient.readNamespacedPersistentVolumeClaim(name, namespace), undefined, 4));
|
||||
core.info(`PVC ${name} created`);
|
||||
CloudRunnerLogger.log(
|
||||
JSON.stringify(await kubeClient.readNamespacedPersistentVolumeClaim(name, namespace), undefined, 4),
|
||||
);
|
||||
CloudRunnerLogger.log(`PVC ${name} created`);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { CoreV1Api } from '@kubernetes/client-node';
|
||||
import waitUntil from 'async-wait-until';
|
||||
import * as core from '@actions/core';
|
||||
import CloudRunnerLogger from './cloud-runner-logger';
|
||||
|
||||
class KubernetesUtilities {
|
||||
static async findPodFromJob(kubeClient: CoreV1Api, jobName: string, namespace: string) {
|
||||
|
|
@ -15,7 +15,7 @@ class KubernetesUtilities {
|
|||
|
||||
static async watchUntilPodRunning(kubeClient: CoreV1Api, podName: string, namespace: string) {
|
||||
let success: boolean = false;
|
||||
core.info(`Watching ${podName} ${namespace}`);
|
||||
CloudRunnerLogger.log(`Watching ${podName} ${namespace}`);
|
||||
await waitUntil(
|
||||
async () => {
|
||||
const phase = (await kubeClient.readNamespacedPodStatus(podName, namespace))?.body.status?.phase;
|
||||
|
|
|
|||
Loading…
Reference in New Issue