Search in sources :

Example 26 with MachineException

use of org.eclipse.che.api.machine.server.exception.MachineException in project che by eclipse.

the class DockerProcess method start.

@Override
public void start(LineConsumer output) throws ConflictException, MachineException {
    if (started) {
        throw new ConflictException("Process already started.");
    }
    started = true;
    // Trap is invoked when bash session ends. Here we kill all sub-processes of shell and remove pid-file.
    final String trap = format("trap '[ -z \"$(jobs -p)\" ] || kill $(jobs -p); [ -e %1$s ] && rm %1$s' EXIT", pidFilePath);
    // 'echo' saves shell pid in file, then run command
    final String shellCommand = trap + "; echo $$>" + pidFilePath + "; " + commandLine;
    final String[] command = { shellInvoker, "-c", shellCommand };
    Exec exec;
    try {
        exec = docker.createExec(CreateExecParams.create(container, command).withDetach(output == null));
    } catch (IOException e) {
        throw new MachineException(format("Error occurs while initializing command %s in docker container %s: %s", Arrays.toString(command), container, e.getMessage()), e);
    }
    try {
        docker.startExec(StartExecParams.create(exec.getId()), output == null ? null : new LogMessagePrinter(output));
    } catch (IOException e) {
        if (output != null && e instanceof SocketTimeoutException) {
            throw new MachineException(getErrorMessage());
        } else {
            throw new MachineException(format("Error occurs while executing command %s: %s", Arrays.toString(exec.getCommand()), e.getMessage()), e);
        }
    }
}
Also used : Exec(org.eclipse.che.plugin.docker.client.Exec) SocketTimeoutException(java.net.SocketTimeoutException) ConflictException(org.eclipse.che.api.core.ConflictException) MachineException(org.eclipse.che.api.machine.server.exception.MachineException) IOException(java.io.IOException)

Example 27 with MachineException

use of org.eclipse.che.api.machine.server.exception.MachineException in project che by eclipse.

the class DockerProcess method kill.

@Override
public void kill() throws MachineException {
    if (started) {
        // Read pid from file and run 'kill [pid]' command.
        final String killCmd = format("[ -r %1$s ] && kill $(cat %1$s)", pidFilePath);
        final String[] command = { "/bin/sh", "-c", killCmd };
        Exec exec;
        try {
            exec = docker.createExec(CreateExecParams.create(container, command).withDetach(true));
        } catch (IOException e) {
            throw new MachineException(format("Error occurs while initializing command %s in docker container %s: %s", Arrays.toString(command), container, e.getMessage()), e);
        }
        try {
            docker.startExec(StartExecParams.create(exec.getId()), MessageProcessor.DEV_NULL);
        } catch (IOException e) {
            throw new MachineException(format("Error occurs while executing command %s in docker container %s: %s", Arrays.toString(exec.getCommand()), container, e.getMessage()), e);
        }
    }
}
Also used : Exec(org.eclipse.che.plugin.docker.client.Exec) MachineException(org.eclipse.che.api.machine.server.exception.MachineException) IOException(java.io.IOException)

Example 28 with MachineException

use of org.eclipse.che.api.machine.server.exception.MachineException in project che by eclipse.

the class DockerInstance method readFileContent.

/**
     * Reads file content by specified file path.
     *
     * 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 shCommand = format("sed -n \'%1$2s, %2$2sp\' %3$2s", startFrom, startFrom + limit, filePath);
    final String[] command = { "/bin/sh", "-c", shCommand };
    ListLineConsumer lines = new ListLineConsumer();
    try {
        Exec exec = docker.createExec(CreateExecParams.create(container, command).withDetach(false));
        docker.startExec(StartExecParams.create(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;
}
Also used : ListLineConsumer(org.eclipse.che.api.core.util.ListLineConsumer) Exec(org.eclipse.che.plugin.docker.client.Exec) MachineException(org.eclipse.che.api.machine.server.exception.MachineException) IOException(java.io.IOException)

Example 29 with MachineException

use of org.eclipse.che.api.machine.server.exception.MachineException in project che by eclipse.

the class DockerInstance method getProcesses.

@Override
public List<InstanceProcess> getProcesses() throws MachineException {
    List<InstanceProcess> processes = new LinkedList<>();
    try {
        final Exec exec = docker.createExec(CreateExecParams.create(container, new String[] { "/bin/sh", "-c", GET_ALIVE_PROCESSES_COMMAND }).withDetach(false));
        docker.startExec(StartExecParams.create(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);
    }
}
Also used : Exec(org.eclipse.che.plugin.docker.client.Exec) Matcher(java.util.regex.Matcher) MachineException(org.eclipse.che.api.machine.server.exception.MachineException) InstanceProcess(org.eclipse.che.api.machine.server.spi.InstanceProcess) IOException(java.io.IOException) LinkedList(java.util.LinkedList)

Example 30 with MachineException

use of org.eclipse.che.api.machine.server.exception.MachineException in project che by eclipse.

the class DockerInstanceProvider method removeInstanceSnapshot.

/**
     * Removes snapshot of the instance in implementation specific way.
     *
     * @param machineSource
     *         contains implementation specific key of the snapshot of the instance that should be removed
     * @throws SnapshotException
     *         if exception occurs on instance snapshot removal
     */
@Override
public void removeInstanceSnapshot(final MachineSource machineSource) throws SnapshotException {
    // use registry API directly because docker doesn't have such API yet
    // https://github.com/docker/docker-registry/issues/45
    final DockerMachineSource dockerMachineSource;
    try {
        dockerMachineSource = new DockerMachineSource(machineSource);
    } catch (MachineException e) {
        throw new SnapshotException(e);
    }
    if (!snapshotUseRegistry) {
        try {
            docker.removeImage(RemoveImageParams.create(dockerMachineSource.getLocation(false)));
        } catch (IOException ignore) {
        }
        return;
    }
    final String registry = dockerMachineSource.getRegistry();
    final String repository = dockerMachineSource.getRepository();
    if (registry == null || repository == null) {
        LOG.error("Failed to remove instance snapshot: invalid machine source: {}", dockerMachineSource);
        throw new SnapshotException("Snapshot removing failed. Snapshot attributes are not valid");
    }
    try {
        URL url = // TODO make possible to use https here
        UriBuilder.fromUri("http://" + registry).path("/v2/{repository}/manifests/{digest}").build(repository, dockerMachineSource.getDigest()).toURL();
        final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        try {
            conn.setConnectTimeout(30 * 1000);
            conn.setRequestMethod("DELETE");
            // TODO add auth header for secured registry
            // conn.setRequestProperty("Authorization", authHeader);
            final int responseCode = conn.getResponseCode();
            if ((responseCode / 100) != 2) {
                InputStream in = conn.getErrorStream();
                if (in == null) {
                    in = conn.getInputStream();
                }
                LOG.error("An error occurred while deleting snapshot with url: {}\nError stream: {}", url, IoUtil.readAndCloseQuietly(in));
                throw new SnapshotException("Internal server error occurs. Can't remove snapshot");
            }
        } finally {
            conn.disconnect();
        }
    } catch (IOException e) {
        LOG.error(e.getLocalizedMessage(), e);
    }
}
Also used : HttpURLConnection(java.net.HttpURLConnection) InputStream(java.io.InputStream) MachineException(org.eclipse.che.api.machine.server.exception.MachineException) IOException(java.io.IOException) SnapshotException(org.eclipse.che.api.machine.server.exception.SnapshotException) URL(java.net.URL)

Aggregations

MachineException (org.eclipse.che.api.machine.server.exception.MachineException)35 IOException (java.io.IOException)17 ListLineConsumer (org.eclipse.che.api.core.util.ListLineConsumer)7 ConflictException (org.eclipse.che.api.core.ConflictException)6 ServerException (org.eclipse.che.api.core.ServerException)6 InstanceProcess (org.eclipse.che.api.machine.server.spi.InstanceProcess)6 JSchException (com.jcraft.jsch.JSchException)5 File (java.io.File)5 LineConsumer (org.eclipse.che.api.core.util.LineConsumer)5 Instance (org.eclipse.che.api.machine.server.spi.Instance)5 Test (org.testng.annotations.Test)5 Agent (org.eclipse.che.api.agent.shared.model.Agent)4 Command (org.eclipse.che.api.core.model.machine.Command)4 CommandImpl (org.eclipse.che.api.machine.server.model.impl.CommandImpl)4 Exec (org.eclipse.che.plugin.docker.client.Exec)4 URL (java.net.URL)3 NotFoundException (org.eclipse.che.api.core.NotFoundException)3 AbstractLineConsumer (org.eclipse.che.api.core.util.AbstractLineConsumer)3 ChannelExec (com.jcraft.jsch.ChannelExec)2 ChannelSftp (com.jcraft.jsch.ChannelSftp)2