com.adaptc.mws.plugins.natives.NativePlugin.groovy Maven / Gradle / Ivy
package com.adaptc.mws.plugins.natives
import com.adaptc.mws.plugins.*
/**
* The Native Plugin is a replication of the Moab Native resource manager interface in MWS.
* Documentation may be found by going to the reference guide -> Bundled Plugins ->
* Native.
* @author bsaville
*/
class NativePlugin extends AbstractPlugin {
static description = "Basic implementation of a native plugin"
static constraints = {
environment(required:false)
getCluster required:false, scriptableUrl:true
getNodes required:false, scriptableUrl:true
getVirtualMachines required:false, scriptableUrl:true
getJobs required:false, scriptableUrl:true
jobCancel required:false, scriptableUrl:true
jobModify required:false, scriptableUrl:true
jobRequeue required:false, scriptableUrl:true
jobResume required:false, scriptableUrl:true
jobStart required:false, scriptableUrl:true
jobSubmit required:false, scriptableUrl:true
jobSuspend required:false, scriptableUrl:true
nodeModify required:false, scriptableUrl:true
nodePower required:false, scriptableUrl:true
startUrl required:false, scriptableUrl:true
stopUrl required:false, scriptableUrl:true
}
JobNativeTranslator jobNativeTranslator
NodeNativeTranslator nodeNativeTranslator
VirtualMachineNativeTranslator virtualMachineNativeTranslator
IJobRMService jobRMService
INodeRMService nodeRMService
IVirtualMachineRMService virtualMachineRMService
private def getConfigKey(String key) {
if (config.containsKey(key))
return config[key]
return null
}
/**
* Overrides the default implementation of poll so that a single
* cluster query can be used for both nodes and VMs.
*/
public void poll() {
def nodes = []
def vms = []
if (getConfigKey("getCluster")) {
log.debug("Polling getCluster URL")
getCluster()?.groupBy { it.class }?.each { Class clazz, List values ->
switch(clazz) {
case NodeReport.class:
nodes = values
break;
case VirtualMachineReport.class:
vms = values
break;
default:
log.warn("Unknown object found from cluster query, ignoring values: ${clazz}")
break;
}
}
} else {
log.debug("Polling getNodes and getVirtualMachines URLs")
nodes = getNodes()
vms = getVirtualMachines()
}
// Ensure that save is called EVERY time the poll is executed
nodeRMService.save(nodes)
virtualMachineRMService.save(vms)
log.debug("Polling getJobs URL")
jobRMService.save(getJobs());
}
public void beforeStart() {
try {
def url = getConfigKey("startUrl")?.toURL()
if (!url)
return
log.debug("Starting plugin ${id} with ${url}")
def result = readURL(url)
if (result.exitCode==0)
log.info("Started plugin ${id} (${result.content})")
else
log.warn("Could not start plugin ${id} (${result.exitCode}): ${result.content}")
} catch(Exception e) {
log.warn("Could not start plugin ${id} due to exception: ${e.message}")
}
}
public void afterStop() {
try {
def url = getConfigKey("stopUrl")?.toURL()
if (!url)
return
log.debug("Stopping plugin ${id} with ${url}")
def result = readURL(url)
if (result.exitCode==0)
log.info("Stopped plugin ${id} (${result.content})")
else
log.warn("Could not stop plugin ${id} (${result.exitCode}): ${result.content}")
} catch(Exception e) {
log.warn("Could not stop plugin ${id} due to exception: ${e.message}")
}
}
public List getJobs() {
def url = getConfigKey("getJobs")?.toURL()
if (!url)
return []
def result = readURL(url)
if (!hasError(result, true)) {
return parseWiki(result.content).collect { Map attrs ->
jobNativeTranslator.createReport(attrs)
}
}
return []
}
public List> getCluster() {
def url = getConfigKey("getCluster")?.toURL()
if (!url)
return []
def result = readURL(url)
if (!hasError(result, true)) {
return parseWiki(result.content).collect { Map attrs ->
if (attrs.CONTAINERNODE) // Only VMs have this attribute
return virtualMachineNativeTranslator.createReport(attrs)
else // Default to a node
return nodeNativeTranslator.createReport(attrs)
}
}
return []
}
public List getNodes() {
def url = getConfigKey("getNodes")?.toURL()
if (!url)
return []
def result = readURL(url)
if (!hasError(result, true)) {
return parseWiki(result.content).collect { Map attrs ->
nodeNativeTranslator.createReport(attrs)
}
}
return []
}
public List getVirtualMachines() {
def url = getConfigKey("getVirtualMachines")?.toURL()
if (!url)
return []
def result = readURL(url)
if (!hasError(result, true)) {
return parseWiki(result.content).collect { Map attrs ->
virtualMachineNativeTranslator.createReport(attrs)
}
}
return []
}
// TODO Cancel more than just the first job
public boolean jobCancel(List jobs) {
def url = getConfigKey("jobCancel")?.toURL()
if (!url)
return false
def jobId = jobs[0]
url.query = jobId
log.debug("Canceling job ${jobId}")
def result = readURL(url)
return !hasError(result)
}
// TODO Modify more than just the first job
public boolean jobModify(List jobs, Map properties) {
def url = getConfigKey("jobModify")?.toURL()
if (!url)
return false
def jobId = jobs[0]
def queryParams = [jobId]
queryParams.addAll(properties.collect { "${it.key}="+(it.value?.contains(" ")?"\"${it.value}\"":it.value) })
url.query = queryParams.join("&")
log.debug("Modifying job ${jobId} with properties ${properties}")
def result = readURL(url)
return !hasError(result)
}
// TODO Resume more than just the first job
public boolean jobResume(List jobs) {
def url = getConfigKey("jobResume")?.toURL()
if (!url)
return false
def jobId = jobs[0]
url.query = jobId
log.debug("Resuming job ${jobId}")
def result = readURL(url)
return !hasError(result)
}
// TODO Requeue more than just the first job
public boolean jobRequeue(List jobs) {
def url = getConfigKey("jobRequeue")?.toURL()
if (!url)
return false
def jobId = jobs[0]
url.query = jobId
log.debug("Requeuing job ${jobId}")
def result = readURL(url)
return !hasError(result)
}
//TODO Handle properties in jobStart
public boolean jobStart(String jobId, String taskList, String userName, Map properties=null) {
def url = getConfigKey("jobStart")?.toURL()
if (!url)
return false
url.query = [jobId, taskList, userName].join("&")
log.debug("Starting job ${jobId} with task list ${taskList} and user ${userName}")
def result = readURL(url)
return !hasError(result)
}
public boolean jobSubmit(Map properties) {
def url = getConfigKey("jobSubmit")?.toURL()
if (!url)
return false
url.query = properties?.collect { "${it.key}="+(it.value?.contains(" ")?"\"${it.value}\"":it.value) }.join("&")
log.debug("Submitting job ${properties.NAME}")
def result = readURL(url)
return !hasError(result)
}
// TODO Suspend more than just the first job
public boolean jobSuspend(List jobs) {
def url = getConfigKey("jobSuspend")?.toURL()
if (!url)
return false
def jobId = jobs[0]
url.query = jobId
log.debug("Suspending job ${jobId}")
def result = readURL(url)
return !hasError(result)
}
public boolean nodeModify(List nodes, Map properties) {
def url = getConfigKey("nodeModify")?.toURL()
if (!url)
return false
url.query = nodes.join(",")+"&--set&"
url.query += properties.collect { "${it.key}="+(it.value?.contains(" ")?"\"${it.value}\"":it.value) }.join("&")
log.debug("Modifying nodes ${nodes} with properties ${properties}")
def result = readURL(url)
return !hasError(result)
}
public boolean nodePower(List nodes, NodeReportPower state) {
def url = getConfigKey("nodePower")?.toURL()
if (!url)
return false
url.query = [nodes.join(","), state.name()].join("&")
log.debug("Changing power state to ${state} for nodes ${nodes}")
def result = readURL(url)
return !hasError(result)
}
/**
* Returns a list of maps containing the wiki parameters, with the id stored as id
* and all other parameters as key/value pairs.
* Also handles hashes for newline delimiters
* @param lines Native wiki lines delimited by semi-colons and equals (; and =)
* @return
*/
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy