Cleanup log streaming dependencies to enable cli option

pull/419/head
Frostebite 2022-08-02 20:21:46 +01:00
parent 6ffc4c6508
commit 824f017b0b
6 changed files with 95 additions and 107 deletions

93
dist/index.js vendored
View File

@ -1354,7 +1354,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
const AWS = __importStar(__nccwpck_require__(71786));
const core = __importStar(__nccwpck_require__(42186)); const core = __importStar(__nccwpck_require__(42186));
const zlib = __importStar(__nccwpck_require__(59796)); const zlib = __importStar(__nccwpck_require__(59796));
const cloud_runner_logger_1 = __importDefault(__nccwpck_require__(22855)); const cloud_runner_logger_1 = __importDefault(__nccwpck_require__(22855));
@ -1363,7 +1362,7 @@ const cloud_runner_1 = __importDefault(__nccwpck_require__(79144));
const cloud_runner_custom_hooks_1 = __nccwpck_require__(58873); const cloud_runner_custom_hooks_1 = __nccwpck_require__(58873);
const follow_log_stream_service_1 = __nccwpck_require__(64121); const follow_log_stream_service_1 = __nccwpck_require__(64121);
class AWSTaskRunner { class AWSTaskRunner {
static runTask(taskDef, ECS, CF, environment, buildGuid, commands) { static runTask(taskDef, environment, 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;
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const cluster = ((_b = (_a = taskDef.baseResources) === null || _a === void 0 ? void 0 : _a.find((x) => x.LogicalResourceId === 'ECSCluster')) === null || _b === void 0 ? void 0 : _b.PhysicalResourceId) || ''; const cluster = ((_b = (_a = taskDef.baseResources) === null || _a === void 0 ? void 0 : _a.find((x) => x.LogicalResourceId === 'ECSCluster')) === null || _b === void 0 ? void 0 : _b.PhysicalResourceId) || '';
@ -1372,7 +1371,7 @@ class AWSTaskRunner {
const SubnetTwo = ((_h = (_g = taskDef.baseResources) === null || _g === void 0 ? void 0 : _g.find((x) => x.LogicalResourceId === 'PublicSubnetTwo')) === null || _h === void 0 ? void 0 : _h.PhysicalResourceId) || ''; const SubnetTwo = ((_h = (_g = taskDef.baseResources) === null || _g === void 0 ? void 0 : _g.find((x) => x.LogicalResourceId === 'PublicSubnetTwo')) === null || _h === void 0 ? void 0 : _h.PhysicalResourceId) || '';
const ContainerSecurityGroup = ((_k = (_j = taskDef.baseResources) === null || _j === void 0 ? void 0 : _j.find((x) => x.LogicalResourceId === 'ContainerSecurityGroup')) === null || _k === void 0 ? void 0 : _k.PhysicalResourceId) || ''; const ContainerSecurityGroup = ((_k = (_j = taskDef.baseResources) === null || _j === void 0 ? void 0 : _j.find((x) => x.LogicalResourceId === 'ContainerSecurityGroup')) === null || _k === void 0 ? void 0 : _k.PhysicalResourceId) || '';
const streamName = ((_m = (_l = taskDef.taskDefResources) === null || _l === void 0 ? void 0 : _l.find((x) => x.LogicalResourceId === 'KinesisStream')) === null || _m === void 0 ? void 0 : _m.PhysicalResourceId) || ''; const streamName = ((_m = (_l = taskDef.taskDefResources) === null || _l === void 0 ? void 0 : _l.find((x) => x.LogicalResourceId === 'KinesisStream')) === null || _m === void 0 ? void 0 : _m.PhysicalResourceId) || '';
const task = yield ECS.runTask({ const task = yield AWSTaskRunner.ECS.runTask({
cluster, cluster,
taskDefinition, taskDefinition,
platformVersion: '1.4.0', platformVersion: '1.4.0',
@ -1396,10 +1395,10 @@ class AWSTaskRunner {
}).promise(); }).promise();
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) || '';
cloud_runner_logger_1.default.log('Cloud runner job is starting'); cloud_runner_logger_1.default.log('Cloud runner job is starting');
yield AWSTaskRunner.waitUntilTaskRunning(ECS, taskArn, cluster); yield AWSTaskRunner.waitUntilTaskRunning(taskArn, cluster);
cloud_runner_logger_1.default.log(`Cloud runner job status is running ${(_p = (yield AWSTaskRunner.describeTasks(ECS, cluster, taskArn))) === null || _p === void 0 ? void 0 : _p.lastStatus}`); cloud_runner_logger_1.default.log(`Cloud runner job status is running ${(_p = (yield AWSTaskRunner.describeTasks(cluster, taskArn))) === null || _p === void 0 ? void 0 : _p.lastStatus}`);
const { output, shouldCleanup } = yield this.streamLogsUntilTaskStops(ECS, CF, taskDef, cluster, taskArn, streamName); const { output, shouldCleanup } = yield this.streamLogsUntilTaskStops(cluster, taskArn, streamName);
const taskData = yield AWSTaskRunner.describeTasks(ECS, cluster, taskArn); const taskData = yield AWSTaskRunner.describeTasks(cluster, taskArn);
const exitCode = (_q = taskData.containers) === null || _q === void 0 ? void 0 : _q[0].exitCode; const exitCode = (_q = taskData.containers) === null || _q === void 0 ? void 0 : _q[0].exitCode;
const wasSuccessful = exitCode === 0 || (exitCode === undefined && taskData.lastStatus === 'RUNNING'); const wasSuccessful = exitCode === 0 || (exitCode === undefined && taskData.lastStatus === 'RUNNING');
if (wasSuccessful) { if (wasSuccessful) {
@ -1418,25 +1417,25 @@ class AWSTaskRunner {
} }
}); });
} }
static waitUntilTaskRunning(ECS, taskArn, cluster) { static waitUntilTaskRunning(taskArn, cluster) {
var _a; var _a;
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
try { try {
yield ECS.waitFor('tasksRunning', { tasks: [taskArn], cluster }).promise(); yield AWSTaskRunner.ECS.waitFor('tasksRunning', { tasks: [taskArn], cluster }).promise();
} }
catch (error_) { catch (error_) {
const error = error_; const error = error_;
yield new Promise((resolve) => setTimeout(resolve, 3000)); yield new Promise((resolve) => setTimeout(resolve, 3000));
cloud_runner_logger_1.default.log(`Cloud runner job has ended ${(_a = (yield AWSTaskRunner.describeTasks(ECS, cluster, taskArn)).containers) === null || _a === void 0 ? void 0 : _a[0].lastStatus}`); cloud_runner_logger_1.default.log(`Cloud runner job has ended ${(_a = (yield AWSTaskRunner.describeTasks(cluster, taskArn)).containers) === null || _a === void 0 ? void 0 : _a[0].lastStatus}`);
core.setFailed(error); core.setFailed(error);
core.error(error); core.error(error);
} }
}); });
} }
static describeTasks(ECS, clusterName, taskArn) { static describeTasks(clusterName, taskArn) {
var _a, _b; var _a, _b;
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const tasks = yield ECS.describeTasks({ const tasks = yield AWSTaskRunner.ECS.describeTasks({
cluster: clusterName, cluster: clusterName,
tasks: [taskArn], tasks: [taskArn],
}).promise(); }).promise();
@ -1448,11 +1447,10 @@ class AWSTaskRunner {
} }
}); });
} }
static streamLogsUntilTaskStops(ECS, CF, taskDef, clusterName, taskArn, kinesisStreamName) { static streamLogsUntilTaskStops(clusterName, taskArn, kinesisStreamName) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const kinesis = new AWS.Kinesis(); const stream = yield AWSTaskRunner.getLogStream(kinesisStreamName);
const stream = yield AWSTaskRunner.getLogStream(kinesis, kinesisStreamName); let iterator = yield AWSTaskRunner.getLogIterator(stream);
let iterator = yield AWSTaskRunner.getLogIterator(kinesis, stream);
const logBaseUrl = `https://${__1.Input.region}.console.aws.amazon.com/cloudwatch/home?region=${__1.Input.region}#logsV2:log-groups/log-group/${cloud_runner_1.default.buildParameters.awsBaseStackName}-${cloud_runner_1.default.buildParameters.buildGuid}`; const logBaseUrl = `https://${__1.Input.region}.console.aws.amazon.com/cloudwatch/home?region=${__1.Input.region}#logsV2:log-groups/log-group/${cloud_runner_1.default.buildParameters.awsBaseStackName}-${cloud_runner_1.default.buildParameters.buildGuid}`;
cloud_runner_logger_1.default.log(`You view the log stream on AWS Cloud Watch: ${logBaseUrl}`); cloud_runner_logger_1.default.log(`You view the log stream on AWS Cloud Watch: ${logBaseUrl}`);
let shouldReadLogs = true; let shouldReadLogs = true;
@ -1461,22 +1459,20 @@ class AWSTaskRunner {
let output = ''; let output = '';
while (shouldReadLogs) { while (shouldReadLogs) {
yield new Promise((resolve) => setTimeout(resolve, 1500)); yield new Promise((resolve) => setTimeout(resolve, 1500));
const taskData = yield AWSTaskRunner.describeTasks(ECS, clusterName, taskArn); const taskData = yield AWSTaskRunner.describeTasks(clusterName, taskArn);
({ timestamp, shouldReadLogs } = AWSTaskRunner.checkStreamingShouldContinue(taskData, timestamp, shouldReadLogs)); ({ timestamp, shouldReadLogs } = AWSTaskRunner.checkStreamingShouldContinue(taskData, timestamp, shouldReadLogs));
({ iterator, shouldReadLogs, output, shouldCleanup } = yield AWSTaskRunner.handleLogStreamIteration(kinesis, iterator, shouldReadLogs, taskDef, output, shouldCleanup)); ({ iterator, shouldReadLogs, output, shouldCleanup } = yield AWSTaskRunner.handleLogStreamIteration(iterator, shouldReadLogs, output, shouldCleanup));
} }
return { output, shouldCleanup }; return { output, shouldCleanup };
}); });
} }
static handleLogStreamIteration(kinesis, iterator, shouldReadLogs, taskDef, output, shouldCleanup) { static handleLogStreamIteration(iterator, shouldReadLogs, output, shouldCleanup) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const records = yield kinesis const records = yield AWSTaskRunner.Kinesis.getRecords({
.getRecords({
ShardIterator: iterator, ShardIterator: iterator,
}) }).promise();
.promise();
iterator = records.NextShardIterator || ''; iterator = records.NextShardIterator || '';
({ shouldReadLogs, output, shouldCleanup } = AWSTaskRunner.logRecords(records, iterator, taskDef, shouldReadLogs, output, shouldCleanup)); ({ shouldReadLogs, output, shouldCleanup } = AWSTaskRunner.logRecords(records, iterator, shouldReadLogs, output, shouldCleanup));
return { iterator, shouldReadLogs, output, shouldCleanup }; return { iterator, shouldReadLogs, output, shouldCleanup };
}); });
} }
@ -1497,7 +1493,7 @@ class AWSTaskRunner {
} }
return { timestamp, shouldReadLogs }; return { timestamp, shouldReadLogs };
} }
static logRecords(records, iterator, taskDef, shouldReadLogs, output, shouldCleanup) { static logRecords(records, iterator, shouldReadLogs, output, shouldCleanup) {
if (records.Records.length > 0 && iterator) { if (records.Records.length > 0 && iterator) {
for (let index = 0; index < records.Records.length; index++) { for (let index = 0; index < records.Records.length; index++) {
const json = JSON.parse(zlib.gunzipSync(Buffer.from(records.Records[index].Data, 'base64')).toString('utf8')); const json = JSON.parse(zlib.gunzipSync(Buffer.from(records.Records[index].Data, 'base64')).toString('utf8'));
@ -1511,24 +1507,20 @@ class AWSTaskRunner {
} }
return { shouldReadLogs, output, shouldCleanup }; return { shouldReadLogs, output, shouldCleanup };
} }
static getLogStream(kinesis, kinesisStreamName) { static getLogStream(kinesisStreamName) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
return yield kinesis return yield AWSTaskRunner.Kinesis.describeStream({
.describeStream({
StreamName: kinesisStreamName, StreamName: kinesisStreamName,
}) }).promise();
.promise();
}); });
} }
static getLogIterator(kinesis, stream) { static getLogIterator(stream) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
return ((yield kinesis return ((yield AWSTaskRunner.Kinesis.getShardIterator({
.getShardIterator({
ShardIteratorType: 'TRIM_HORIZON', ShardIteratorType: 'TRIM_HORIZON',
StreamName: stream.StreamDescription.StreamName, StreamName: stream.StreamDescription.StreamName,
ShardId: stream.StreamDescription.Shards[0].ShardId, ShardId: stream.StreamDescription.Shards[0].ShardId,
}) }).promise()).ShardIterator || '');
.promise()).ShardIterator || '');
}); });
} }
} }
@ -2168,11 +2160,6 @@ class AwsCliCommands {
return task_service_1.TaskService.awsListJobs(perResultCallback); return task_service_1.TaskService.awsListJobs(perResultCallback);
}); });
} }
static listTasks(perResultCallback = false) {
return __awaiter(this, void 0, void 0, function* () {
return task_service_1.TaskService.awsListJobs(perResultCallback);
});
}
static awsListLogGroups(perResultCallback = false) { static awsListLogGroups(perResultCallback = false) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
yield tertiary_resources_service_1.TertiaryResourcesService.AwsListLogGroups(perResultCallback); yield tertiary_resources_service_1.TertiaryResourcesService.AwsListLogGroups(perResultCallback);
@ -2183,6 +2170,16 @@ class AwsCliCommands {
return task_service_1.TaskService.awsListJobs(perResultCallback); return task_service_1.TaskService.awsListJobs(perResultCallback);
}); });
} }
static listTasks(perResultCallback = false) {
return __awaiter(this, void 0, void 0, function* () {
return task_service_1.TaskService.awsListJobs(perResultCallback);
});
}
static watchTasks() {
return __awaiter(this, void 0, void 0, function* () {
return task_service_1.TaskService.watch();
});
}
} }
__decorate([ __decorate([
cli_functions_repository_1.CliFunction(`aws-list-all`, `List all resources`) cli_functions_repository_1.CliFunction(`aws-list-all`, `List all resources`)
@ -2202,15 +2199,18 @@ __decorate([
__decorate([ __decorate([
cli_functions_repository_1.CliFunction(`aws-list-tasks`, `List tasks`) cli_functions_repository_1.CliFunction(`aws-list-tasks`, `List tasks`)
], AwsCliCommands, "awsListTasks", null); ], AwsCliCommands, "awsListTasks", null);
__decorate([
cli_functions_repository_1.CliFunction(`list-tasks`, `List tasks`)
], AwsCliCommands, "listTasks", null);
__decorate([ __decorate([
cli_functions_repository_1.CliFunction(`aws-list-log-groups`, `List tasks`) cli_functions_repository_1.CliFunction(`aws-list-log-groups`, `List tasks`)
], AwsCliCommands, "awsListLogGroups", null); ], AwsCliCommands, "awsListLogGroups", null);
__decorate([ __decorate([
cli_functions_repository_1.CliFunction(`aws-list-jobs`, `List tasks`) cli_functions_repository_1.CliFunction(`aws-list-jobs`, `List tasks`)
], AwsCliCommands, "awsListJobs", null); ], AwsCliCommands, "awsListJobs", null);
__decorate([
cli_functions_repository_1.CliFunction(`list-tasks`, `List tasks`)
], AwsCliCommands, "listTasks", null);
__decorate([
cli_functions_repository_1.CliFunction(`watch`, `List tasks`)
], AwsCliCommands, "watchTasks", null);
exports.AwsCliCommands = AwsCliCommands; exports.AwsCliCommands = AwsCliCommands;
@ -2317,6 +2317,8 @@ class AWSBuildEnvironment {
process.env.AWS_REGION = __1.Input.region; process.env.AWS_REGION = __1.Input.region;
const ECS = new SDK.ECS(); const ECS = new SDK.ECS();
const CF = new SDK.CloudFormation(); const CF = new SDK.CloudFormation();
aws_task_runner_1.default.ECS = ECS;
aws_task_runner_1.default.Kinesis = new SDK.Kinesis();
cloud_runner_logger_1.default.log(`AWS Region: ${CF.config.region}`); cloud_runner_logger_1.default.log(`AWS Region: ${CF.config.region}`);
const entrypoint = ['/bin/sh']; const entrypoint = ['/bin/sh'];
const startTimeMs = Date.now(); const startTimeMs = Date.now();
@ -2326,7 +2328,7 @@ class AWSBuildEnvironment {
try { try {
const postSetupStacksTimeMs = Date.now(); const postSetupStacksTimeMs = Date.now();
cloud_runner_logger_1.default.log(`Setup job time: ${Math.floor((postSetupStacksTimeMs - startTimeMs) / 1000)}s`); cloud_runner_logger_1.default.log(`Setup job time: ${Math.floor((postSetupStacksTimeMs - startTimeMs) / 1000)}s`);
const { output, shouldCleanup } = yield aws_task_runner_1.default.runTask(taskDef, ECS, CF, environment, buildGuid, commands); const { output, shouldCleanup } = yield aws_task_runner_1.default.runTask(taskDef, environment, commands);
postRunTaskTimeMs = Date.now(); postRunTaskTimeMs = Date.now();
cloud_runner_logger_1.default.log(`Run job time: ${Math.floor((postRunTaskTimeMs - postSetupStacksTimeMs) / 1000)}s`); cloud_runner_logger_1.default.log(`Run job time: ${Math.floor((postRunTaskTimeMs - postSetupStacksTimeMs) / 1000)}s`);
if (shouldCleanup) { if (shouldCleanup) {
@ -2491,6 +2493,9 @@ const input_1 = __importDefault(__nccwpck_require__(91933));
const cloud_runner_logger_1 = __importDefault(__nccwpck_require__(22855)); const cloud_runner_logger_1 = __importDefault(__nccwpck_require__(22855));
const base_stack_formation_1 = __nccwpck_require__(29643); const base_stack_formation_1 = __nccwpck_require__(29643);
class TaskService { class TaskService {
static watch() {
throw new Error('Method not implemented.');
}
static awsListStacks(perResultCallback = false) { static awsListStacks(perResultCallback = false) {
var _a, _b; var _a, _b;
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -10,12 +10,11 @@ import { CloudRunnerCustomHooks } from '../../services/cloud-runner-custom-hooks
import { FollowLogStreamService } from '../../services/follow-log-stream-service'; import { FollowLogStreamService } from '../../services/follow-log-stream-service';
class AWSTaskRunner { class AWSTaskRunner {
public static ECS: AWS.ECS;
public static Kinesis: AWS.Kinesis;
static async runTask( static async runTask(
taskDef: CloudRunnerAWSTaskDef, taskDef: CloudRunnerAWSTaskDef,
ECS: AWS.ECS,
CF: AWS.CloudFormation,
environment: CloudRunnerEnvironmentVariable[], environment: CloudRunnerEnvironmentVariable[],
buildGuid: string,
commands: string, commands: string,
) { ) {
const cluster = taskDef.baseResources?.find((x) => x.LogicalResourceId === 'ECSCluster')?.PhysicalResourceId || ''; const cluster = taskDef.baseResources?.find((x) => x.LogicalResourceId === 'ECSCluster')?.PhysicalResourceId || '';
@ -30,7 +29,7 @@ class AWSTaskRunner {
const streamName = const streamName =
taskDef.taskDefResources?.find((x) => x.LogicalResourceId === 'KinesisStream')?.PhysicalResourceId || ''; taskDef.taskDefResources?.find((x) => x.LogicalResourceId === 'KinesisStream')?.PhysicalResourceId || '';
const task = await ECS.runTask({ const task = await AWSTaskRunner.ECS.runTask({
cluster, cluster,
taskDefinition, taskDefinition,
platformVersion: '1.4.0', platformVersion: '1.4.0',
@ -54,19 +53,12 @@ class AWSTaskRunner {
}).promise(); }).promise();
const taskArn = task.tasks?.[0].taskArn || ''; const taskArn = task.tasks?.[0].taskArn || '';
CloudRunnerLogger.log('Cloud runner job is starting'); CloudRunnerLogger.log('Cloud runner job is starting');
await AWSTaskRunner.waitUntilTaskRunning(ECS, taskArn, cluster); await AWSTaskRunner.waitUntilTaskRunning(taskArn, cluster);
CloudRunnerLogger.log( CloudRunnerLogger.log(
`Cloud runner job status is running ${(await AWSTaskRunner.describeTasks(ECS, cluster, taskArn))?.lastStatus}`, `Cloud runner job status is running ${(await AWSTaskRunner.describeTasks(cluster, taskArn))?.lastStatus}`,
); );
const { output, shouldCleanup } = await this.streamLogsUntilTaskStops( const { output, shouldCleanup } = await this.streamLogsUntilTaskStops(cluster, taskArn, streamName);
ECS, const taskData = await AWSTaskRunner.describeTasks(cluster, taskArn);
CF,
taskDef,
cluster,
taskArn,
streamName,
);
const taskData = await AWSTaskRunner.describeTasks(ECS, cluster, taskArn);
const exitCode = taskData.containers?.[0].exitCode; const exitCode = taskData.containers?.[0].exitCode;
const wasSuccessful = exitCode === 0 || (exitCode === undefined && taskData.lastStatus === 'RUNNING'); const wasSuccessful = exitCode === 0 || (exitCode === undefined && taskData.lastStatus === 'RUNNING');
if (wasSuccessful) { if (wasSuccessful) {
@ -85,15 +77,15 @@ class AWSTaskRunner {
} }
} }
private static async waitUntilTaskRunning(ECS: AWS.ECS, taskArn: string, cluster: string) { private static async waitUntilTaskRunning(taskArn: string, cluster: string) {
try { try {
await ECS.waitFor('tasksRunning', { tasks: [taskArn], cluster }).promise(); await AWSTaskRunner.ECS.waitFor('tasksRunning', { tasks: [taskArn], cluster }).promise();
} 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));
CloudRunnerLogger.log( CloudRunnerLogger.log(
`Cloud runner job has ended ${ `Cloud runner job has ended ${
(await AWSTaskRunner.describeTasks(ECS, cluster, taskArn)).containers?.[0].lastStatus (await AWSTaskRunner.describeTasks(cluster, taskArn)).containers?.[0].lastStatus
}`, }`,
); );
@ -102,8 +94,8 @@ class AWSTaskRunner {
} }
} }
static async describeTasks(ECS: AWS.ECS, clusterName: string, taskArn: string) { static async describeTasks(clusterName: string, taskArn: string) {
const tasks = await ECS.describeTasks({ const tasks = await AWSTaskRunner.ECS.describeTasks({
cluster: clusterName, cluster: clusterName,
tasks: [taskArn], tasks: [taskArn],
}).promise(); }).promise();
@ -114,17 +106,9 @@ class AWSTaskRunner {
} }
} }
static async streamLogsUntilTaskStops( static async streamLogsUntilTaskStops(clusterName: string, taskArn: string, kinesisStreamName: string) {
ECS: AWS.ECS, const stream = await AWSTaskRunner.getLogStream(kinesisStreamName);
CF: AWS.CloudFormation, let iterator = await AWSTaskRunner.getLogIterator(stream);
taskDef: CloudRunnerAWSTaskDef,
clusterName: string,
taskArn: string,
kinesisStreamName: string,
) {
const kinesis = new AWS.Kinesis();
const stream = await AWSTaskRunner.getLogStream(kinesis, kinesisStreamName);
let iterator = await AWSTaskRunner.getLogIterator(kinesis, stream);
const logBaseUrl = `https://${Input.region}.console.aws.amazon.com/cloudwatch/home?region=${Input.region}#logsV2:log-groups/log-group/${CloudRunner.buildParameters.awsBaseStackName}-${CloudRunner.buildParameters.buildGuid}`; const logBaseUrl = `https://${Input.region}.console.aws.amazon.com/cloudwatch/home?region=${Input.region}#logsV2:log-groups/log-group/${CloudRunner.buildParameters.awsBaseStackName}-${CloudRunner.buildParameters.buildGuid}`;
CloudRunnerLogger.log(`You view the log stream on AWS Cloud Watch: ${logBaseUrl}`); CloudRunnerLogger.log(`You view the log stream on AWS Cloud Watch: ${logBaseUrl}`);
@ -134,13 +118,11 @@ class AWSTaskRunner {
let output = ''; let output = '';
while (shouldReadLogs) { while (shouldReadLogs) {
await new Promise((resolve) => setTimeout(resolve, 1500)); await new Promise((resolve) => setTimeout(resolve, 1500));
const taskData = await AWSTaskRunner.describeTasks(ECS, clusterName, taskArn); const taskData = await AWSTaskRunner.describeTasks(clusterName, taskArn);
({ timestamp, shouldReadLogs } = AWSTaskRunner.checkStreamingShouldContinue(taskData, timestamp, shouldReadLogs)); ({ timestamp, shouldReadLogs } = AWSTaskRunner.checkStreamingShouldContinue(taskData, timestamp, shouldReadLogs));
({ iterator, shouldReadLogs, output, shouldCleanup } = await AWSTaskRunner.handleLogStreamIteration( ({ iterator, shouldReadLogs, output, shouldCleanup } = await AWSTaskRunner.handleLogStreamIteration(
kinesis,
iterator, iterator,
shouldReadLogs, shouldReadLogs,
taskDef,
output, output,
shouldCleanup, shouldCleanup,
)); ));
@ -150,23 +132,18 @@ class AWSTaskRunner {
} }
private static async handleLogStreamIteration( private static async handleLogStreamIteration(
kinesis: AWS.Kinesis,
iterator: string, iterator: string,
shouldReadLogs: boolean, shouldReadLogs: boolean,
taskDef: CloudRunnerAWSTaskDef,
output: string, output: string,
shouldCleanup: boolean, shouldCleanup: boolean,
) { ) {
const records = await kinesis const records = await AWSTaskRunner.Kinesis.getRecords({
.getRecords({ ShardIterator: iterator,
ShardIterator: iterator, }).promise();
})
.promise();
iterator = records.NextShardIterator || ''; iterator = records.NextShardIterator || '';
({ shouldReadLogs, output, shouldCleanup } = AWSTaskRunner.logRecords( ({ shouldReadLogs, output, shouldCleanup } = AWSTaskRunner.logRecords(
records, records,
iterator, iterator,
taskDef,
shouldReadLogs, shouldReadLogs,
output, output,
shouldCleanup, shouldCleanup,
@ -197,7 +174,6 @@ class AWSTaskRunner {
private static logRecords( private static logRecords(
records, records,
iterator: string, iterator: string,
taskDef: CloudRunnerAWSTaskDef,
shouldReadLogs: boolean, shouldReadLogs: boolean,
output: string, output: string,
shouldCleanup: boolean, shouldCleanup: boolean,
@ -224,24 +200,20 @@ class AWSTaskRunner {
return { shouldReadLogs, output, shouldCleanup }; return { shouldReadLogs, output, shouldCleanup };
} }
private static async getLogStream(kinesis: AWS.Kinesis, kinesisStreamName: string) { private static async getLogStream(kinesisStreamName: string) {
return await kinesis return await AWSTaskRunner.Kinesis.describeStream({
.describeStream({ StreamName: kinesisStreamName,
StreamName: kinesisStreamName, }).promise();
})
.promise();
} }
private static async getLogIterator(kinesis: AWS.Kinesis, stream) { private static async getLogIterator(stream) {
return ( return (
( (
await kinesis await AWSTaskRunner.Kinesis.getShardIterator({
.getShardIterator({ ShardIteratorType: 'TRIM_HORIZON',
ShardIteratorType: 'TRIM_HORIZON', StreamName: stream.StreamDescription.StreamName,
StreamName: stream.StreamDescription.StreamName, ShardId: stream.StreamDescription.Shards[0].ShardId,
ShardId: stream.StreamDescription.Shards[0].ShardId, }).promise()
})
.promise()
).ShardIterator || '' ).ShardIterator || ''
); );
} }

View File

@ -34,10 +34,6 @@ export class AwsCliCommands {
static async awsListTasks(perResultCallback: any = false) { static async awsListTasks(perResultCallback: any = false) {
return TaskService.awsListJobs(perResultCallback); return TaskService.awsListJobs(perResultCallback);
} }
@CliFunction(`list-tasks`, `List tasks`)
static async listTasks(perResultCallback: any = false) {
return TaskService.awsListJobs(perResultCallback);
}
@CliFunction(`aws-list-log-groups`, `List tasks`) @CliFunction(`aws-list-log-groups`, `List tasks`)
static async awsListLogGroups(perResultCallback: any = false) { static async awsListLogGroups(perResultCallback: any = false) {
@ -48,4 +44,14 @@ export class AwsCliCommands {
public static async awsListJobs(perResultCallback: any = false) { public static async awsListJobs(perResultCallback: any = false) {
return TaskService.awsListJobs(perResultCallback); return TaskService.awsListJobs(perResultCallback);
} }
@CliFunction(`list-tasks`, `List tasks`)
static async listTasks(perResultCallback: any = false) {
return TaskService.awsListJobs(perResultCallback);
}
@CliFunction(`watch`, `List tasks`)
static async watchTasks() {
return TaskService.watch();
}
} }

View File

@ -79,6 +79,8 @@ class AWSBuildEnvironment implements ProviderInterface {
process.env.AWS_REGION = Input.region; process.env.AWS_REGION = Input.region;
const ECS = new SDK.ECS(); const ECS = new SDK.ECS();
const CF = new SDK.CloudFormation(); const CF = new SDK.CloudFormation();
AWSTaskRunner.ECS = ECS;
AWSTaskRunner.Kinesis = new SDK.Kinesis();
CloudRunnerLogger.log(`AWS Region: ${CF.config.region}`); CloudRunnerLogger.log(`AWS Region: ${CF.config.region}`);
const entrypoint = ['/bin/sh']; const entrypoint = ['/bin/sh'];
const startTimeMs = Date.now(); const startTimeMs = Date.now();
@ -99,7 +101,7 @@ class AWSBuildEnvironment implements ProviderInterface {
try { try {
const postSetupStacksTimeMs = Date.now(); const postSetupStacksTimeMs = Date.now();
CloudRunnerLogger.log(`Setup job time: ${Math.floor((postSetupStacksTimeMs - startTimeMs) / 1000)}s`); CloudRunnerLogger.log(`Setup job time: ${Math.floor((postSetupStacksTimeMs - startTimeMs) / 1000)}s`);
const { output, shouldCleanup } = await AWSTaskRunner.runTask(taskDef, ECS, CF, environment, buildGuid, commands); const { output, shouldCleanup } = await AWSTaskRunner.runTask(taskDef, environment, commands);
postRunTaskTimeMs = Date.now(); postRunTaskTimeMs = Date.now();
CloudRunnerLogger.log(`Run job time: ${Math.floor((postRunTaskTimeMs - postSetupStacksTimeMs) / 1000)}s`); CloudRunnerLogger.log(`Run job time: ${Math.floor((postRunTaskTimeMs - postSetupStacksTimeMs) / 1000)}s`);
if (shouldCleanup) { if (shouldCleanup) {

View File

@ -4,6 +4,9 @@ import CloudRunnerLogger from '../../../services/cloud-runner-logger';
import { BaseStackFormation } from '../cloud-formations/base-stack-formation'; import { BaseStackFormation } from '../cloud-formations/base-stack-formation';
export class TaskService { export class TaskService {
static watch() {
throw new Error('Method not implemented.');
}
public static async awsListStacks(perResultCallback: any = false) { public static async awsListStacks(perResultCallback: any = false) {
process.env.AWS_REGION = Input.region; process.env.AWS_REGION = Input.region;
const CF = new AWS.CloudFormation(); const CF = new AWS.CloudFormation();