30
30
import java .io .OutputStream ;
31
31
import java .nio .file .Path ;
32
32
import java .nio .file .Paths ;
33
+ import java .util .concurrent .ExecutionException ;
34
+ import java .util .concurrent .Future ;
35
+ import java .util .concurrent .TimeUnit ;
33
36
import org .apache .commons .codec .binary .Base64InputStream ;
34
37
import org .apache .commons .codec .binary .Base64OutputStream ;
35
38
import org .apache .commons .compress .archivers .ArchiveEntry ;
@@ -153,6 +156,21 @@ public void copyDirectoryFromPod(
153
156
createDirectoryStructureFromTree (tree , namespace , pod , container , srcPath , destination );
154
157
return ;
155
158
}
159
+ Future <Integer > future =
160
+ copyDirectoryFromPodAsync (namespace , pod , container , srcPath , destination );
161
+ try {
162
+ int code = future .get ().intValue ();
163
+ if (code != 0 ) {
164
+ throw new IOException ("Copy failed (" + code + ")" );
165
+ }
166
+ } catch (InterruptedException | ExecutionException ex ) {
167
+ throw new IOException (ex );
168
+ }
169
+ }
170
+
171
+ public Future <Integer > copyDirectoryFromPodAsync (
172
+ String namespace , String pod , String container , String srcPath , Path destination )
173
+ throws IOException , ApiException {
156
174
final Process proc =
157
175
this .exec (
158
176
namespace ,
@@ -187,14 +205,7 @@ public void copyDirectoryFromPod(
187
205
}
188
206
}
189
207
}
190
- try {
191
- int status = proc .waitFor ();
192
- if (status != 0 ) {
193
- throw new IOException ("Copy command failed with status " + status );
194
- }
195
- } catch (InterruptedException ex ) {
196
- throw new IOException (ex );
197
- }
208
+ return new ProcessFuture (proc );
198
209
}
199
210
200
211
// This creates directories and files using tree of files and directories under container
@@ -330,6 +341,19 @@ public void copyFileToPod(
330
341
String namespace , String pod , String container , Path srcPath , Path destPath )
331
342
throws ApiException , IOException {
332
343
344
+ try {
345
+ int exit = copyFileToPodAsync (namespace , pod , container , srcPath , destPath ).get ();
346
+ if (exit != 0 ) {
347
+ throw new IOException ("Failed to copy: " + exit );
348
+ }
349
+ } catch (InterruptedException | ExecutionException ex ) {
350
+ throw new IOException (ex );
351
+ }
352
+ }
353
+
354
+ public Future <Integer > copyFileToPodAsync (
355
+ String namespace , String pod , String container , Path srcPath , Path destPath )
356
+ throws ApiException , IOException {
333
357
// Run decoding and extracting processes
334
358
final Process proc = execCopyToPod (namespace , pod , container , destPath );
335
359
@@ -344,15 +368,27 @@ public void copyFileToPod(
344
368
archiveOutputStream .putArchiveEntry (tarEntry );
345
369
ByteStreams .copy (input , archiveOutputStream );
346
370
archiveOutputStream .closeArchiveEntry ();
347
- } finally {
348
- proc . destroy ( );
371
+
372
+ return new ProcessFuture ( proc );
349
373
}
350
374
}
351
375
352
376
public void copyFileToPod (
353
377
String namespace , String pod , String container , byte [] src , Path destPath )
354
378
throws ApiException , IOException {
379
+ try {
380
+ int exit = copyFileToPodAsync (namespace , pod , container , src , destPath ).get ();
381
+ if (exit != 0 ) {
382
+ throw new IOException ("Copy failed: " + exit );
383
+ }
384
+ } catch (InterruptedException | ExecutionException ex ) {
385
+ throw new IOException (ex );
386
+ }
387
+ }
355
388
389
+ public Future <Integer > copyFileToPodAsync (
390
+ String namespace , String pod , String container , byte [] src , Path destPath )
391
+ throws ApiException , IOException {
356
392
// Run decoding and extracting processes
357
393
final Process proc = execCopyToPod (namespace , pod , container , destPath );
358
394
@@ -365,8 +401,8 @@ public void copyFileToPod(
365
401
archiveOutputStream .putArchiveEntry (tarEntry );
366
402
ByteStreams .copy (new ByteArrayInputStream (src ), archiveOutputStream );
367
403
archiveOutputStream .closeArchiveEntry ();
368
- } finally {
369
- proc . destroy ( );
404
+
405
+ return new ProcessFuture ( proc );
370
406
}
371
407
}
372
408
@@ -397,4 +433,37 @@ private boolean isTarPresentInContainer(String namespace, String pod, String con
397
433
proc .destroy ();
398
434
}
399
435
}
436
+
437
+ private static class ProcessFuture implements Future <Integer > {
438
+ private Process proc ;
439
+
440
+ ProcessFuture (Process proc ) {
441
+ this .proc = proc ;
442
+ }
443
+
444
+ // TODO: support cancelling?
445
+ public boolean cancel (boolean interupt ) {
446
+ return false ;
447
+ }
448
+
449
+ public boolean isCancelled () {
450
+ return false ;
451
+ }
452
+
453
+ public Integer get () throws InterruptedException {
454
+ proc .waitFor ();
455
+ proc .destroy ();
456
+ return proc .exitValue ();
457
+ }
458
+
459
+ public Integer get (long timeout , TimeUnit unit ) throws InterruptedException {
460
+ proc .waitFor (timeout , unit );
461
+ proc .destroy ();
462
+ return proc .exitValue ();
463
+ }
464
+
465
+ public boolean isDone () {
466
+ return proc .isAlive ();
467
+ }
468
+ }
400
469
}
0 commit comments