package Ġcom . save our tool . save . orche strator . service Ċ Ċ import Ġcom . save our tool . save . domain . Python Ċ import Ġcom . save our tool . save . entities . Execution Ċ import Ġcom . save our tool . save . entities . TestSuite Ċ import Ġcom . save our tool . save . execution . Execution Status Ċ import Ġcom . save our tool . save . execution . Execution Update Dto Ċ import Ġcom . save our tool . save . orche strator . SAVE _ CLI _ EXECUT ABLE _ NAME Ċ import Ġcom . save our tool . save . orche strator . config . Config Properties Ċ import Ġcom . save our tool . save . orche strator . copy Re cursively With Attributes Ċ import Ġcom . save our tool . save . orche strator . create Synt hetic Tom l Config Ċ import Ġcom . save our tool . save . orche strator . docker . Container Manager Ċ import Ġcom . save our tool . save . orche strator . fill Agent Properties From Configuration Ċ import Ġcom . save our tool . save . tests uite . TestSuite Dto Ċ import Ġcom . save our tool . save . utils . PREFIX _ FOR _ SU ITES _ LOCATION _ IN _ STANDARD _ MODE Ċ import Ġcom . save our tool . save . utils . STANDARD _ TEST _ SUITE _ DIR Ċ import Ġcom . save our tool . save . utils . move File With Attributes Ċ Ċ import Ġcom . github . docker java . api . exception . Docker Exception Ċ import Ġio . micro meter . core . instrument . Meter Registry Ċ import Ġnet . ling ala . zip 4 j . Zip File Ċ import Ġnet . ling ala . zip 4 j . exception . Zip Exception Ċ import Ġorg . apache . commons . io . FileUtils Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġorg . springframework . beans . factory . annotation . Autowired Ċ import Ġorg . springframework . beans . factory . annotation . Qualifier Ċ import Ġorg . springframework . core . io . Class Path Resource Ċ import Ġorg . springframework . http . MediaType Ċ import Ġorg . springframework . stereotype . Service Ċ import Ġorg . springframework . util . FileSystem Utils Ċ import Ġorg . springframework . web . reactive . function . Body Inser ters Ċ import Ġorg . springframework . web . reactive . function . client . Web Client Ċ import Ġorg . springframework . web . reactive . function . client . body To Mono Ċ Ċ import Ġjava . io . File Ċ import Ġjava . nio . file . Files Ċ import Ġjava . nio . file . Link Option Ċ import Ġjava . nio . file . attribute . Pos ix File Attribute View Ċ import Ġjava . util . concurrent . atomic . Atomic Boolean Ċ Ċ import Ġkotlin . io . path . Experimental Path Api Ċ Ċ /** Ċ Ġ* ĠA Ġservice Ġthat Ġuses Ġ[ Container Manager ] Ġto Ġbuild Ġand Ġstart Ġcontainers Ġfor Ġtest Ġexecution . Ċ Ġ*/ Ċ @ Service Ċ @ Opt In ( Experimental Path Api :: class ) Ċ class ĠDocker Service ( private Ġval Ġconfig Properties : ĠConfig Properties , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmeter Registry : ĠMeter Registry , Ċ ) Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ[ Container Manager ] Ġthat Ġis Ġused Ġto Ġaccess Ġdocker Ġdaemon ĠAPI ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinternal Ġval Ġcontainer Manager Ġ= ĠContainer Manager ( config Properties . docker , Ġmeter Registry ) ĊĠĠĠ Ġprivate Ġval Ġexecution Dir Ġ= Ġ"/ run / save - execution " ĊĊĠĠĠ Ġ@ Suppress (" Non Boolean Property Prefix ed With Is ") ĊĠĠĠ Ġprivate Ġval Ġis Agent Stopping InProgress Ġ= ĠAtomic Boolean ( false ) ĊĊĠĠĠ Ġ@ Autowired ĊĠĠĠ Ġ@ Qualifier (" web Client Backend ") ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġweb Client Backend : ĠWeb Client ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠFunction Ġthat Ġbuilds Ġa Ġbase Ġimage Ġwith Ġtest Ġresources Ġand Ġthen Ġcreates Ġcontainers Ġwith Ġagents . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġexecution Ġ[ Execution ] Ġfrom Ġwhich Ġthis Ġworkflow Ġis Ġstarted ĊĠĠĠĠ Ġ* Ġ@ param Ġtest Suite Dto s Ġtest Ġsu ites , Ġselected Ġby Ġuser ĊĠĠĠĠ Ġ* Ġ@ return Ġlist Ġof ĠIDs Ġof Ġcreated Ġcontainers ĊĠĠĠĠ Ġ* Ġ@ throws ĠDocker Exception Ġif Ġinteraction Ġwith Ġdocker Ġdaemon Ġis Ġnot Ġsuccessful ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġbuild And Create Containers ( ĊĠĠĠĠĠĠĠ Ġexecution : ĠExecution , ĊĠĠĠĠĠĠĠ Ġtest Suite Dto s : ĠList < TestSuite Dto > ?, ĊĠĠĠ Ġ): ĠList < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . info (" Building Ġbase Ġimage Ġfor Ġexecution . id =${ execution . id }") ĊĠĠĠĠĠĠĠ Ġval Ġ( image Id , Ġagent Run Cmd ) Ġ= Ġbuild Base Image For Execution ( execution , Ġtest Suite Dto s ) ĊĠĠĠĠĠĠĠ Ġlog . info (" Built Ġbase Ġimage Ġfor Ġexecution . id =${ execution . id }") ĊĠĠĠĠĠĠĠ Ġreturn Ġ( 1 .. config Properties . agents Count ). map Ġ{ Ġnumber Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Building Ġcontainer Ġ#$ number Ġfor Ġexecution . id =${ execution . id }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontainer Manager . create Container From Image ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimage Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecution Dir , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġagent Run Cmd , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontainer Name ("${ execution . id }- $ number "), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Built Ġcontainer Ġid =$ it Ġfor Ġexecution . id =${ execution . id }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġexecution Ġan Ġ[ Execution ] Ġfor Ġwhich Ġcontainers Ġare Ġbeing Ġstarted ĊĠĠĠĠ Ġ* Ġ@ param Ġagent Ids Ġlist Ġof ĠIDs Ġof Ġagents Ġ( == containers ) Ġfor Ġthis Ġexecution ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġstart Containers AndUpdate Execution ( execution : ĠExecution , Ġagent Ids : ĠList < String >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġexecution Id Ġ= Ġrequire NotNull ( execution . id ) Ġ{ Ġ" For Ġproject =${ execution . project } Ġmethod Ġhas Ġbeen Ġcalled Ġwith Ġexecution Ġwith Ġid = null " Ġ} ĊĠĠĠĠĠĠĠ Ġlog . info (" Sending Ġrequest Ġto Ġmake Ġexecution . id =$ execution Id ĠRUN NING ") ĊĠĠĠĠĠĠĠ Ġweb Client Backend ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. post () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. uri ("/ update Execution By Dto ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. body ( Body Inser ters . from Value ( Execution Update Dto ( execution Id , ĠExecution Status . RUNNING ))) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. retrieve () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. to B od ile ss Entity () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. subscribe () ĊĠĠĠĠĠĠĠ Ġagent Ids . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Starting Ġcontainer Ġid =$ it ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontainer Manager . docker Client ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. start Container Cmd ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. exec () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġlog . info (" Successfully Ġstarted Ġall Ġcontainers Ġfor Ġexecution . id =$ execution Id ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġagent Ids Ġlist Ġof ĠIDs Ġof Ġagents Ġto Ġstop ĊĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġagents Ġhave Ġbeen Ġstopped , Ġfalse Ġif Ġanother Ġthread Ġis Ġalready Ġstopping Ġthem ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Suppress (" TOO _ MAN Y _ LINES _ IN _ L AMBDA ") ĊĠĠĠ Ġfun Ġstop Agents ( agent Ids : ĠCollection < String >) Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Agent Stopping InProgress . compare AndSet ( false , Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontainer List Ġ= Ġcontainer Manager . docker Client . list Containers Cmd (). with Show All ( true ). exec () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrunning Containers Ids Ġ= Ġcontainer List . filter Ġ{ Ġit . state Ġ== Ġ" running " Ġ}. map Ġ{ Ġit . id Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġagent Ids . forEach Ġ{ Ġagent Id Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( agent Id Ġin Ġrunning Containers Ids ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Stopping Ġagent Ġwith Ġid =$ agent Id ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontainer Manager . docker Client . stop Container Cmd ( agent Id ). exec () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Agent Ġwith Ġid =$ agent Id Ġhas Ġbeen Ġstopped ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġcontainer List . find Ġ{ Ġit . id Ġ== Ġagent Id Ġ} ?. state Ġ?: Ġ" deleted " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwarn Msg Ġ= Ġ" Agent Ġwith Ġid =$ agent Id Ġwas Ġrequested Ġto Ġbe Ġstopped , Ġbut Ġit Ġactual Ġstate =$ state " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . warn ( warn Msg ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( dex : ĠDocker Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error (" Error Ġwhile Ġstopping Ġagents Ġ$ agent Ids ", Ġdex ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Agent Stopping InProgress . lazy Set ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Agents Ġstopping Ġis Ġalready Ġin Ġprogress , Ġskipping ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġimage Name Ġname Ġof Ġthe Ġimage Ġto Ġremove ĊĠĠĠĠ Ġ* Ġ@ return Ġan Ġinstance Ġof Ġdocker Ġcommand ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġremove Image ( image Name : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . info (" Removing Ġimage Ġ$ image Name ") ĊĠĠĠĠĠĠĠ Ġval Ġexisting Images Ġ= Ġcontainer Manager . docker Client . list Images Cmd (). exec (). map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . id ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( image Name Ġin Ġexisting Images ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontainer Manager . docker Client . remove Image Cmd ( image Name ). exec () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Image Ġ$ image Name Ġis Ġnot Ġpresent , Ġso Ġwon 't Ġattempt Ġto Ġremove ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġcontainer Id Ġid Ġof Ġcontainer Ġto Ġremove ĊĠĠĠĠ Ġ* Ġ@ return Ġan Ġinstance Ġof Ġdocker Ġcommand ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġremove Container ( container Id : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . info (" Removing Ġcontainer Ġ$ container Id ") ĊĠĠĠĠĠĠĠ Ġval Ġexisting Container Ids Ġ= Ġcontainer Manager . docker Client . list Containers Cmd (). with Show All ( true ). exec () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . id ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( container Id Ġin Ġexisting Container Ids ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontainer Manager . docker Client . remove Container Cmd ( container Id ). exec () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Container Ġ$ container Id Ġis Ġnot Ġpresent , Ġso Ġwon 't Ġattempt Ġto Ġremove ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress ( ĊĠĠĠĠĠĠĠ Ġ" TOO _ LONG _ FUNCTION ", ĊĠĠĠĠĠĠĠ Ġ" Unsafe Call On Nullable Type ", ĊĠĠĠĠĠĠĠ Ġ" Long Method ", ĊĠĠĠ Ġ) ĊĠĠĠ Ġprivate Ġfun Ġbuild Base Image For Execution ( ĊĠĠĠĠĠĠĠ Ġexecution : ĠExecution , ĊĠĠĠĠĠĠĠ Ġtest Suite Dto s : ĠList < TestSuite Dto >? ĊĠĠĠ Ġ): ĠPair < String , ĠString > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresources Path Ġ= ĠFile ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconfig Properties . test Resources . basePath , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecution . resources RootPath !! , ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġagent Run Cmd Ġ= Ġ"./ $ SAVE _ AGENT _ EXECUT ABLE _ NAME " ĊĊĠĠĠĠĠĠĠ Ġ// Ġcollect Ġstandard Ġtest Ġsu ites Ġfor Ġdocker Ġimage , Ġwhich Ġwere Ġselected Ġby Ġuser , Ġif Ġany ĊĠĠĠĠĠĠĠ Ġval Ġtest Su ites For Docker Ġ= Ġcollect Standard Test Su ites For Docker ( test Suite Dto s ) ĊĠĠĠĠĠĠĠ Ġval Ġtest Su ites Dir Ġ= Ġresources Path . resolve ( STANDARD _ TEST _ SUITE _ DIR ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġlist Ġis Ġnot Ġempty Ġonly Ġin Ġstandard Ġmode ĊĠĠĠĠĠĠĠ Ġval Ġis Standard Mode Ġ= Ġtest Su ites For Docker . isNotEmpty () ĊĊĠĠĠĠĠĠĠ Ġif Ġ( is Standard Mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcopy Ġcorresponding Ġstandard Ġtest Ġsu ites Ġto Ġresources RootPath Ġdir ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcopy Test Su ites To Resources Path ( test Su ites For Docker , Ġtest Su ites Dir ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġmove Ġadditional Ġfiles , Ġwhich Ġwere Ġdownloaded Ġinto Ġthe Ġroot Ġdit Ġto Ġthe Ġexecution Ġdir Ġfor Ġstandard Ġsu ites ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecution . additional Files ?. split ("; ") ?. filter Ġ{ Ġit . isNotBlank () Ġ} ?. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġadditional FilePath Ġ= Ġresources Path . resolve ( File ( it ). name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Move Ġadditional Ġfile Ġ$ additional FilePath Ġinto Ġ$ test Su ites Dir ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmove File With Attributes ( additional FilePath , Ġtest Su ites Dir ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġif Ġsome Ġadditional Ġfile Ġis Ġarchive , Ġunzip Ġit Ġinto Ġproper Ġdestination : ĊĠĠĠĠĠĠĠ Ġ// Ġfor Ġstandard Ġmode Ġinto ĠST AND ARD _ TEST _ SUITE _ DIR ĊĠĠĠĠĠĠĠ Ġ// Ġfor ĠGit Ġmode Ġinto Ġtest RootPath ĊĠĠĠĠĠĠĠ Ġunzip Arch ives A mong Additional Files ( execution , Ġis Standard Mode , Ġtest Su ites Dir , Ġresources Path ) ĊĊĠĠĠĠĠĠĠ Ġval Ġsave Cli Exec Flags Ġ= Ġif Ġ( is Standard Mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcreate Ġstub Ġto ml Ġconfig Ġin Ġaim Ġto Ġexecute Ġall Ġtest Ġsu ites Ġdirectories Ġfrom Ġ` test Su ites Dir ` ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconfig Data Ġ= Ġcreate Synt hetic Tom l Config ( execution . exec Cmd , Ġexecution . batch Size For Analyzer ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtest Su ites Dir . resolve (" save . toml "). apply Ġ{ Ġcreate New File () Ġ}. write Text ( config Data ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ġ$ STANDARD _ TEST _ SUITE _ DIR Ġ-- include - su ites Ġ\" ${ test Su ites For Docker . join ToString (",") Ġ{ Ġit . name Ġ}} \"" ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"" ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġinclude Ġsave - agent Ġinto Ġthe Ġimage ĊĠĠĠĠĠĠĠ Ġval Ġsave Agent Ġ= ĠFile ( resources Path , ĠSAVE _ AGENT _ EXECUT ABLE _ NAME ) ĊĠĠĠĠĠĠĠ ĠFileUtils . copy InputStream ToFile ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠClass Path Resource ( SAVE _ AGENT _ EXECUT ABLE _ NAME ). inputStream , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsave Agent ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġinclude Ġsave - cli Ġinto Ġthe Ġimage ĊĠĠĠĠĠĠĠ Ġval Ġsave Cli Ġ= ĠFile ( resources Path , ĠSAVE _ CLI _ EXECUT ABLE _ NAME ) ĊĠĠĠĠĠĠĠ ĠFileUtils . copy InputStream ToFile ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠClass Path Resource ( SAVE _ CLI _ EXECUT ABLE _ NAME ). inputStream , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsave Cli ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( config Properties . adjust Resource Owner ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchange Owner Re cursively ( resources Path , Ġ" c nb ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġagent Properties File Ġ= ĠFile ( resources Path , Ġ" agent . properties ") ĊĠĠĠĠĠĠĠ Ġfill Agent Properties From Configuration ( agent Properties File , Ġconfig Properties . agent Settings , Ġsave Cli Exec Flags ) ĊĊĠĠĠĠĠĠĠ Ġval Ġbase Image Ġ= Ġexecution . sdk ĊĠĠĠĠĠĠĠ Ġval Ġapt Cmd Ġ= Ġ" apt - get Ġ${ config Properties . apt Extra Flags }" ĊĠĠĠĠĠĠĠ Ġ// Ġfix me : Ġhttps :// github . com / save our tool / save - cloud / issues / 3 5 2 ĊĠĠĠĠĠĠĠ Ġval Ġadditional Run Cmd Ġ= Ġif Ġ( execution . sdk . startsWith ( Python . NAME , Ġignore Case Ġ= Ġtrue )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ""" | RUN Ġenv ĠDE BI AN _ FRONT END =" non interactive " Ġ$ apt Cmd Ġinstall Ġzip ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ| RUN Ġcurl Ġ- s Ġ" https :// get . sdk man . io " Ġ| Ġbash ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ| RUN Ġbash Ġ- c Ġ' source Ġ"${ '$ '} HOME /. sdk man / bin / sdk man - init . sh " Ġ&& Ġsdk Ġinstall Ġjava Ġ 8 . 0 . 3 0 2 - open ' ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ| RUN Ġln Ġ- s Ġ${ '$ '} ( which Ġjava ) Ġ/ usr / bin / java ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ""" . trim Margin () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġimage Id Ġ= Ġcontainer Manager . build Image With Resources ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbase Image Ġ= Ġbase Image , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimage Name Ġ= Ġimage Name ( execution . id !! ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbase Dir Ġ= Ġresources Path , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresources Path Ġ= Ġexecution Dir , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrun Cmd Ġ= Ġ""" RUN Ġ$ apt Cmd Ġupdate Ġ&& Ġenv ĠDE BI AN _ FRONT END =" non interactive " Ġ$ apt Cmd Ġinstall Ġ- y Ġ\ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ| lib curl 4 - openssl - dev Ġtz data ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ| RUN Ġln Ġ- fs Ġ/ usr / share / zone info / UTC Ġ/ etc / local time ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ| $ additional Run Cmd ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ| RUN Ġrm Ġ- rf Ġ/ var / lib / apt / lists /* ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ| RUN Ġchmod Ġ+ x Ġ$ execution Dir /$ SAVE _ AGENT _ EXECUT ABLE _ NAME ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ| RUN Ġchmod Ġ+ x Ġ$ execution Dir /$ SAVE _ CLI _ EXECUT ABLE _ NAME ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġsave Agent . delete () ĊĠĠĠĠĠĠĠ Ġsave Cli . delete () ĊĠĠĠĠĠĠĠ Ġreturn ĠPair ( image Id , Ġagent Run Cmd ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġchange Owner Re cursively ( directory : ĠFile , Ġuser : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġorche strator Ġis Ġexecuted Ġas Ġroot Ġ( to Ġaccess Ġdocker Ġsocket ), Ġbut Ġfiles Ġare Ġin Ġa Ġshared Ġvolume ĊĠĠĠĠĠĠĠ Ġval Ġlookup Service Ġ= Ġdirectory . to Path (). file System . user Principal Lookup Service ĊĠĠĠĠĠĠĠ Ġdirectory . walk (). forEach Ġ{ Ġfile Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFiles . getFile Attribute View ( file . to Path (), ĠPos ix File Attribute View :: class . java , ĠLink Option . NO FOLLOW _ LIN KS ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Group ( lookup Service . lookup Principal By GroupName ( user )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Owner ( lookup Service . lookup Principal ByName ( user )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress (" TOO _ MAN Y _ LINES _ IN _ L AMBDA ") ĊĠĠĠ Ġprivate Ġfun Ġunzip Arch ives A mong Additional Files ( ĊĠĠĠĠĠĠĠ Ġexecution : ĠExecution , ĊĠĠĠĠĠĠĠ Ġis Standard Mode : ĠBoolean , ĊĠĠĠĠĠĠĠ Ġtest Su ites Dir : ĠFile , ĊĠĠĠĠĠĠĠ Ġresources Path : ĠFile , ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠFix Me : Ġfor Ġnow Ġsupport Ġonly Ġ. zip Ġfiles ĊĠĠĠĠĠĠĠ Ġexecution . additional Files ?. split ("; ") ?. filter Ġ{ Ġit . endsWith (". zip ") Ġ} ?. forEach Ġ{ ĠfileName Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Location Ġ= Ġif Ġ( is Standard Mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtest Su ites Dir ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtest RootPath Ġ= Ġweb Client Backend . post () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. uri ("/ find Test RootPath For Execution By Test Su ites ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. contentType ( MediaType . APPLICATION _ JSON ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. body ( Body Inser ters . from Value ( execution )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. retrieve () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. body To Mono < List < String >>() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. block () !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. distinct () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. single () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresources Path . resolve ( test RootPath ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġfile Location . resolve ( File ( fileName ). name ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠshouldBe Executable Ġ= Ġfile . can Execute () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . debug (" Un zip Ġ${ file . absolute Path } Ġinto Ġ${ file Location . absolute Path }") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile . unzip Into ( file Location ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( shouldBe Executable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Mark ing Ġfiles Ġin Ġ$ file Location Ġexecutable ...") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Location . walk Top Down (). forEach Ġ{ Ġsource Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! source . set Executable ( true )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . warn (" Failed Ġto Ġmark Ġfile Ġ${ source . name } Ġas Ġexecutable ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile . delete () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠFile . unzip Into ( destination : ĠFile ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġzip File Ġ= ĠZip File ( this . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġzip File . extract All ( destination . toString ()) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠZip Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error (" Error Ġoccurred Ġduring Ġextracting Ġof Ġarchive Ġ${ this . name }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcollect Standard Test Su ites For Docker ( test Suite Dto s : ĠList < TestSuite Dto >? ): ĠList < TestSuite Dto > Ġ= Ġtest Suite Dto s ?. flatMap Ġ{ ĊĠĠĠĠĠĠĠ Ġweb Client Backend . get () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. uri ("/ standard Test Su ites WithName ? name =${ it . name }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. retrieve () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. body To Mono < List < TestSuite >>() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. block () !! ĊĠĠĠ Ġ} ?. map Ġ{ Ġit . to Dto () Ġ} Ġ?: Ġempty List () ĊĊĠĠĠ Ġ@ Suppress (" Unsafe Call On Nullable Type ", Ġ" TOO _ MAN Y _ LINES _ IN _ L AMBDA ") ĊĠĠĠ Ġprivate Ġfun Ġcopy Test Su ites To Resources Path ( test Su ites For Docker : ĠList < TestSuite Dto >, Ġdestination : ĠFile ) Ġ{ ĊĠĠĠĠĠĠĠ ĠFileSystem Utils . delete Re cursively ( destination ) ĊĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġhttps :// github . com / save our tool / save - cloud / issues / 3 2 1 ĊĠĠĠĠĠĠĠ Ġlog . info (" Copy ing Ġsu ites Ġ${ test Su ites For Docker . map Ġ{ Ġit . name Ġ}} Ġinto Ġ$ destination ") ĊĠĠĠĠĠĠĠ Ġtest Su ites For Docker . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstandard TestSuite AbsolutePath Ġ= ĠFile ( config Properties . test Resources . basePath ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtmp Ġdirectories Ġnames Ġfor Ġstandard Ġtest Ġsu ites Ġconstructs Ġjust Ġby ĠhashCode Ġof ĠlistOf ( repo Url ); Ġreuse Ġthis Ġlogic ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. resolve ( File ("${ listOf ( it . test Suite Repo Url !! ). hashCode () }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. resolve ( it . test RootPath ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Suite Destination Ġ= Ġdestination . resolve ( getLocation In Standard Dir For TestSuite ( it )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! current Suite Destination . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . debug (" Copy ing Ġsuite Ġ${ it . name } Ġfrom Ġ$ standard TestSuite AbsolutePath Ġinto Ġ$ current Suite Destination / ...") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcopy Re cursively With Attributes ( standard TestSuite AbsolutePath , Ġcurrent Suite Destination ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġlog Ġ= ĠLoggerFactory . getLogger ( Docker Service :: class . java ) ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠSAVE _ AGENT _ EXECUT ABLE _ NAME Ġ= Ġ" save - agent . k exe " ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* Ġ@ param Ġexecution Id Ċ Ġ*/ Ċ internal Ġfun Ġimage Name ( execution Id : ĠLong ) Ġ= Ġ" save - execution :$ execution Id " Ċ Ċ /** Ċ Ġ* Ġ@ param Ġid Ċ Ġ*/ Ċ internal Ġfun Ġcontainer Name ( id : ĠString ) Ġ= Ġ" save - execution -$ id " Ċ Ċ /** Ċ Ġ* Ġ@ param Ġtest Suite Dto Ċ Ġ*/ Ċ internal Ġfun Ġget Location In Standard Dir For TestSuite ( test Suite Dto : ĠTest Suite Dto ) Ġ= ĊĠĠĠĠĠĠĠ Ġ"$ PREFIX _ FOR _ SU ITES _ LOCATION _ IN _ STANDARD _ MODE ${ test Suite Dto . test Suite Repo Url . hashCode ()} _${ test Suite Dto . test RootPath . hashCode () }" Ċ