1414
1515import com .google .common .io .ByteStreams ;
1616import io .kubernetes .client .models .V1Pod ;
17- import java .io .ByteArrayInputStream ;
18- import java .io .ByteArrayOutputStream ;
17+ import java .io .BufferedInputStream ;
18+ import java .io .File ;
1919import java .io .FileOutputStream ;
2020import java .io .IOException ;
2121import java .io .InputStream ;
22+ import java .io .OutputStream ;
2223import java .nio .file .Path ;
23- import org .apache .commons .codec .binary .Base64 ;
24+ import org .apache .commons .codec .binary .Base64InputStream ;
25+ import org .apache .commons .compress .archivers .ArchiveEntry ;
26+ import org .apache .commons .compress .archivers .ArchiveInputStream ;
27+ import org .apache .commons .compress .archivers .tar .TarArchiveInputStream ;
2428import org .slf4j .Logger ;
2529import org .slf4j .LoggerFactory ;
2630
@@ -41,22 +45,22 @@ public Copy(ApiClient apiClient) {
4145 super (apiClient );
4246 }
4347
44- public InputStream copyFile (String namespace , String pod , String srcPath )
48+ public InputStream copyFileFromPod (String namespace , String pod , String srcPath )
4549 throws ApiException , IOException {
46- return copyFile (namespace , pod , null , srcPath );
50+ return copyFileFromPod (namespace , pod , null , srcPath );
4751 }
4852
49- public InputStream copyFile (V1Pod pod , String srcPath ) throws ApiException , IOException {
50- return copyFile (pod , null , srcPath );
53+ public InputStream copyFileFromPod (V1Pod pod , String srcPath ) throws ApiException , IOException {
54+ return copyFileFromPod (pod , null , srcPath );
5155 }
5256
53- public InputStream copyFile (V1Pod pod , String container , String srcPath )
57+ public InputStream copyFileFromPod (V1Pod pod , String container , String srcPath )
5458 throws ApiException , IOException {
55- return copyFile (
59+ return copyFileFromPod (
5660 pod .getMetadata ().getNamespace (), pod .getMetadata ().getName (), container , srcPath );
5761 }
5862
59- public InputStream copyFile (String namespace , String pod , String container , String srcPath )
63+ public InputStream copyFileFromPod (String namespace , String pod , String container , String srcPath )
6064 throws ApiException , IOException {
6165 Process proc =
6266 this .exec (
@@ -66,21 +70,85 @@ public InputStream copyFile(String namespace, String pod, String container, Stri
6670 container ,
6771 false ,
6872 false );
69- try {
70- proc .waitFor ();
71- } catch (InterruptedException ex ) {
72- log .warn ("Interrupted waiting for copy to complete" , ex );
73+ return new Base64InputStream (proc .getInputStream ());
74+ }
75+
76+ public void copyFileFromPod (
77+ String namespace , String name , String container , String srcPath , Path destination )
78+ throws ApiException , IOException {
79+ try (InputStream is = copyFileFromPod (namespace , name , srcPath );
80+ FileOutputStream fos = new FileOutputStream (destination .toFile ())) {
81+ ByteStreams .copy (is , fos );
82+ fos .flush ();
7383 }
74- ByteArrayOutputStream bos = new ByteArrayOutputStream ();
75- ByteStreams .copy (proc .getInputStream (), bos );
84+ }
7685
77- return new ByteArrayInputStream (Base64 .decodeBase64 (bos .toByteArray ()));
86+ public void copyDirectoryFromPod (V1Pod pod , String srcPath , Path destination )
87+ throws ApiException , IOException {
88+ copyDirectoryFromPod (pod , null , srcPath , destination );
89+ }
90+
91+ public void copyDirectoryFromPod (V1Pod pod , String container , String srcPath , Path destination )
92+ throws ApiException , IOException {
93+ copyDirectoryFromPod (
94+ pod .getMetadata ().getNamespace (),
95+ pod .getMetadata ().getName (),
96+ container ,
97+ srcPath ,
98+ destination );
99+ }
100+
101+ public void copyDirectoryFromPod (String namespace , String pod , String srcPath , Path destination )
102+ throws ApiException , IOException {
103+ copyDirectoryFromPod (namespace , pod , null , srcPath , destination );
104+ }
105+
106+ public void copyDirectoryFromPod (
107+ String namespace , String pod , String container , String srcPath , Path destination )
108+ throws ApiException , IOException {
109+ // TODO: Test that 'tar' is present in the container?
110+ final Process proc =
111+ this .exec (
112+ namespace ,
113+ pod ,
114+ new String [] {"sh" , "-c" , "tar cf - " + srcPath + " | base64" },
115+ container ,
116+ false ,
117+ false );
118+ InputStream is = new Base64InputStream (new BufferedInputStream (proc .getInputStream ()));
119+ try (ArchiveInputStream archive =
120+ new TarArchiveInputStream (is )) { // new GzipCompressorInputStream(is))) {
121+ for (ArchiveEntry entry = archive .getNextEntry ();
122+ entry != null ;
123+ entry = archive .getNextEntry ()) {
124+ if (!archive .canReadEntryData (entry )) {
125+ log .error ("Can't read: " + entry );
126+ continue ;
127+ }
128+ File f = new File (destination .toFile (), entry .getName ());
129+ if (entry .isDirectory ()) {
130+ if (!f .isDirectory () && !f .mkdirs ()) {
131+ throw new IOException ("create directory failed: " + f );
132+ }
133+ } else {
134+ File parent = f .getParentFile ();
135+ if (!parent .isDirectory () && !parent .mkdirs ()) {
136+ throw new IOException ("create directory failed: " + parent );
137+ }
138+ try (OutputStream fs = new FileOutputStream (f )) {
139+ System .out .println ("Writing: " + f .getCanonicalPath ());
140+ ByteStreams .copy (archive , fs );
141+ fs .flush ();
142+ }
143+ }
144+ }
145+ }
78146 }
79147
80- public static void copyFile (String namespace , String pod , String srcPath , Path dest )
148+ public static void copyFileFromPod (String namespace , String pod , String srcPath , Path dest )
81149 throws ApiException , IOException {
82150 Copy c = new Copy ();
83- InputStream is = c .copyFile (namespace , pod , null , srcPath );
151+ InputStream is = c .copyFileFromPod (namespace , pod , null , srcPath );
84152 FileOutputStream os = new FileOutputStream (dest .toFile ());
85153 ByteStreams .copy (is , os );
86154 os .flush ();
0 commit comments