use of io.cdap.cdap.runtime.spi.ssh.SSHSession in project cdap by cdapio.
the class SSHRemoteExecutionService method createServiceProxyTunnel.
/**
* Creates a remote port forwarding SSH tunnel for remote runtime to access CDAP services.
*/
private SSHSession createServiceProxyTunnel() throws IOException {
SSHSession session = new DefaultSSHSession(sshConfig);
ProgramRunId programRunId = getProgramRunId();
// Creates a new remote port forwarding from the session.
// We don't need to care about closing the forwarding as it will last until the session get closed,
// in which the remote port forwarding will be closed automatically
int remotePort = session.createRemotePortForward(0, serviceSocksProxyPort).getRemotePort();
LOG.debug("Service SOCKS proxy started on port {} for program run {}", remotePort, programRunId);
ServiceSocksProxyInfo info = new ServiceSocksProxyInfo(remotePort);
// Upload the service socks proxy information to the remote runtime
String targetPath = session.executeAndWait("echo `pwd`/" + programRunId.getRun()).trim();
session.executeAndWait("mkdir -p " + targetPath);
byte[] content = GSON.toJson(info).getBytes(StandardCharsets.UTF_8);
String targetFileName = Constants.RuntimeMonitor.SERVICE_PROXY_FILE + "-" + programRunId.getRun() + ".json";
String tmpFileName = targetFileName + "-" + System.currentTimeMillis() + ".tmp";
// noinspection OctalInteger
session.copy(new ByteArrayInputStream(content), "/tmp", tmpFileName, content.length, 0600, null, null);
session.executeAndWait(String.format("mv /tmp/%s /tmp/%s", tmpFileName, targetFileName));
LOG.debug("Service proxy file uploaded to remote runtime for program run {}", programRunId);
return session;
}
use of io.cdap.cdap.runtime.spi.ssh.SSHSession in project cdap by cdapio.
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.SSHSession in project cdap by cdapio.
the class SSHSessionTest method testSsh.
@Test
public void testSsh() throws Exception {
SSHConfig config = getSSHConfig();
try (SSHSession session = new DefaultSSHSession(config)) {
for (int i = 0; i < 10; i++) {
String msg = "Sending some message " + i;
String result = session.executeAndWait(msg);
Assert.assertEquals(msg, result);
}
}
// Test the error exit
try (SSHSession session = new DefaultSSHSession(config)) {
try {
session.executeAndWait("failure");
Assert.fail("Expected failure from ssh command");
} catch (Exception e) {
// Expected
}
}
}
use of io.cdap.cdap.runtime.spi.ssh.SSHSession in project cdap by cdapio.
the class SSHSessionTest method testLocalPortForwarding.
@Test
public void testLocalPortForwarding() throws Exception {
// Starts an echo server for testing the port forwarding
EchoServer echoServer = new EchoServer();
echoServer.startAndWait();
try {
// Creates the DataConsumer for receiving data and validating the lifecycle
StringBuilder received = new StringBuilder();
AtomicBoolean finished = new AtomicBoolean();
PortForwarding.DataConsumer dataConsumer = new PortForwarding.DataConsumer() {
private final List<String> messages = new ArrayList<>();
@Override
public void received(ByteBuffer buffer) {
messages.add(StandardCharsets.UTF_8.decode(buffer).toString());
}
@Override
public synchronized void flushed() {
messages.forEach(received::append);
}
@Override
public void finished() {
finished.set(true);
}
};
SSHConfig sshConfig = getSSHConfig();
// Creates a SSH session.
try (SSHSession session = new DefaultSSHSession(sshConfig)) {
InetSocketAddress bindAddress = echoServer.getBindAddress();
// Creates local port forward and send data to the echo server through that forwarding channel
try (PortForwarding portForwarding = session.createLocalPortForward(bindAddress.getHostName(), bindAddress.getPort(), 12345, dataConsumer)) {
List<String> messages = new ArrayList<>();
for (int i = 0; i < 10; i++) {
String msg = "Testing" + i;
portForwarding.write(StandardCharsets.UTF_8.encode(msg));
portForwarding.write(StandardCharsets.UTF_8.encode("\n"));
messages.add(msg);
}
portForwarding.flush();
Iterable<String> splits = Splitter.on("\n").omitEmptyStrings().split(received);
Assert.assertEquals(messages, StreamSupport.stream(splits.spliterator(), false).collect(Collectors.toList()));
}
// After closing the port forwarding, the data consumer should have finished.
Assert.assertTrue(finished.get());
}
} finally {
echoServer.stopAndWait();
}
}
use of io.cdap.cdap.runtime.spi.ssh.SSHSession in project cdap by cdapio.
the class RemoteHadoopProvisioner method initializeCluster.
@Override
public void initializeCluster(ProvisionerContext context, Cluster cluster) throws Exception {
RemoteHadoopConf conf = RemoteHadoopConf.fromProperties(context.getProperties());
String initializationAction = conf.getInitializationAction();
if (initializationAction != null && !initializationAction.isEmpty()) {
try (SSHSession session = createSSHSession(context, getMasterExternalIp(cluster))) {
LOG.debug("Initializing action: {}", initializationAction);
String output = session.executeAndWait(initializationAction);
LOG.debug("Initialization action completed: {}", output);
}
}
}
Aggregations