Skip to content

Commit

Permalink
Adding inContainer input parameter to be able to switch between direc…
Browse files Browse the repository at this point in the history
…t and in-container mode of execution
  • Loading branch information
Waldek Herka committed Apr 1, 2024
1 parent 99c7fe7 commit ffe2adf
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 4 deletions.
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ inputs:
description: 'Azure CLI version to be used to execute the script. If not provided, latest version is used'
required: false
default: 'agentazcliversion'
inContainer:
description: 'Execute the commands in container'
required: false
default: true
branding:
icon: 'login.svg'
color: 'blue'
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

66 changes: 63 additions & 3 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const cpExec = util.promisify(require('child_process').exec);
import { createScriptFile, TEMP_DIRECTORY, NullOutstreamStringWritable, deleteFile, getCurrentTime, checkIfEnvironmentVariableIsOmitted } from './utils';

const START_SCRIPT_EXECUTION_MARKER: string = "Starting script execution via docker image mcr.microsoft.com/azure-cli:";
const START_SCRIPT_DIRECT_EXECUTION_MARKER: string = "Starting script execution via az in the agent:";
const AZ_CLI_VERSION_DEFAULT_VALUE = 'agentazcliversion'
const prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : "";

Expand All @@ -21,20 +22,23 @@ export async function main() {

var scriptFileName: string = '';
const CONTAINER_NAME = `MICROSOFT_AZURE_CLI_${getCurrentTime()}_CONTAINER`;
let executingInContainer: boolean = false;
try {
if (process.env.RUNNER_OS != 'Linux') {
throw new Error('Please use Linux-based OS as a runner.');
}

let inlineScript: string = core.getInput('inlineScript', { required: true });
let azcliversion: string = core.getInput('azcliversion', { required: false }).trim().toLowerCase();
let inContainer: boolean = core.getInput('inContainer', { required: false }).trim().toLowerCase() === 'true';

if (azcliversion == AZ_CLI_VERSION_DEFAULT_VALUE) {
try {
const { stdout } = await cpExec('az version');
azcliversion = JSON.parse(stdout)["azure-cli"]
} catch (err) {
console.log('Failed to fetch az cli version from agent. Reverting back to latest.')
console.log(err)
azcliversion = 'latest'
}
}
Expand All @@ -48,9 +52,22 @@ export async function main() {
core.error('Please enter a valid script.');
throw new Error('Please enter a valid script.')
}
if (inContainer == false) {
try {
inlineScript = ` set -e >&2; echo '${START_SCRIPT_DIRECT_EXECUTION_MARKER}' >&2; ${inlineScript}`;
scriptFileName = await createScriptFile(inlineScript);
let args: string[] = ["--noprofile", "--norc", "-e", `${TEMP_DIRECTORY}/${scriptFileName}`];
console.log(`${START_SCRIPT_DIRECT_EXECUTION_MARKER}`);
await executeBashCommand(args);
console.log("az script ran successfully.");
return;
} catch (err) {
console.log('Failed to fetch az cli version from agent. Reverting back to execution in container.')
}
}
executingInContainer = true;
inlineScript = ` set -e >&2; echo '${START_SCRIPT_EXECUTION_MARKER}' >&2; ${inlineScript}`;
scriptFileName = await createScriptFile(inlineScript);

/*
For the docker run command, we are doing the following
- Set the working directory for docker continer
Expand All @@ -75,6 +92,7 @@ export async function main() {
console.log(`${START_SCRIPT_EXECUTION_MARKER}${azcliversion}`);
await executeDockerCommand(args);
console.log("az script ran successfully.");

}
catch (error) {
core.error(error);
Expand All @@ -84,8 +102,10 @@ export async function main() {
// clean up
const scriptFilePath: string = path.join(TEMP_DIRECTORY, scriptFileName);
await deleteFile(scriptFilePath);
console.log("cleaning up container...");
await executeDockerCommand(["rm", "--force", CONTAINER_NAME], true);
if (executingInContainer) {
console.log("cleaning up container...");
await executeDockerCommand(["rm", "--force", CONTAINER_NAME], true);
}
}
};

Expand Down Expand Up @@ -157,3 +177,43 @@ const executeDockerCommand = async (args: string[], continueOnError: boolean = f
core.warning(errorStream)
}
}

const executeBashCommand = async (args: string[], continueOnError: boolean = false): Promise<void> => {

const bash: string = await io.which("bash", true);
var errorStream: string = '';
var shouldOutputErrorStream: boolean = false;
var execOptions: any = {
outStream: new NullOutstreamStringWritable({ decodeStrings: false }),
listeners: {
stdout: (data: any) => console.log(data.toString()), //to log the script output while the script is running.
errline: (data: string) => {
if (!shouldOutputErrorStream) {
errorStream += data + os.EOL;
}
else {
console.log(data);
}
if (data.trim() === START_SCRIPT_EXECUTION_MARKER) {
shouldOutputErrorStream = true;
errorStream = ''; // Flush the container logs. After this, script error logs will be tracked.
}
}
}
};
var exitCode;
try {
exitCode = await exec.exec(bash, args, execOptions);
} catch (error) {
if (!continueOnError) {
throw error;
}
core.warning(error);
}
finally {
if (exitCode !== 0 && !continueOnError) {
throw new Error(errorStream || 'az cli script failed.');
}
core.warning(errorStream)
}
}

0 comments on commit ffe2adf

Please sign in to comment.