use of io.cdap.cdap.runtime.spi.ssh.SSHProcess in project cdap by caskdata.
the class DefaultSSHSession method executeAndWait.
@Override
public String executeAndWait(List<String> commands) throws IOException {
SSHProcess process = execute(commands);
// Reading will be blocked until the process finished
String out = CharStreams.toString(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
String err = CharStreams.toString(new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8));
// Await uninterruptedly
boolean interrupted = false;
try {
while (true) {
try {
int exitCode = process.waitFor();
if (exitCode != 0) {
throw new IOException("Commands execution failed with exit code (" + exitCode + ") Commands: " + commands + ", Output: " + out + " Error: " + err);
}
return out;
} catch (InterruptedException e) {
interrupted = true;
}
}
} finally {
if (interrupted) {
Thread.currentThread().interrupt();
}
}
}
use of io.cdap.cdap.runtime.spi.ssh.SSHProcess in project cdap by caskdata.
the class SSHRemoteProcessController method killProcess.
private void killProcess(int signal) throws IOException, InterruptedException {
// SSH and kill the process
try (SSHSession session = new DefaultSSHSession(sshConfig)) {
SSHProcess process = session.execute(String.format("pkill -%d -f -- -Dcdap.runid=%s", signal, programRunId.getRun()));
// Reading will be blocked until the process finished
ByteStreams.toByteArray(process.getInputStream());
String err = CharStreams.toString(new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8));
int exitCode = process.waitFor();
// If the exit code is 1, it means there is no such process, which is fine from the termination perspective
if (exitCode == 0 || exitCode == 1) {
return;
}
throw new IllegalStateException("Failed to kill remote process for program run " + programRunId + " due to error " + err);
}
}
use of io.cdap.cdap.runtime.spi.ssh.SSHProcess in project cdap by caskdata.
the class SSHRemoteProcessController method isRunning.
@Override
public boolean isRunning() throws Exception {
// Try to SSH into the host and see if the CDAP runtime process is running or not
try (SSHSession session = new DefaultSSHSession(sshConfig)) {
SSHProcess process = session.execute("pgrep -f -- -Dcdap.runid=" + programRunId.getRun());
// Reading will be blocked until the process finished.
// The output is not needed, just read it to avoid filling up the network buffer.
ByteStreams.toByteArray(process.getInputStream());
ByteStreams.toByteArray(process.getErrorStream());
int exitCode = process.waitFor();
if (exitCode != 0) {
LOG.info("Received exit code {} when checking for remote process for program run {}.", exitCode, programRunId);
}
return exitCode == 0;
} catch (IOException e) {
// If there is error performing SSH, check if the cluster still exist and running
LOG.debug("Failed to use SSH to determine if the remote process is running for {}. Check cluster status instead.", programRunId, e);
Cluster cluster = GSON.fromJson(programOpts.getArguments().getOption(ProgramOptionConstants.CLUSTER), Cluster.class);
String userId = programOpts.getArguments().getOption(ProgramOptionConstants.USER_ID);
ClusterStatus clusterStatus = provisioningService.getClusterStatus(programRunId, programOpts, cluster, userId);
// The cluster status has to be RUNNING in order for the remote process still has a chance that is running
return clusterStatus == ClusterStatus.RUNNING;
}
}
use of io.cdap.cdap.runtime.spi.ssh.SSHProcess in project cdap by caskdata.
the class DefaultSSHSession method execute.
@Override
public SSHProcess execute(List<String> commands) throws IOException {
try {
Channel channel = session.openChannel("exec");
try {
ChannelExec channelExec = (ChannelExec) channel;
// Should get the stream before connecting.
// Otherwise JSch will write the output to some default stream, causing data missing from
// the InputStream that acquired later.
SSHProcess process = new DefaultSSHProcess(channelExec, channelExec.getOutputStream(), channelExec.getInputStream(), channelExec.getErrStream());
channelExec.setCommand(String.join(";", commands));
channelExec.connect();
return process;
} catch (Exception e) {
channel.disconnect();
throw e;
}
} catch (JSchException e) {
throw new IOException(e);
}
}
Aggregations