2017-06-06 13 views
0

kubernetes-clientを使用して、ポッドからディレクトリをコピーしようとしていますが、stdoutの入力ストリームに問題があります。 read()に接続しようとすると、java.io.IOException: Pipe brokenの例外が発生します。データがまったく流れないことは確かです。私は別のスレッドや何かでInputStreamを読む必要がある場合は半分の疑問に思っていますか?kubernetes-client exec()を使ってPipeInputStreamで破損したパイプ

ストリームは次のように作成されます

public InputStream copyFiles(String containerId, 
          String folderName) { 

    ExecWatch exec = client.pods().withName(containerId).redirectingOutput().exec("tar -C " + folderName + " -c"); 

    // We need to wrap the InputStream so that when the stdout is closed, then the underlying ExecWatch is closed 
    // also. This will cleanup any Websockets connections. 
    ChainedCloseInputStreamWrapper inputStreamWrapper = new ChainedCloseInputStreamWrapper(exec.getOutput(), exec); 

    return inputStreamWrapper; 
} 

をし、InputStreamは、この関数内で処理され

void copyVideos(final String containerId) { 
    TarArchiveInputStream tarStream = new TarArchiveInputStream(containerClient.copyFiles(containerId, "/videos/")); 
    TarArchiveEntry entry; 
    boolean videoWasCopied = false; 
    try { 
     while ((entry = tarStream.getNextTarEntry()) != null) { 
      if (entry.isDirectory()) { 
       continue; 
      } 
      String fileExtension = entry.getName().substring(entry.getName().lastIndexOf('.')); 
      testInformation.setFileExtension(fileExtension); 
      File videoFile = new File(testInformation.getVideoFolderPath(), testInformation.getFileName()); 
      File parent = videoFile.getParentFile(); 
      if (!parent.exists()) { 
       parent.mkdirs(); 
      } 
      OutputStream outputStream = new FileOutputStream(videoFile); 
      IOUtils.copy(tarStream, outputStream); 
      outputStream.close(); 
      videoWasCopied = true; 
      LOGGER.log(Level.INFO, "{0} Video file copied to: {1}/{2}", new Object[]{getId(), 
        testInformation.getVideoFolderPath(), testInformation.getFileName()}); 
     } 
    } catch (IOException e) { 
     LOGGER.log(Level.WARNING, getId() + " Error while copying the video", e); 
     ga.trackException(e); 
    } finally { 
     if (!videoWasCopied) { 
      testInformation.setVideoRecorded(false); 
     } 
    } 

} 

のInputStreamラッパークラスは、入力ストリーム一度終わりにExecWatchを閉じるにはただそこにありますこれは次のようになります。

private static class ChainedCloseInputStreamWrapper extends InputStream { 

    private InputStream delegate; 
    private Closeable resourceToClose; 

    public ChainedCloseInputStreamWrapper(InputStream delegate, Closeable resourceToClose) { 
     this.delegate = delegate; 
     this.resourceToClose = resourceToClose; 
    } 

    @Override 
    public int read() throws IOException { 
     return delegate.read(); 
    } 

    public int available() throws IOException { 
     return delegate.available(); 
    } 

    public void close() throws IOException { 
     logger.info("Shutdown called!"); 
     delegate.close(); 

     // Close our dependent resource 
     resourceToClose.close(); 
    } 

    public boolean equals(Object o) { 
     return delegate.equals(o); 
    } 

    public int hashCode() { 
     return delegate.hashCode(); 
    } 

    public int read(byte[] array) throws IOException { 
     return delegate.read(array); 
    } 

    public int read(byte[] array, 
        int n, 
        int n2) throws IOException { 
     return delegate.read(array, n, n2); 
    } 

    public long skip(long n) throws IOException { 
     return delegate.skip(n); 
    } 

    public void mark(int n) { 
     delegate.mark(n); 
    } 

    public void reset() throws IOException { 
     delegate.reset(); 
    } 

    public boolean markSupported() { 
     return delegate.markSupported(); 
    } 

    public String toString() { 
     return delegate.toString(); 
    } 

} 
+0

どのようにしてapiserverに接続しますか?クラスターで走っているトラフ 'kubectl proxy'に接続していますか? –

+0

必要な役割が作成されたサービスアカウントを使用してクラスタ内で実行しています。私はOpenshift 1.4を走らせています。 –

+0

フルソースはhttps://github.com/IPAustralia/zalenium/blob/40b253018b81e2d70b4742fd80a9ed8b19b1dae8/src/main/java/de/zalando/ep/zalenium/container/KubernetesContainerClient.java#L125にあります。私はexecを実行し、うまく動作するoutputstreamに書き込む別の関数を持っています:https://github.com/IPAustralia/zalenium/blob/40b253018b81e2d70b4742fd80a9ed8b19b1dae8/src/main/java/de/zalando/ep/zalenium/container/KubernetesContainerClient .java#L144 –

答えて

0

tarコマンドが間違っていたので、それは失敗を引き起こしていて、stdout PipeInputStreamはデッドロックでした。私はデッドロックの回避策を見つけることができました。しかし、失敗の主な理由は、タールに実際に何かをさせることを忘れてしまったことでした。私は少なくとも "。"が必要でした。現在のディレクトリをインクルードします。

関連する問題