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);
}
}
}
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);
}
}
}
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;
}
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);
}
}
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);
}
}
Aggregations