Skip to content

Commit af91756

Browse files
committed
HARMONY-2030: Make successful service deployment logs available via Harmony deployment logs endpoint.
1 parent 8574ac2 commit af91756

File tree

2 files changed

+57
-16
lines changed

2 files changed

+57
-16
lines changed

services/harmony/app/frontends/service-image-tags.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -436,12 +436,12 @@ export async function getServiceImageTag(
436436
}
437437

438438
/**
439-
* Get the log location of service deployment errors
439+
* Get the log location of service deployment
440440
*
441441
* @param deploymentId - The id of service deployment
442442
*/
443443
function getLogLocation(deploymentId: string ): string {
444-
return `s3://${env.artifactBucket}/${deploymentId}/errors.json`;
444+
return `s3://${env.artifactBucket}/${deploymentId}/log.json`;
445445
}
446446

447447
/**
@@ -450,8 +450,8 @@ function getLogLocation(deploymentId: string ): string {
450450
* @param req - The request object
451451
* @param service - The name of the service to deploy
452452
* @param tag - The service image tag to deploy
453-
* @param regressionTestVersion - The regression test version to run the regression test with
454453
* @param deploymentId - The deployment id
454+
* @param regressionTestVersion - The regression test version to run the regression test with
455455
*/
456456
export async function execDeployScript(
457457
req: HarmonyRequest,
@@ -473,17 +473,15 @@ export async function execDeployScript(
473473

474474
exec(command, options, async (error, stdout, _stderr) => {
475475
const lines = stdout.split('\n');
476+
// save the service deployment log to S3
477+
const s3 = objectStoreForProtocol('s3');
478+
const logLocation = getLogLocation(deploymentId);
479+
await s3.upload(JSON.stringify(lines), logLocation);
480+
481+
const urlRoot = getRequestRoot(req);
482+
const logUrl = `${urlRoot}/deployment-logs/${deploymentId}`;
476483
if (error) {
477484
req.context.logger.error(`Error executing script: ${error.message}`);
478-
479-
// save the service deployment errors to S3
480-
const logLocation = getLogLocation(deploymentId);
481-
const s3 = objectStoreForProtocol('s3');
482-
await s3.upload(JSON.stringify(lines), logLocation);
483-
484-
const urlRoot = getRequestRoot(req);
485-
const logUrl = `${urlRoot}/deployment-logs/${deploymentId}`;
486-
487485
lines.forEach(line => {
488486
req.context.logger.info(`Failed script output: ${line}`);
489487
});
@@ -500,7 +498,10 @@ export async function execDeployScript(
500498
// only re-enable the service deployment on successful deployment
501499
await enableServiceDeployment(`Re-enable service deployment after successful deployment: ${deploymentId}`);
502500
await db.transaction(async (tx) => {
503-
await setStatusMessage(tx, deploymentId, 'successful', 'Deployment successful');
501+
await setStatusMessage(tx,
502+
deploymentId,
503+
'successful',
504+
`Deployment successful. See details at: ${logUrl}`);
504505
});
505506
}
506507
});

services/harmony/test/service-image-tags.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ describe('Service image endpoint', async function () {
11531153
expect(service).to.eql('harmony-service-example');
11541154
expect(tag).to.eql('foo');
11551155
expect(status).to.eql('successful');
1156-
expect(message).to.eql('Deployment successful');
1156+
expect(message).to.include('Deployment successful');
11571157
});
11581158
});
11591159

@@ -1178,7 +1178,7 @@ describe('Service image endpoint', async function () {
11781178
expect(service).to.eql('harmony-service-example');
11791179
expect(tag).to.eql('foo');
11801180
expect(status).to.eql('successful');
1181-
expect(message).to.eql('Deployment successful');
1181+
expect(message).to.include('Deployment successful');
11821182
});
11831183
});
11841184
});
@@ -1196,6 +1196,7 @@ describe('Service self-deployment successful', async function () {
11961196
let execDeployScriptStub: sinon.SinonStub;
11971197
let link = null;
11981198
let linkDeploymentId = null;
1199+
let deploymentLogPath = null;
11991200

12001201
hookDescribeImage({
12011202
imageDigest: '',
@@ -1258,14 +1259,53 @@ describe('Service self-deployment successful', async function () {
12581259

12591260
it('returns the deployment status successful', async function () {
12601261
const { deploymentId, username, service, tag, regressionTestVersion, status, message } = this.res.body;
1262+
deploymentLogPath = `/deployment-logs/${deploymentId}`;
12611263
expect(deploymentId).to.eql(linkDeploymentId);
12621264
expect(username).to.eql('buzz');
12631265
expect(service).to.eql('harmony-service-example');
12641266
expect(tag).to.eql('foo');
12651267
// regressionTestVersion is set to the default value
12661268
expect(regressionTestVersion).to.eql('latest');
12671269
expect(status).to.eql('successful');
1268-
expect(message).to.eql('Deployment successful');
1270+
expect(message).to.include('Deployment successful');
1271+
expect(message).to.include(`See details at: http://127.0.0.1:4000${deploymentLogPath}`);
1272+
});
1273+
});
1274+
1275+
describe('when get the service deployment log with authorized user', async function () {
1276+
before(async function () {
1277+
hookRedirect('coraline');
1278+
this.res = await request(this.frontend).get(deploymentLogPath).use(auth({ username: 'coraline' }));
1279+
});
1280+
1281+
after(function () {
1282+
delete this.res;
1283+
});
1284+
1285+
it('returns a status 200', async function () {
1286+
expect(this.res.status).to.equal(200);
1287+
});
1288+
1289+
it('returns enabled false', async function () {
1290+
expect(this.res.body).to.eql(['Success output']);
1291+
});
1292+
});
1293+
1294+
describe('when get the service deployment log with unauthorized user', async function () {
1295+
before(async function () {
1296+
hookRedirect('coraline');
1297+
this.res = await request(this.frontend).get(deploymentLogPath).use(auth({ username: 'joe' }));
1298+
});
1299+
1300+
after(function () {
1301+
delete this.res;
1302+
});
1303+
1304+
it('returns a status 403', async function () {
1305+
expect(this.res.status).to.equal(403);
1306+
});
1307+
it('returns a meaningful error message', async function () {
1308+
expect(this.res.text).to.equal('User joe does not have permission to access this resource');
12691309
});
12701310
});
12711311

0 commit comments

Comments
 (0)