@@ -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,23 @@ 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+ console . log ( err )
67+ }
68+ }
69+ executingInContainer = true ;
5170 inlineScript = ` set -e >&2; echo '${ START_SCRIPT_EXECUTION_MARKER } ' >&2; ${ inlineScript } ` ;
5271 scriptFileName = await createScriptFile ( inlineScript ) ;
53-
5472 /*
5573 For the docker run command, we are doing the following
5674 - Set the working directory for docker continer
@@ -75,6 +93,7 @@ export async function main() {
7593 console . log ( `${ START_SCRIPT_EXECUTION_MARKER } ${ azcliversion } ` ) ;
7694 await executeDockerCommand ( args ) ;
7795 console . log ( "az script ran successfully." ) ;
96+
7897 }
7998 catch ( error ) {
8099 core . error ( error ) ;
@@ -84,8 +103,10 @@ export async function main() {
84103 // clean up
85104 const scriptFilePath : string = path . join ( TEMP_DIRECTORY , scriptFileName ) ;
86105 await deleteFile ( scriptFilePath ) ;
87- console . log ( "cleaning up container..." ) ;
88- await executeDockerCommand ( [ "rm" , "--force" , CONTAINER_NAME ] , true ) ;
106+ if ( executingInContainer ) {
107+ console . log ( "cleaning up container..." ) ;
108+ await executeDockerCommand ( [ "rm" , "--force" , CONTAINER_NAME ] , true ) ;
109+ }
89110 }
90111} ;
91112
@@ -157,3 +178,43 @@ const executeDockerCommand = async (args: string[], continueOnError: boolean = f
157178 core . warning ( errorStream )
158179 }
159180}
181+
182+ const executeBashCommand = async ( args : string [ ] , continueOnError : boolean = false ) : Promise < void > => {
183+
184+ const bash : string = await io . which ( "bash" , true ) ;
185+ var errorStream : string = '' ;
186+ var shouldOutputErrorStream : boolean = false ;
187+ var execOptions : any = {
188+ outStream : new NullOutstreamStringWritable ( { decodeStrings : false } ) ,
189+ listeners : {
190+ stdout : ( data : any ) => console . log ( data . toString ( ) ) , //to log the script output while the script is running.
191+ errline : ( data : string ) => {
192+ if ( ! shouldOutputErrorStream ) {
193+ errorStream += data + os . EOL ;
194+ }
195+ else {
196+ console . log ( data ) ;
197+ }
198+ if ( data . trim ( ) === START_SCRIPT_EXECUTION_MARKER ) {
199+ shouldOutputErrorStream = true ;
200+ errorStream = '' ; // Flush the container logs. After this, script error logs will be tracked.
201+ }
202+ }
203+ }
204+ } ;
205+ var exitCode ;
206+ try {
207+ exitCode = await exec . exec ( bash , args , execOptions ) ;
208+ } catch ( error ) {
209+ if ( ! continueOnError ) {
210+ throw error ;
211+ }
212+ core . warning ( error ) ;
213+ }
214+ finally {
215+ if ( exitCode !== 0 && ! continueOnError ) {
216+ throw new Error ( errorStream || 'az cli script failed.' ) ;
217+ }
218+ core . warning ( errorStream )
219+ }
220+ }
0 commit comments