use of org.ow2.proactive.resourcemanager.authentication.Client in project scheduling by ow2-proactive.
the class RMCore method releaseNodes.
/**
* {@inheritDoc}
*/
public BooleanWrapper releaseNodes(NodeSet nodes) {
if (nodes.getExtraNodes() != null) {
// do not forget to release extra nodes
nodes.addAll(nodes.getExtraNodes());
}
// exception to throw in case of problems
RuntimeException exception = null;
NodeSet nodesReleased = new NodeSet();
NodeSet nodesFailedToRelease = new NodeSet();
for (Node node : nodes) {
String nodeURL = null;
try {
nodeURL = node.getNodeInformation().getURL();
logger.debug("Releasing node " + nodeURL);
} catch (RuntimeException e) {
logger.debug("A Runtime exception occurred while obtaining information on the node," + "the node must be down (it will be detected later)", e);
// node is down, will be detected by pinger
exception = new IllegalStateException(e.getMessage(), e);
nodesFailedToRelease.add(node);
}
// verify whether the node has not been removed from the RM
if (this.allNodes.containsKey(nodeURL)) {
RMNode rmnode = this.getNodebyUrl(nodeURL);
// free
if (rmnode.isFree()) {
logger.warn("Client " + caller + " tries to release the already free node " + nodeURL);
nodesFailedToRelease.add(node);
} else if (rmnode.isDown()) {
logger.warn("Node was down, it cannot be released");
nodesFailedToRelease.add(node);
} else {
Set<? extends IdentityPrincipal> userPrincipal = rmnode.getOwner().getSubject().getPrincipals(UserNamePrincipal.class);
Permission ownerPermission = new PrincipalPermission(rmnode.getOwner().getName(), userPrincipal);
try {
caller.checkPermission(ownerPermission, caller + " is not authorized to free node " + node.getNodeInformation().getURL(), new RMCoreAllPermission(), new NodeUserAllPermission(), new NSAdminPermission());
if (rmnode.isToRemove()) {
removeNodeFromCoreAndSource(rmnode, caller);
nodesReleased.add(node);
if (delayedNodeSourceRemovalEvents.containsKey(rmnode.getNodeSourceName()) && nodeSourceCanBeRemoved(rmnode.getNodeSourceName())) {
logger.debug(NODE_SOURCE_STRING + rmnode.getNodeSourceName() + " is eligible to remove.");
final Entry<RMNodeSourceEvent, NodeSource> remove = delayedNodeSourceRemovalEvents.remove(rmnode.getNodeSourceName());
final RMNodeSourceEvent removedEvent = remove.getKey();
final NodeSource nodeSource = remove.getValue();
logger.info(NODE_SOURCE_STRING + rmnode.getNodeSourceName() + HAS_BEEN_SUCCESSFULLY + removedEvent.getEventType().getDescription());
this.monitoring.nodeSourceEvent(removedEvent);
nodeSource.shutdown(this.caller);
} else if (delayedNodeSourceUndeploying.containsKey(rmnode.getNodeSourceName()) && nodeSourceCanBeRemoved(rmnode.getNodeSourceName())) {
logger.debug(NODE_SOURCE_STRING + rmnode.getNodeSourceName() + " is eligible to undeploy.");
final NodeSource nodeSource = delayedNodeSourceUndeploying.remove(rmnode.getNodeSourceName());
logger.info(NODE_SOURCE_STRING + rmnode.getNodeSourceName() + HAS_BEEN_SUCCESSFULLY + "undeployed.");
nodeSource.shutdown(this.caller);
}
} else {
internalSetFree(rmnode);
nodesReleased.add(node);
}
} catch (SecurityException ex) {
logger.error(ex.getMessage(), ex);
nodesFailedToRelease.add(node);
exception = ex;
}
}
} else {
logger.warn("Cannot release unknown node " + nodeURL);
nodesFailedToRelease.add(node);
exception = new IllegalArgumentException("Cannot release unknown node " + nodeURL);
}
}
logger.info("Nodes released : " + nodesReleased);
if (!nodesFailedToRelease.isEmpty()) {
logger.warn("Nodes failed to release : " + nodesFailedToRelease);
}
if (exception != null) {
// throwing the latest exception we had
throw exception;
}
return new BooleanWrapper(true);
}
use of org.ow2.proactive.resourcemanager.authentication.Client in project scheduling by ow2-proactive.
the class RMCore method internalSetToRemove.
/**
* Mark node to be removed after releasing.
*
* @param rmNode node to be removed after node is released.
*/
void internalSetToRemove(final RMNode rmNode, Client initiator) {
// If the node is already marked to be removed, so no need to go further
if (rmNode.isToRemove()) {
return;
}
if (logger.isDebugEnabled()) {
logger.debug("Prepare to removing the node " + rmNode.getNodeURL());
}
// Get the previous state of the node needed for the event
final NodeState previousNodeState = rmNode.getState();
rmNode.setToRemove();
persistUpdatedRMNodeIfRecoveryEnabled(rmNode);
// create the event
this.registerAndEmitNodeEvent(rmNode.createNodeEvent(RMEventType.NODE_STATE_CHANGED, previousNodeState, initiator.getName()));
}
use of org.ow2.proactive.resourcemanager.authentication.Client in project scheduling by ow2-proactive.
the class RMCore method internalSetFree.
/**
* Change the state of the node to free, after a Task has been completed by the specified node.
* The node passed as parameter is moved to the list of nodes which are eligible for scheduling if it is not locked.
* In all cases, an event informing the node state's change is propagated to RMMonitoring.
*
* @param rmNode node to set free.
* @return true if the node successfully set as free, false if it was down before.
*/
@VisibleForTesting
BooleanWrapper internalSetFree(final RMNode rmNode) {
if (logger.isDebugEnabled()) {
logger.debug("Current node state " + rmNode.getState() + " " + rmNode.getNodeURL());
logger.debug("Setting node state to free " + rmNode.getNodeURL());
}
// If the node is already free no need to go further
if (rmNode.isFree()) {
return new BooleanWrapper(true);
}
// Get the previous state of the node needed for the event
final NodeState previousNodeState = rmNode.getState();
Client client = rmNode.getOwner();
if (client == null) {
// node has been just configured, so the user initiated this action is the node provider
client = rmNode.getProvider();
}
// resetting owner here
rmNode.setFree();
// an eligible node is a node that is free and not locked
if (!rmNode.isLocked()) {
this.eligibleNodes.add(rmNode);
}
persistUpdatedRMNodeIfRecoveryEnabled(rmNode);
this.registerAndEmitNodeEvent(rmNode.createNodeEvent(RMEventType.NODE_STATE_CHANGED, previousNodeState, client.getName()));
return new BooleanWrapper(true);
}
use of org.ow2.proactive.resourcemanager.authentication.Client in project scheduling by ow2-proactive.
the class RMCore method executeScript.
/**
* {@inheritDoc}
*/
@ImmediateService
public <T> List<ScriptResult<T>> executeScript(Script<T> script, String targetType, Set<String> targets) {
Client client;
try {
client = checkPermissionAndGetClientIsSuccessful();
} catch (Exception e) {
logger.error("Error while checking permission to execute node script", e);
return Collections.singletonList(new ScriptResult<>(new ScriptException(e)));
}
// Depending on the target type, select nodes for script execution
final TargetType tType = TargetType.valueOf(targetType);
final HashSet<RMNode> selectedRMNodes = new HashSet<>();
switch(tType) {
case NODESOURCE_NAME:
// If target is a nodesource name select one node, not busy if possible
for (String target : targets) {
NodeSource nodeSource = this.deployedNodeSources.get(target);
if (nodeSource != null) {
Set<String> scriptExecutionHostNames = new HashSet<>();
for (RMNode candidateNode : this.allNodes.values()) {
String candidateNodeHostName = candidateNode.getHostName();
if (candidateNode.getNodeSource().equals(nodeSource) && !scriptExecutionHostNames.contains(candidateNodeHostName)) {
scriptExecutionHostNames.add(candidateNodeHostName);
this.selectCandidateNode(selectedRMNodes, candidateNode, client);
}
}
}
}
break;
case NODE_URL:
// If target is node url select the node
for (String target : targets) {
RMNode candidateNode = this.allNodes.get(target);
if (candidateNode != null) {
this.selectCandidateNode(selectedRMNodes, candidateNode, client);
}
}
break;
case HOSTNAME:
// If target is hostname select first node from that host
for (String target : targets) {
for (RMNode node : this.allNodes.values()) {
if (node.getHostName().equals(target)) {
this.selectCandidateNode(selectedRMNodes, node, client);
break;
}
}
}
break;
default:
throw new IllegalArgumentException("Unable to execute node script, unknown target type: " + targetType);
}
// Return a ProActive future on the list of results
return this.selectionManager.executeScript(script, selectedRMNodes, null);
// To avoid blocking rmcore ao the call is delegated to the selection
// manager ao and each node is unlocked as soon as the script has
// finished it's execution.
}
use of org.ow2.proactive.resourcemanager.authentication.Client 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 (!deploymentMode.equals("useNodeJarStartupScript")) {
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) && !deploymentMode.equals("useNodeJarStartupScript")) {
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) && !deploymentMode.equals("useNodeJarStartupScript")) {
// 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);
// set the stratup script retrieved from NodeCommandLine.properties
if (!this.deploymentMode.equals("autoGenerated")) {
clb.setDeploymentMode(deploymentMode);
clb.setStartupScript((deploymentMode.equals("useStartupScript") ? startupScriptStandard : startupScriptWithNodeJarDownload));
}
if (this.deploymentMode.equals("useNodeJarStartupScript")) {
clb.setNodeJarUrl(nodeJarUrl);
}
// 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();
}
}
Aggregations