Search in sources :

Example 6 with CommandLineBuilder

use of org.ow2.proactive.resourcemanager.utils.CommandLineBuilder in project scheduling by ow2-proactive.

the class SSHInfrastructureV2 method startNodeImpl.

/**
 * Internal node acquisition method
 * <p>
 * Starts a PA runtime on remote host using SSH, register it manually in the
 * nodesource.
 *
 * @param hostTracker The host on which one the node will be started
 * @param nbNodes number of nodes to deploy
 * @param depNodeURLs list of deploying or lost nodes urls created
 * @throws RMException
 *             acquisition failed
 */
public void startNodeImpl(final HostTracker hostTracker, final int nbNodes, final List<String> depNodeURLs) throws RMException {
    String fs = getTargetOSObj().fs;
    // we set the java security policy file
    ArrayList<String> sb = new ArrayList<>();
    final boolean containsSpace = schedulingPath.contains(" ");
    if (containsSpace) {
        sb.add("-Dproactive.home=\"" + schedulingPath + "\"");
    } else {
        sb.add("-Dproactive.home=" + schedulingPath);
    }
    String securitycmd = CentralPAPropertyRepository.JAVA_SECURITY_POLICY.getCmdLine();
    if (!this.javaOptions.contains(securitycmd)) {
        if (containsSpace) {
            securitycmd += "\"";
        }
        securitycmd += this.schedulingPath + fs + "config" + fs;
        securitycmd += "security.java.policy-client";
        if (containsSpace) {
            securitycmd += "\"";
        }
        sb.add(securitycmd);
    }
    // we set the log4j configuration file
    String log4jcmd = CentralPAPropertyRepository.LOG4J.getCmdLine();
    if (!this.javaOptions.contains(log4jcmd)) {
        // log4j only understands urls
        if (containsSpace) {
            log4jcmd += "\"";
        }
        log4jcmd += "file:";
        if (!this.schedulingPath.startsWith("/")) {
            log4jcmd += "/";
        }
        log4jcmd += this.schedulingPath.replace("\\", "/");
        log4jcmd += "/config/log/node.properties";
        if (containsSpace) {
            log4jcmd += "\"";
        }
        sb.add(log4jcmd);
    }
    // we add extra java/PA configuration
    if (this.javaOptions != null && !this.javaOptions.trim().isEmpty()) {
        sb.add(this.javaOptions.trim());
    }
    CommandLineBuilder clb = super.getDefaultCommandLineBuilder(getTargetOSObj());
    final boolean deployNodesInDetachedMode = PAResourceManagerProperties.RM_NODES_RECOVERY.getValueAsBoolean() || PAResourceManagerProperties.RM_PRESERVE_NODES_ON_SHUTDOWN.getValueAsBoolean();
    if (deployNodesInDetachedMode) {
        // if we do not want to kill the nodes when the RM exits or
        // restarts, then we should launch the nodes in background and
        // ignore the RM termination signal
        clb.setDetached();
    }
    clb.setJavaPath(this.javaPath);
    clb.setRmHome(this.schedulingPath);
    clb.setPaProperties(sb);
    final String nodeName = nodeNameBuilder.generateNodeName(hostTracker);
    clb.setNodeName(nodeName);
    clb.setNumberOfNodes(nbNodes);
    // finally, the credential's value
    String credString;
    try {
        Client currentClient = super.nodeSource.getAdministrator();
        credString = new String(currentClient.getCredentials().getBase64());
    } catch (KeyException e) {
        throw new RMException("Could not get base64 credentials", e);
    }
    clb.setCredentialsValueAndNullOthers(credString);
    // add an expected node. every unexpected node will be discarded
    String cmdLine;
    String obfuscatedCmdLine;
    try {
        cmdLine = clb.buildCommandLine(true);
        obfuscatedCmdLine = clb.buildCommandLine(false);
    } catch (IOException e) {
        throw new RMException("Cannot build the " + RMNodeStarter.class.getSimpleName() + "'s command line.", e);
    }
    // one escape the command to make it runnable through ssh
    if (cmdLine.contains("\"")) {
        cmdLine = cmdLine.replaceAll("\"", "\\\\\"");
    }
    final String finalCmdLine = cmdLine;
    // The final addDeployingNode() method will initiate a timeout that
    // will declare node as lost and set the description of the failure
    // with a simplistic message, since there is no way to override this
    // mechanism we consider only 90% of timeout to set custom description
    // in case of failure and still allow global timeout
    final int shorterTimeout = Math.round((90 * super.nodeTimeOut) / 100);
    JSch jsch = new JSch();
    final String msg = "deploy on " + hostTracker.getResolvedAddress();
    final List<String> createdNodeNames = RMNodeStarter.getWorkersNodeNames(nodeName, nbNodes);
    depNodeURLs.addAll(addMultipleDeployingNodes(createdNodeNames, obfuscatedCmdLine, msg, super.nodeTimeOut));
    addTimeouts(depNodeURLs);
    Session session;
    try {
        // Create ssh session to the hostname
        session = jsch.getSession(this.sshUsername, hostTracker.getResolvedAddress().getHostName(), this.sshPort);
        if (this.sshPassword == null) {
            jsch.addIdentity(this.sshUsername, this.sshPrivateKey, null, null);
        } else {
            session.setPassword(this.sshPassword);
        }
        session.setConfig(this.sshOptions);
        session.connect(shorterTimeout);
    } catch (JSchException e) {
        multipleDeclareDeployingNodeLost(depNodeURLs, "unable to " + msg + "\n" + getStackTraceAsString(e));
        throw new RMException("unable to " + msg, e);
    }
    SSHInfrastructureV2.logger.info("Executing SSH command: '" + finalCmdLine + "'");
    ScheduledExecutorService deployService = Executors.newSingleThreadScheduledExecutor();
    try {
        // Create ssh channel to run the cmd
        ByteArrayOutputStream baos = new ByteArrayOutputStream(DEFAULT_OUTPUT_BUFFER_LENGTH);
        ChannelExec channel;
        try {
            channel = (ChannelExec) session.openChannel("exec");
            channel.setCommand(finalCmdLine);
            channel.setOutputStream(baos);
            channel.setErrStream(baos);
            channel.connect();
        } catch (JSchException e) {
            multipleDeclareDeployingNodeLost(depNodeURLs, "unable to " + msg + "\n" + getStackTraceAsString(e));
            throw new RMException("unable to " + msg, e);
        }
        final ChannelExec chan = channel;
        Future<Void> deployResult = deployService.submit(new Callable<Void>() {

            @Override
            public Void call() throws Exception {
                while (!shutDown.get() && !checkAllNodesAreAcquiredAndDo(createdNodeNames, null, null)) {
                    if (anyTimedOut(depNodeURLs)) {
                        throw new IllegalStateException("The upper infrastructure has issued a timeout");
                    }
                    // processes live completely independently
                    if (!deployNodesInDetachedMode && chan.getExitStatus() != PROCESS_STILL_RUNNING_VALUE) {
                        throw new IllegalStateException("The jvm process of the node has exited prematurely");
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // we know the cause of this
                        return null;
                    // interruption just exit
                    }
                }
                // Victory
                return null;
            }
        });
        try {
            deployResult.get(shorterTimeout, TimeUnit.MILLISECONDS);
        } catch (ExecutionException e) {
            declareLostAndThrow("Unable to " + msg + " due to " + e.getCause(), depNodeURLs, channel, baos, e);
        } catch (InterruptedException e) {
            deployResult.cancel(true);
            declareLostAndThrow("Unable to " + msg + " due to an interruption", depNodeURLs, channel, baos, e);
        } catch (TimeoutException e) {
            deployResult.cancel(true);
            declareLostAndThrow("Unable to " + msg + " due to timeout", depNodeURLs, channel, baos, e);
        } finally {
            channel.disconnect();
        }
    } finally {
        removeTimeouts(depNodeURLs);
        session.disconnect();
        deployService.shutdownNow();
    }
}
Also used : JSchException(com.jcraft.jsch.JSchException) ArrayList(java.util.ArrayList) Throwables.getStackTraceAsString(com.google.common.base.Throwables.getStackTraceAsString) CommandLineBuilder(org.ow2.proactive.resourcemanager.utils.CommandLineBuilder) JSch(com.jcraft.jsch.JSch) RMException(org.ow2.proactive.resourcemanager.exception.RMException) Client(org.ow2.proactive.resourcemanager.authentication.Client) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) KeyException(java.security.KeyException) ChannelExec(com.jcraft.jsch.ChannelExec) KeyException(java.security.KeyException) TimeoutException(java.util.concurrent.TimeoutException) IOException(java.io.IOException) RMException(org.ow2.proactive.resourcemanager.exception.RMException) ExecutionException(java.util.concurrent.ExecutionException) JSchException(com.jcraft.jsch.JSchException) Session(com.jcraft.jsch.Session)

Example 7 with CommandLineBuilder

use of org.ow2.proactive.resourcemanager.utils.CommandLineBuilder in project scheduling by ow2-proactive.

the class CommandLineBuilder method buildCommandLineAsList.

/**
 * Same as {@link CommandLineBuilder#buildCommandLine(boolean)} but the command is a list of String.
 * @param displayCredentials if true displays the credentials in the command line if false, obfuscates them
 * @return The RMNodeStarter command line as a list of String.
 * @throws java.io.IOException if you supplied a ProActive Configuration file that doesn't exist.
 */
public List<String> buildCommandLineAsList(boolean displayCredentials) throws IOException {
    final ArrayList<String> command = new ArrayList<>();
    final OperatingSystem os = targetOS;
    final Properties paProp = paPropProperties;
    String rmHome = this.getRmHome();
    if (rmHome != null) {
        if (!rmHome.endsWith(os.fs)) {
            rmHome = rmHome + os.fs;
        }
    } else {
        rmHome = "";
    }
    if (detached) {
        makeDetachedCommand(command, os);
    }
    final String libRoot = rmHome + "dist" + os.fs + "lib" + os.fs;
    String javaPath = this.javaPath;
    if (javaPath != null) {
        command.add(javaPath);
    } else {
        RMNodeStarter.logger.warn("Java path isn't set in RMNodeStarter configuration.");
        command.add("java");
    }
    // building configuration
    if (paProp != null) {
        Set<Object> keys = paProp.keySet();
        for (Object key : keys) {
            command.add("-D" + key + "=" + paProp.get(key));
        }
    } else {
        if (this.paPropList != null) {
            command.addAll(this.paPropList);
        }
    }
    // forward current charset to the forked JVM
    String currentJvmCharset = PAProperties.getFileEncoding();
    command.add("-Dfile.encoding=" + currentJvmCharset);
    RMNodeStarter.logger.info("Using '" + currentJvmCharset + "' as file encoding");
    // building classpath
    command.add("-cp");
    final StringBuilder classpath = new StringBuilder(".");
    // add the content of addons dir on the classpath
    classpath.append(os.ps).append(rmHome).append(ADDONS_DIR);
    // add jars inside the addons directory
    classpath.append(os.ps).append(rmHome).append(ADDONS_DIR).append(os.fs).append("*");
    classpath.append(os.ps).append(libRoot).append("*");
    command.add(classpath.toString());
    command.add(RMNodeStarter.class.getName());
    // appending options
    String credsEnv = credentialsEnv;
    if (credsEnv != null) {
        command.add("-" + RMNodeStarter.OPTION_CREDENTIAL_ENV);
        command.add(credsEnv);
    }
    String credsFile = this.getCredentialsFile();
    if (credsFile != null) {
        command.add("-" + RMNodeStarter.OPTION_CREDENTIAL_FILE);
        command.add(credsFile);
    }
    String credsValue = this.getCredentialsValue();
    if (credsValue != null) {
        command.add("-" + RMNodeStarter.OPTION_CREDENTIAL_VAL);
        command.add(displayCredentials ? credsValue : OBFUSC);
    }
    String nodename = this.getNodeName();
    if (nodename != null) {
        command.add("-" + RMNodeStarter.OPTION_NODE_NAME);
        command.add(nodename);
    }
    String nodesource = this.getSourceName();
    if (nodesource != null) {
        command.add("-" + RMNodeStarter.OPTION_SOURCE_NAME);
        command.add(nodesource);
    }
    String rmurl = rmURL;
    if (rmurl != null) {
        command.add("-" + RMNodeStarter.OPTION_RM_URL);
        command.add(rmurl);
    }
    command.add("-" + RMNodeStarter.OPTION_WORKERS);
    command.add("" + nbNodes);
    if (detached && os.equals(OperatingSystem.UNIX)) {
        command.add("&");
    }
    return command;
}
Also used : ArrayList(java.util.ArrayList) PAResourceManagerProperties(org.ow2.proactive.resourcemanager.core.properties.PAResourceManagerProperties) Properties(java.util.Properties) PAProperties(org.ow2.proactive.utils.PAProperties)

Aggregations

IOException (java.io.IOException)6 KeyException (java.security.KeyException)5 CommandLineBuilder (org.ow2.proactive.resourcemanager.utils.CommandLineBuilder)5 Throwables.getStackTraceAsString (com.google.common.base.Throwables.getStackTraceAsString)4 RMException (org.ow2.proactive.resourcemanager.exception.RMException)4 ArrayList (java.util.ArrayList)3 UnknownHostException (java.net.UnknownHostException)2 ChannelExec (com.jcraft.jsch.ChannelExec)1 JSch (com.jcraft.jsch.JSch)1 JSchException (com.jcraft.jsch.JSchException)1 Session (com.jcraft.jsch.Session)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 File (java.io.File)1 InputStream (java.io.InputStream)1 InetAddress (java.net.InetAddress)1 Properties (java.util.Properties)1 ExecutionException (java.util.concurrent.ExecutionException)1 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)1 TimeoutException (java.util.concurrent.TimeoutException)1 ProcessExecutor (org.ow2.proactive.process.ProcessExecutor)1