/** * 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; }
@Override public List<InstanceProcess> getProcesses() throws MachineException { List<InstanceProcess> processes = new LinkedList<>(); try { final Exec exec = docker.createExec(container, false, "/bin/bash", "-c", GET_ALIVE_PROCESSES_COMMAND); docker.startExec( exec.getId(), logMessage -> { final String pidFilePath = logMessage.getContent().trim(); final Matcher matcher = PID_FILE_PATH_PATTERN.matcher(pidFilePath); if (matcher.matches()) { final int virtualPid = Integer.parseInt(matcher.group(1)); final InstanceProcess dockerProcess = machineProcesses.get(virtualPid); if (dockerProcess != null) { processes.add(dockerProcess); } else { LOG.warn( "Machine process {} exists in container but missing in processes map", virtualPid); } } }); return processes; } catch (IOException e) { throw new MachineException(e); } }