@@ -10,6 +10,7 @@ const cpExec = util.promisify(require('child_process').exec);
1010import { createScriptFile , TEMP_DIRECTORY , NullOutstreamStringWritable , deleteFile , getCurrentTime , checkIfEnvironmentVariableIsOmitted } from './utils' ;
1111
1212const START_SCRIPT_EXECUTION_MARKER : string = "Starting script execution via docker image mcr.microsoft.com/azure-cli:" ;
13+ const START_SCRIPT_DIRECT_EXECUTION_MARKER : string = "Starting script execution via az in the agent:" ;
1314const AZ_CLI_VERSION_DEFAULT_VALUE = 'agentazcliversion'
1415const prefix = ! ! process . env . AZURE_HTTP_USER_AGENT ? `${ process . env . AZURE_HTTP_USER_AGENT } ` : "" ;
1516
@@ -21,20 +22,23 @@ export async function main() {
2122
2223 var scriptFileName : string = '' ;
2324 const CONTAINER_NAME = `MICROSOFT_AZURE_CLI_${ getCurrentTime ( ) } _CONTAINER` ;
25+ let executingInContainer : boolean = false ;
2426 try {
2527 if ( process . env . RUNNER_OS != 'Linux' ) {
2628 throw new Error ( 'Please use Linux-based OS as a runner.' ) ;
2729 }
2830
2931 let inlineScript : string = core . getInput ( 'inlineScript' , { required : true } ) ;
3032 let azcliversion : string = core . getInput ( 'azcliversion' , { required : false } ) . trim ( ) . toLowerCase ( ) ;
33+ let inContainer : boolean = core . getInput ( 'inContainer' , { required : false } ) . trim ( ) . toLowerCase ( ) === 'true' ;
3134
3235 if ( azcliversion == AZ_CLI_VERSION_DEFAULT_VALUE ) {
3336 try {
3437 const { stdout } = await cpExec ( 'az version' ) ;
3538 azcliversion = JSON . parse ( stdout ) [ "azure-cli" ]
3639 } catch ( err ) {
3740 console . log ( 'Failed to fetch az cli version from agent. Reverting back to latest.' )
41+ console . log ( err )
3842 azcliversion = 'latest'
3943 }
4044 }
@@ -48,9 +52,22 @@ export async function main() {
4852 core . error ( 'Please enter a valid script.' ) ;
4953 throw new Error ( 'Please enter a valid script.' )
5054 }
55+ if ( inContainer == false ) {
56+ try {
57+ inlineScript = ` set -e >&2; echo '${ START_SCRIPT_DIRECT_EXECUTION_MARKER } ' >&2; ${ inlineScript } ` ;
58+ scriptFileName = await createScriptFile ( inlineScript ) ;
59+ let args : string [ ] = [ "--noprofile" , "--norc" , "-e" , `${ TEMP_DIRECTORY } /${ scriptFileName } ` ] ;
60+ console . log ( `${ START_SCRIPT_DIRECT_EXECUTION_MARKER } ` ) ;
61+ await executeBashCommand ( args ) ;
62+ console . log ( "az script ran successfully." ) ;
63+ return ;
64+ } catch ( err ) {
65+ console . log ( 'Failed to fetch az cli version from agent. Reverting back to execution in container.' )
66+ }
67+ }
68+ executingInContainer = true ;
5169 inlineScript = ` set -e >&2; echo '${ START_SCRIPT_EXECUTION_MARKER } ' >&2; ${ inlineScript } ` ;
5270 scriptFileName = await createScriptFile ( inlineScript ) ;
53-
5471 /*
5572 For the docker run command, we are doing the following
5673 - Set the working directory for docker continer
@@ -75,6 +92,7 @@ export async function main() {
7592 console . log ( `${ START_SCRIPT_EXECUTION_MARKER } ${ azcliversion } ` ) ;
7693 await executeDockerCommand ( args ) ;
7794 console . log ( "az script ran successfully." ) ;
95+
7896 }
7997 catch ( error ) {
8098 core . error ( error ) ;
@@ -84,8 +102,10 @@ export async function main() {
84102 // clean up
85103 const scriptFilePath : string = path . join ( TEMP_DIRECTORY , scriptFileName ) ;
86104 await deleteFile ( scriptFilePath ) ;
87- console . log ( "cleaning up container..." ) ;
88- await executeDockerCommand ( [ "rm" , "--force" , CONTAINER_NAME ] , true ) ;
105+ if ( executingInContainer ) {
106+ console . log ( "cleaning up container..." ) ;
107+ await executeDockerCommand ( [ "rm" , "--force" , CONTAINER_NAME ] , true ) ;
108+ }
89109 }
90110} ;
91111
@@ -157,3 +177,43 @@ const executeDockerCommand = async (args: string[], continueOnError: boolean = f
157177 core . warning ( errorStream )
158178 }
159179}
180+
181+ const executeBashCommand = async ( args : string [ ] , continueOnError : boolean = false ) : Promise < void > => {
182+
183+ const bash : string = await io . which ( "bash" , true ) ;
184+ var errorStream : string = '' ;
185+ var shouldOutputErrorStream : boolean = false ;
186+ var execOptions : any = {
187+ outStream : new NullOutstreamStringWritable ( { decodeStrings : false } ) ,
188+ listeners : {
189+ stdout : ( data : any ) => console . log ( data . toString ( ) ) , //to log the script output while the script is running.
190+ errline : ( data : string ) => {
191+ if ( ! shouldOutputErrorStream ) {
192+ errorStream += data + os . EOL ;
193+ }
194+ else {
195+ console . log ( data ) ;
196+ }
197+ if ( data . trim ( ) === START_SCRIPT_EXECUTION_MARKER ) {
198+ shouldOutputErrorStream = true ;
199+ errorStream = '' ; // Flush the container logs. After this, script error logs will be tracked.
200+ }
201+ }
202+ }
203+ } ;
204+ var exitCode ;
205+ try {
206+ exitCode = await exec . exec ( bash , args , execOptions ) ;
207+ } catch ( error ) {
208+ if ( ! continueOnError ) {
209+ throw error ;
210+ }
211+ core . warning ( error ) ;
212+ }
213+ finally {
214+ if ( exitCode !== 0 && ! continueOnError ) {
215+ throw new Error ( errorStream || 'az cli script failed.' ) ;
216+ }
217+ core . warning ( errorStream )
218+ }
219+ }
0 commit comments