/** Ċ Copyright Ġ 2 0 1 9 ĠBar D ĠSoftware Ġs . r . o Ċ Ċ Licensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ you Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ You Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ċ http :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Unless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ distributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ WITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ See Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ limitations Ġunder Ġthe ĠLicense . Ċ */ Ċ package Ġcom . b ard software . p ape eria . backend Ċ Ċ import Ġcom . spotify . docker . client . Default Docker Client Ċ import Ġcom . spotify . docker . client . Docker Client Ċ import Ġcom . spotify . docker . client . messages . Container Config Ċ import Ġcom . spotify . docker . client . messages . Host Config Ċ import Ġcom . xen om ach ina . arg parser . Arg Parser Ċ import Ġcom . xen om ach ina . arg parser . default Ċ import Ġkotlinx . coroutines . Global Scope Ċ import Ġkotlinx . coroutines . channels . Channel Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlinx . coroutines . new Single Thread Context Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġjava . math . BigDecimal Ċ import Ġjava . nio . file . Path Ċ import Ġjava . util . concurrent . Executors Ċ Ċ private Ġval ĠN AN O Ġ= Ġ 1 0 0 0 0 0 0 0 0 0 L Ċ Ċ data Ġclass ĠDocker Task ( val Ġworkspace Root : ĠPath , Ġval Ġdocker Cmd Args : ĠList < String >) Ċ /** Ċ Ġ* Ġ@ author Ġd bar as he v @ b ard software . com Ċ Ġ*/ Ċ class ĠDocker Stage ( val Ġargs : ĠDocker Stage Args ) Ġ{ ĊĠ Ġprivate Ġval Ġlogs Executor Ġ= ĠExec utors . new Single Thread Executor () ĊĠ Ġprivate Ġval Ġdocker Context Ġ= Ġnew Single Thread Context (" Docker Thread ") ĊĠ Ġprivate Ġval Ġdocker Ġ= ĠgetDefault Docker Client () ĊĊĠ Ġsuspend Ġfun Ġprocess ( ĊĠĠĠĠĠ Ġtask : ĠDocker Task , Ġexit Code Channel : ĠChannel < Long >, ĊĠĠĠĠĠ Ġout : ĠBase Output , ĊĠĠĠĠĠ Ġconfig Code : Ġ( host Config : ĠHost Config . Builder , Ġcontainer Config : ĠContainer Config . Builder ) Ġ-> ĠUnit Ġ= Ġ{ Ġ_, Ġ_ Ġ-> Ġ}) Ġ{ ĊĠĠĠ ĠLOG . info (" Running Ġdocker Ġtask Ġ{}", Ġtask ) ĊĊĠĠĠ Ġval Ġhost Config Builder Ġ= ĠHost Config . builder () ĊĠĠĠĠĠĠĠ Ġ. append Bind s ("${ task . workspace Root . to AbsolutePath ()} :/ workspace ") ĊĠĠĠĠĠĠĠ Ġ. nano C pus ( args . docker Cpu . to BigDecimal () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. multiply ( BigDecimal . valueOf ( NAN O )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. to Long ()) ĊĠĠĠĠĠĠĠ Ġ. memory ( args . docker Mem . to Long () Ġ* Ġ( 1 Ġshl Ġ 2 0 )) ĊĊĠĠĠ Ġval Ġcontainer Config Builder Ġ= ĠContainer Config . builder () ĊĠĠĠĠĠĠĠ Ġ. image ( args . docker Image ) ĊĠĠĠĠĠĠĠ Ġ. working Dir ("/ workspace ") ĊĠĠĠĠĠĠĠ Ġ. cmd ( task . docker Cmd Args ) ĊĠĠĠ Ġconfig Code ( host Config Builder , Ġcontainer Config Builder ) ĊĠĠĠ Ġval Ġhost Config Ġ= Ġhost Config Builder . build () ĊĠĠĠ Ġval Ġcontainer Config Ġ= Ġcontainer Config Builder . host Config ( host Config ). build () ĊĊĠĠĠ ĠGlobal Scope . launch ( docker Context ) Ġ{ ĊĠĠĠĠĠ Ġvar Ġcontainer Id : ĠString ? Ġ= Ġnull ĊĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ ĠLOG . info (" Creating Ġcontainer : Ġ$ container Config ") ĊĠĠĠĠĠĠĠ Ġval Ġcreation Ġ= Ġthis @ Docker Stage . docker . create Container ( container Config ) ĊĠĠĠĠĠĠĠ Ġcontainer Id Ġ= Ġcreation . id () ĊĠĠĠĠĠĠĠ ĠLOG . debug (" Container Ġid =$ container Id ") ĊĠĠĠĠĠĠĠ Ġattach Output ( container Id !! , Ġout ) ĊĠĠĠĠĠĠĠ Ġthis @ Docker Stage . docker . start Container ( container Id ) ĊĠĠĠĠĠĠĠ Ġval Ġexit Code Ġ= Ġthis @ Docker Stage . docker . wait Container ( container Id ) ĊĠĠĠĠĠĠĠ ĠLOG . debug (" Exit Ġcode Ġ=$ exit Code ") ĊĠĠĠĠĠĠĠ Ġout . close () ĊĠĠĠĠĠĠĠ Ġexit Code Channel . send ( exit Code . statusCode ()) ĊĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLOG . error (" Docker Stage Ġfailed ", Ġe ) ĊĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠ Ġcontainer Id ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġout . close () ĊĠĠĠĠĠĠĠĠĠ Ġthis @ Docker Stage . docker . stop Container ( it , Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠ Ġthis @ Docker Stage . docker . remove Container ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġattach Output ( container Id : ĠString , Ġout : ĠBase Output ) Ġ{ ĊĠĠĠ Ġlogs Executor . submit Ġ{ ĊĠĠĠĠĠ Ġdocker . attach Container ( container Id , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDocker Client . Attach Parameter . LOG S , ĠDocker Client . Attach Parameter . STDOUT , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDocker Client . Attach Parameter . STD ERR , ĠDocker Client . Attach Parameter . STREAM ) ĊĠĠĠĠĠĠĠĠĠ Ġ. attach ( out . stdout Pipe , Ġout . stderr Pipe ) ĊĠĠĠĠĠ Ġout . attach () ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ class ĠDocker Stage Args ( parser : ĠArg Parser ) Ġ{ ĊĠ Ġval Ġdocker Image Ġby Ġparser . st oring ("-- docker - image ", Ġhelp Ġ= Ġ" Docker Ġimage Ġto Ġrun "). default Ġ{ Ġ"" Ġ} ĊĠ Ġval Ġdocker Cpu Ġby Ġparser . st oring ("-- docker - cpus ", Ġhelp Ġ= Ġ" Container ĠCPU Ġlimit "). default Ġ{ Ġ" 1 . 0 " Ġ} ĊĠ Ġval Ġdocker Mem Ġby Ġparser . st oring ("-- docker - mem ", Ġhelp Ġ= Ġ" Container Ġmemory Ġlimit Ġin Ġmeg aby tes "). default Ġ{ Ġ" 6 4 " Ġ} Ċ } Ċ Ċ fun ĠgetDefault Docker Client (): ĠDefault Docker Client Ġ{ ĊĠ Ġreturn ĠDefault Docker Client . from Env (). build () Ċ } Ċ Ċ private Ġval ĠLOG Ġ= ĠLoggerFactory . getLogger (" base . docker ") Ċ