@@ -169,6 +169,90 @@ buildscript {
169
169
}
170
170
}
171
171
172
+ private static int freePort (String minioAddress ) {
173
+ int minioPort
174
+ ServerSocket serverSocket = new ServerSocket (0 , 1 , InetAddress . getByName(minioAddress))
175
+ try {
176
+ minioPort = serverSocket. localPort
177
+ } finally {
178
+ serverSocket. close()
179
+ }
180
+ if (minioPort == 0 ) {
181
+ throw new GradleException (" Could not find a free port for Minio" )
182
+ }
183
+ return minioPort
184
+ }
185
+
186
+ private int getMinioPid (Process minioProcess ) {
187
+ int minioPid
188
+ if (JavaVersion . current() <= JavaVersion . VERSION_1_8 ) {
189
+ try {
190
+ Class<?> cProcessImpl = minioProcess. getClass()
191
+ Field fPid = cProcessImpl. getDeclaredField(" pid" )
192
+ if (! fPid. isAccessible()) {
193
+ fPid. setAccessible(true )
194
+ }
195
+ minioPid = fPid. getInt(minioProcess)
196
+ } catch (Exception e) {
197
+ logger. error(" failed to read pid from minio process" , e)
198
+ minioProcess. destroyForcibly()
199
+ throw e
200
+ }
201
+ } else {
202
+ minioPid = minioProcess. pid()
203
+ }
204
+ return minioPid
205
+ }
206
+
207
+ private static Process setupMinio (String minioAddress , int minioPort , String minioDataDir , String accessKey , String secretKey ,
208
+ String minioBinDir , String minioFileName ) {
209
+ // we skip these tests on Windows so we do no need to worry about compatibility here
210
+ final ProcessBuilder minio = new ProcessBuilder (
211
+ " ${ minioBinDir} /${ minioFileName} " ,
212
+ " server" ,
213
+ " --address" ,
214
+ minioAddress + " :" + minioPort,
215
+ minioDataDir)
216
+ minio. environment(). put(' MINIO_ACCESS_KEY' , accessKey)
217
+ minio. environment(). put(' MINIO_SECRET_KEY' , secretKey)
218
+ return minio. start()
219
+ }
220
+
221
+ private void addShutdownHook (Process minioProcess , int minioPort , int minioPid ) {
222
+ new BufferedReader (new InputStreamReader (minioProcess. inputStream)). withReader { br ->
223
+ String line
224
+ int httpPort = 0
225
+ while ((line = br. readLine()) != null ) {
226
+ logger. info(line)
227
+ if (line. matches(' .*Endpoint.*:\\ d+$' )) {
228
+ assert httpPort == 0
229
+ final int index = line. lastIndexOf(" :" )
230
+ assert index >= 0
231
+ httpPort = Integer . parseInt(line. substring(index + 1 ))
232
+ if (httpPort != minioPort) {
233
+ throw new IllegalStateException (" Port mismatch, expected ${ minioPort} but was ${ httpPort} " )
234
+ }
235
+
236
+ final File script = new File (project. buildDir, " minio/minio.killer.sh" )
237
+ script. setText(
238
+ [" function shutdown {" ,
239
+ " kill ${ minioPid} " ,
240
+ " }" ,
241
+ " trap shutdown EXIT" ,
242
+ // will wait indefinitely for input, but we never pass input, and the pipe is only closed when the build dies
243
+ " read line\n " ]. join(' \n ' ), ' UTF-8' )
244
+ final ProcessBuilder killer = new ProcessBuilder (" bash" , script. absolutePath)
245
+ killer. start()
246
+ break
247
+ }
248
+ }
249
+
250
+ if (httpPort <= 0 ) {
251
+ throw new IllegalStateException (" httpPort must be > 0" )
252
+ }
253
+ }
254
+ }
255
+
172
256
if (useFixture && minioDistribution) {
173
257
apply plugin : ' de.undercouch.download'
174
258
@@ -201,72 +285,28 @@ if (useFixture && minioDistribution) {
201
285
ext. minioPort = 0
202
286
203
287
doLast {
204
- // get free port
205
- ServerSocket serverSocket = new ServerSocket (0 , 1 , InetAddress . getByName(minioAddress))
206
- try {
207
- minioPort = serverSocket. localPort
208
- } finally {
209
- serverSocket. close()
210
- }
211
- if (minioPort == 0 ) {
212
- throw new GradleException (" Could not find a free port for Minio" )
213
- }
214
-
215
288
new File (" ${ minioDataDir} /${ s3PermanentBucket} " ). mkdirs()
216
- // we skip these tests on Windows so we do no need to worry about compatibility here
217
- final ProcessBuilder minio = new ProcessBuilder (
218
- " ${ minioBinDir} /${ minioFileName} " ,
219
- " server" ,
220
- " --address" ,
221
- minioAddress + " :" + minioPort,
222
- minioDataDir)
223
- minio. environment(). put(' MINIO_ACCESS_KEY' , s3PermanentAccessKey)
224
- minio. environment(). put(' MINIO_SECRET_KEY' , s3PermanentSecretKey)
225
- final Process process = minio. start()
226
- if (JavaVersion . current() <= JavaVersion . VERSION_1_8 ) {
289
+
290
+ Exception accumulatedException = null
291
+ for (int i = 0 ; i < 5 ; ++ i) {
227
292
try {
228
- Class<?> cProcessImpl = process . getClass( )
229
- Field fPid = cProcessImpl . getDeclaredField( " pid " )
230
- if ( ! fPid . isAccessible()) {
231
- fPid . setAccessible( true )
232
- }
233
- minioPid = fPid . getInt(process)
293
+ minioPort = freePort(minioAddress )
294
+ final Process process =
295
+ setupMinio(minioAddress, minioPort, minioDataDir, s3PermanentAccessKey, s3PermanentSecretKey, minioBinDir, minioFileName)
296
+ minioPid = getMinioPid(process )
297
+ addShutdownHook(process, minioPort, minioPid)
298
+ break
234
299
} catch (Exception e) {
235
- logger. error(" failed to read pid from minio process" , e)
236
- process. destroyForcibly()
237
- throw e
238
- }
239
- } else {
240
- minioPid = process. pid()
241
- }
242
-
243
- new BufferedReader (new InputStreamReader (process. getInputStream())). withReader { br ->
244
- String line
245
- int httpPort = 0
246
- while ((line = br. readLine()) != null ) {
247
- logger. info(line)
248
- if (line. matches(' .*Endpoint.*:\\ d+$' )) {
249
- assert httpPort == 0
250
- final int index = line. lastIndexOf(" :" )
251
- assert index >= 0
252
- httpPort = Integer . parseInt(line. substring(index + 1 ))
253
- assert httpPort == minioPort : " Port mismatch, expected ${ minioPort} but was ${ httpPort} "
254
-
255
- final File script = new File (project. buildDir, " minio/minio.killer.sh" )
256
- script. setText(
257
- [" function shutdown {" ,
258
- " kill ${ minioPid} " ,
259
- " }" ,
260
- " trap shutdown EXIT" ,
261
- // will wait indefinitely for input, but we never pass input, and the pipe is only closed when the build dies
262
- " read line\n " ]. join(' \n ' ), ' UTF-8' )
263
- final ProcessBuilder killer = new ProcessBuilder (" bash" , script. absolutePath)
264
- killer. start()
265
- break
300
+ logger. error(" Exception while trying to start Minio {}" , e)
301
+ if (accumulatedException == null ) {
302
+ accumulated = e
303
+ } else {
304
+ accumulatedException. addSuppressed(e)
266
305
}
267
306
}
268
-
269
- assert httpPort > 0
307
+ }
308
+ if (accumulatedException != null ) {
309
+ throw new GradleException (" Failed to start Minio" , accumulatedException)
270
310
}
271
311
}
272
312
}
0 commit comments