@@ -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,13 +22,15 @@ 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 {
@@ -48,9 +51,22 @@ export async function main() {
4851 core . error ( 'Please enter a valid script.' ) ;
4952 throw new Error ( 'Please enter a valid script.' )
5053 }
54+ if ( inContainer == false ) {
55+ try {
56+ inlineScript = ` set -e >&2; echo '${ START_SCRIPT_DIRECT_EXECUTION_MARKER } ' >&2; ${ inlineScript } ` ;
57+ scriptFileName = await createScriptFile ( inlineScript ) ;
58+ let args : string [ ] = [ "--noprofile" , "--norc" , "-e" , `${ TEMP_DIRECTORY } /${ scriptFileName } ` ] ;
59+ console . log ( `${ START_SCRIPT_DIRECT_EXECUTION_MARKER } ` ) ;
60+ await executeBashCommand ( args ) ;
61+ console . log ( "az script ran successfully." ) ;
62+ return ;
63+ } catch ( err ) {
64+ console . log ( 'Failed to fetch az cli version from agent. Reverting back to execution in container.' )
65+ }
66+ }
67+ executingInContainer = true ;
5168 inlineScript = ` set -e >&2; echo '${ START_SCRIPT_EXECUTION_MARKER } ' >&2; ${ inlineScript } ` ;
5269 scriptFileName = await createScriptFile ( inlineScript ) ;
53-
5470 /*
5571 For the docker run command, we are doing the following
5672 - Set the working directory for docker continer
@@ -75,6 +91,7 @@ export async function main() {
7591 console . log ( `${ START_SCRIPT_EXECUTION_MARKER } ${ azcliversion } ` ) ;
7692 await executeDockerCommand ( args ) ;
7793 console . log ( "az script ran successfully." ) ;
94+
7895 }
7996 catch ( error ) {
8097 core . error ( error ) ;
@@ -84,8 +101,10 @@ export async function main() {
84101 // clean up
85102 const scriptFilePath : string = path . join ( TEMP_DIRECTORY , scriptFileName ) ;
86103 await deleteFile ( scriptFilePath ) ;
87- console . log ( "cleaning up container..." ) ;
88- await executeDockerCommand ( [ "rm" , "--force" , CONTAINER_NAME ] , true ) ;
104+ if ( executingInContainer ) {
105+ console . log ( "cleaning up container..." ) ;
106+ await executeDockerCommand ( [ "rm" , "--force" , CONTAINER_NAME ] , true ) ;
107+ }
89108 }
90109} ;
91110
@@ -157,3 +176,43 @@ const executeDockerCommand = async (args: string[], continueOnError: boolean = f
157176 core . warning ( errorStream )
158177 }
159178}
179+
180+ const executeBashCommand = async ( args : string [ ] , continueOnError : boolean = false ) : Promise < void > => {
181+
182+ const bash : string = await io . which ( "bash" , true ) ;
183+ var errorStream : string = '' ;
184+ var shouldOutputErrorStream : boolean = false ;
185+ var execOptions : any = {
186+ outStream : new NullOutstreamStringWritable ( { decodeStrings : false } ) ,
187+ listeners : {
188+ stdout : ( data : any ) => console . log ( data . toString ( ) ) , //to log the script output while the script is running.
189+ errline : ( data : string ) => {
190+ if ( ! shouldOutputErrorStream ) {
191+ errorStream += data + os . EOL ;
192+ }
193+ else {
194+ console . log ( data ) ;
195+ }
196+ if ( data . trim ( ) === START_SCRIPT_EXECUTION_MARKER ) {
197+ shouldOutputErrorStream = true ;
198+ errorStream = '' ; // Flush the container logs. After this, script error logs will be tracked.
199+ }
200+ }
201+ }
202+ } ;
203+ var exitCode ;
204+ try {
205+ exitCode = await exec . exec ( bash , args , execOptions ) ;
206+ } catch ( error ) {
207+ if ( ! continueOnError ) {
208+ throw error ;
209+ }
210+ core . warning ( error ) ;
211+ }
212+ finally {
213+ if ( exitCode !== 0 && ! continueOnError ) {
214+ throw new Error ( errorStream || 'az cli script failed.' ) ;
215+ }
216+ core . warning ( errorStream )
217+ }
218+ }
0 commit comments