示例#1
0
  /**
   * 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;
  }
示例#2
0
  @Override
  public InstanceKey saveToSnapshot(String owner) throws MachineException {
    try {
      final String repository = generateRepository();
      String comment =
          format("Suspended at %1$ta %1$tb %1$td %1$tT %1$tZ %1$tY", System.currentTimeMillis());
      if (owner != null) {
        comment = comment + " by " + owner;
      }
      // !! We SHOULD NOT pause container before commit because all execs will fail
      // to push image to private registry it should be tagged with registry in repo name
      // https://docs.docker.com/reference/api/docker_remote_api_v1.16/#push-an-image-on-the-registry
      docker.commit(container, registry + "/" + repository, null, comment, owner);
      // TODO fix this workaround. Docker image is not visible after commit when using swarm
      Thread.sleep(2000);

      final ProgressLineFormatterImpl progressLineFormatter = new ProgressLineFormatterImpl();
      docker.push(
          repository,
          null,
          registry,
          currentProgressStatus -> {
            try {
              outputConsumer.writeLine(progressLineFormatter.format(currentProgressStatus));
            } catch (IOException ignored) {
            }
          });
      return new DockerInstanceKey(repository, registry);
    } catch (IOException e) {
      throw new MachineException(e);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new MachineException(e.getLocalizedMessage(), e);
    }
  }
示例#3
0
 @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);
   }
 }
示例#4
0
 /**
  * Copies files from specified container.
  *
  * @param sourceMachine source machine
  * @param sourcePath path to file or directory inside specified container
  * @param targetPath path to destination file or directory inside container
  * @param overwrite If "false" then it will be an error if unpacking the given content would cause
  *     an existing directory to be replaced with a non-directory and vice versa.
  * @throws MachineException if any error occurs when files are being copied
  */
 @Override
 public void copy(Instance sourceMachine, String sourcePath, String targetPath, boolean overwrite)
     throws MachineException {
   if (!(sourceMachine instanceof DockerInstance)) {
     throw new MachineException("Unsupported copying between not docker machines");
   }
   try {
     docker.putResource(
         container,
         targetPath,
         docker.getResource(((DockerInstance) sourceMachine).container, sourcePath),
         overwrite);
   } catch (IOException e) {
     throw new MachineException(e.getLocalizedMessage());
   }
 }
示例#5
0
  @Override
  public void destroy() throws MachineException {
    machineProcesses.clear();
    processesCleaner.untrackProcesses(getId());
    dockerInstanceStopDetector.stopDetection(container);
    try {
      if (getConfig().isDev()) {
        node.unbindWorkspace();
      }

      docker.killContainer(container);

      docker.removeContainer(container, true, true);
    } catch (IOException e) {
      throw new MachineException(e.getLocalizedMessage());
    }

    try {
      docker.removeImage(image, false);
    } catch (IOException ignore) {
    }
  }
示例#6
0
 @Override
 public MachineRuntimeInfoImpl getRuntime() {
   if (machineRuntime == null) {
     try {
       final ContainerInfo containerInfo = docker.inspectContainer(container);
       machineRuntime =
           new MachineRuntimeInfoImpl(
               dockerMachineFactory.createMetadata(containerInfo, node.getHost()));
     } catch (IOException e) {
       LOG.error(e.getLocalizedMessage(), e);
       return null;
     }
   }
   return machineRuntime;
 }