Skip to content

Commit

Permalink
Docker V0 and V1 store build output in temp file (#14773)
Browse files Browse the repository at this point in the history
* Store the build output in temp file and store path in env variable DockerOutputPath

* Updated version number

* removing plural expression

* Moved from where the output variable was set

* Fixing tests

Tests were failing when run in an agent becuase the path was looking at the wrong path

Co-authored-by: Ajinkya <[email protected]>
  • Loading branch information
jcfiorenzano and ajinkya599 authored May 5, 2021
1 parent c345a93 commit ea2446c
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 6 deletions.
13 changes: 13 additions & 0 deletions Tasks/DockerV0/Tests/L0.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as os from "os";
import * as path from 'path';
import * as assert from 'assert';
import * as ttm from 'azure-pipelines-task-lib/mock-test';
Expand Down Expand Up @@ -237,4 +238,16 @@ describe('Docker Suite', function() {
console.log(tr.stderr);
done();
});

it('Runs successfully for docker build and populate ouput variable correctly', (done:Mocha.Done) => {
let tp = path.join(__dirname, 'TestSetup.js');
let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.action] = shared.ActionTypes.buildImage;
tr.run();

assert(tr.succeeded, 'task should have succeeded');
assert(tr.stdout.indexOf("set DockerOutputPath=") != -1, "docker build should set DockerOutputPath env variable.")
console.log(tr.stderr);
done();
});
});
11 changes: 10 additions & 1 deletion Tasks/DockerV0/containerbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,14 @@ export function run(connection: ContainerConnection): any {
context = tl.getPathInput("context");
}
command.arg(context);
return connection.execCommand(command);

let output: string = "";
command.on("stdout", data => {
output += data;
});

return connection.execCommand(command).then(() => {
let taskOutputPath = utils.writeTaskOutput("build", output);
tl.setVariable("DockerOutputPath", taskOutputPath);
});
}
6 changes: 5 additions & 1 deletion Tasks/DockerV0/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"author": "Microsoft Corporation",
"version": {
"Major": 0,
"Minor": 181,
"Minor": 187,
"Patch": 0
},
"demands": [],
Expand Down Expand Up @@ -325,6 +325,10 @@
{
"name": "DockerOutput",
"description": "Stores the output of the docker command"
},
{
"name": "DockerOutputPath",
"description": "The path of the file which contains the output of the build command."
}
],
"instanceNameFormat": "$(action)",
Expand Down
6 changes: 5 additions & 1 deletion Tasks/DockerV0/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"author": "Microsoft Corporation",
"version": {
"Major": 0,
"Minor": 181,
"Minor": 187,
"Patch": 0
},
"demands": [],
Expand Down Expand Up @@ -325,6 +325,10 @@
{
"name": "DockerOutput",
"description": "Stores the output of the docker command"
},
{
"name": "DockerOutputPath",
"description": "The path of the file which contains the output of the build command."
}
],
"instanceNameFormat": "ms-resource:loc.instanceNameFormat",
Expand Down
25 changes: 25 additions & 0 deletions Tasks/DockerV0/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import * as fs from "fs";
import ContainerConnection from "azure-pipelines-tasks-docker-common-v2/containerconnection";
import * as sourceUtils from "azure-pipelines-tasks-docker-common-v2/sourceutils";
import * as imageUtils from "azure-pipelines-tasks-docker-common-v2/containerimageutils";
import * as fileutils from "azure-pipelines-tasks-docker-common-v2/fileutils";
import * as path from "path";
import * as os from "os";

export function getImageNames(): string[] {
let imageNamesFilePath = tl.getPathInput("imageNamesPath", /* required */ true, /* check exists */ true);
Expand Down Expand Up @@ -82,6 +85,28 @@ export function getImageMappings(connection: ContainerConnection, imageNames: st
return sourceToTargetMapping;
}


function getTaskOutputDir(command: string): string {
let tempDirectory = tl.getVariable('agent.tempDirectory') || os.tmpdir();
let taskOutputDir = path.join(tempDirectory, "task_outputs");
return taskOutputDir;
}

export function writeTaskOutput(commandName: string, output: string): string {
let taskOutputDir = getTaskOutputDir(commandName);
if (!fs.existsSync(taskOutputDir)) {
fs.mkdirSync(taskOutputDir);
}

let outputFileName = commandName + "_" + Date.now() + ".txt";
let taskOutputPath = path.join(taskOutputDir, outputFileName);
if (fileutils.writeFileSync(taskOutputPath, output) == 0) {
tl.warning(tl.loc('NoDataWrittenOnFile', taskOutputPath));
}

return taskOutputPath;
}

interface ImageInfo {
/**
* The original, unmodified, image name provided as input to the task
Expand Down
13 changes: 13 additions & 0 deletions Tasks/DockerV1/Tests/L0.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as path from 'path';
import * as os from "os";
import * as assert from 'assert';
import * as ttm from 'azure-pipelines-task-lib/mock-test';
import tl = require('azure-pipelines-task-lib');
Expand Down Expand Up @@ -381,4 +382,16 @@ describe('Docker Suite', function() {
console.log(tr.stderr);
done();
});

it('Runs successfully for docker build and populate ouput variable correctly', (done:Mocha.Done) => {
let tp = path.join(__dirname, 'TestSetup.js');
let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp);
process.env[shared.TestEnvVars.command] = shared.CommandTypes.buildImage;
tr.run();

assert(tr.succeeded, 'task should have succeeded');
assert(tr.stdout.indexOf("set DockerOutputPath=") != -1, "docker build should set DockerOutputPath env variable.")
console.log(tr.stderr);
done();
});
});
11 changes: 10 additions & 1 deletion Tasks/DockerV1/containerbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,14 @@ export function run(connection: ContainerConnection): any {
context = tl.getPathInput("buildContext");
}
command.arg(context);
return connection.execCommand(command);

let output: string = "";
command.on("stdout", data => {
output += data;
});

return connection.execCommand(command).then(() => {
let taskOutputPath = utils.writeTaskOutput("build", output);
tl.setVariable("DockerOutputPath", taskOutputPath);
});
}
6 changes: 5 additions & 1 deletion Tasks/DockerV1/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"author": "Microsoft Corporation",
"version": {
"Major": 1,
"Minor": 181,
"Minor": 187,
"Patch": 0
},
"demands": [],
Expand Down Expand Up @@ -365,6 +365,10 @@
{
"name": "DockerOutput",
"description": "Stores the output of the docker command"
},
{
"name": "DockerOutputPath",
"description": "The path of the file which contains the output of the build command."
}
],
"instanceNameFormat": "$(command)",
Expand Down
6 changes: 5 additions & 1 deletion Tasks/DockerV1/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"author": "Microsoft Corporation",
"version": {
"Major": 1,
"Minor": 181,
"Minor": 187,
"Patch": 0
},
"demands": [],
Expand Down Expand Up @@ -365,6 +365,10 @@
{
"name": "DockerOutput",
"description": "Stores the output of the docker command"
},
{
"name": "DockerOutputPath",
"description": "The path of the file which contains the output of the build command."
}
],
"instanceNameFormat": "ms-resource:loc.instanceNameFormat",
Expand Down
26 changes: 26 additions & 0 deletions Tasks/DockerV1/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import * as fs from "fs";
import ContainerConnection from "azure-pipelines-tasks-docker-common-v2/containerconnection";
import * as sourceUtils from "azure-pipelines-tasks-docker-common-v2/sourceutils";
import * as imageUtils from "azure-pipelines-tasks-docker-common-v2/containerimageutils";
import * as fileutils from "azure-pipelines-tasks-docker-common-v2/fileutils";
import * as path from "path";
import * as os from "os";

export function getImageNames(): string[] {
let imageNamesFilePath = tl.getPathInput("imageNamesPath", /* required */ true, /* check exists */ true);
Expand Down Expand Up @@ -72,6 +75,29 @@ export function getImageMappings(connection: ContainerConnection, imageNames: st
return sourceToTargetMapping;
}


function getTaskOutputDir(command: string): string {
let tempDirectory = tl.getVariable('agent.tempDirectory') || os.tmpdir();
let taskOutputDir = path.join(tempDirectory, "task_outputs");
return taskOutputDir;
}

export function writeTaskOutput(commandName: string, output: string): string {
let taskOutputDir = getTaskOutputDir(commandName);
if (!fs.existsSync(taskOutputDir)) {
fs.mkdirSync(taskOutputDir);
}

let outputFileName = commandName + "_" + Date.now() + ".txt";
let taskOutputPath = path.join(taskOutputDir, outputFileName);
if (fileutils.writeFileSync(taskOutputPath, output) == 0) {
tl.warning(tl.loc('NoDataWrittenOnFile', taskOutputPath));
}

return taskOutputPath;
}


interface ImageInfo {
/**
* The original, unmodified, image name provided as input to the task
Expand Down

0 comments on commit ea2446c

Please sign in to comment.