/** * Reads file content by specified file path. * * <p>TODO: add file size checking, note that size checking and file content reading should be * done in an atomic way, which means that two separate instance processes is not the case. * * @param filePath path to file on machine instance * @param startFrom line number to start reading from * @param limit limitation on line * @return if {@code limit} and {@code startFrom} grater than 0 content from {@code startFrom} to * {@code startFrom + limit} will be returned, if file contains less lines than {@code * startFrom} empty content will be returned * @throws MachineException if any error occurs with file reading */ @Override public String readFileContent(String filePath, int startFrom, int limit) throws MachineException { if (limit <= 0 || startFrom <= 0) { throw new MachineException( "Impossible to read file " + limit + " lines from " + startFrom + " line"); } // command sed getting file content from startFrom line to (startFrom + limit) String bashCommand = format("sed -n \'%1$2s, %2$2sp\' %3$2s", startFrom, startFrom + limit, filePath); final String[] command = {"/bin/bash", "-c", bashCommand}; ListLineConsumer lines = new ListLineConsumer(); try { Exec exec = docker.createExec(container, false, command); docker.startExec(exec.getId(), new LogMessagePrinter(lines, LogMessage::getContent)); } catch (IOException e) { throw new MachineException( format( "Error occurs while initializing command %s in docker container %s: %s", Arrays.toString(command), container, e.getLocalizedMessage()), e); } String content = lines.getText(); if (content.contains("sed: can't read " + filePath + ": No such file or directory") || content.contains("cat: " + filePath + ": No such file or directory")) { throw new MachineException("File with path " + filePath + " not found"); } return content; }
private String execAndGetOutput(String command) throws JSchException, MachineException, IOException { ChannelExec exec = (ChannelExec) session.openChannel("exec"); exec.setCommand(command); try (BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream())); InputStream erStream = exec.getErrStream()) { exec.connect(connectionTimeout); ListLineConsumer listLineConsumer = new ListLineConsumer(); String line; while ((line = reader.readLine()) != null) { listLineConsumer.writeLine(line); } // read stream to wait until command finishes its work IoUtil.readStream(erStream); if (exec.getExitStatus() != 0) { throw new MachineException( format( "Error code: %s. Error: %s", exec.getExitStatus(), IoUtil.readAndCloseQuietly(exec.getErrStream()))); } return listLineConsumer.getText(); } finally { exec.disconnect(); } }