Personal tools
You are here: Home GRIA Documentation Documentation 5.2 Reference Manuals Basic Application Services User Guide The Job Service Resource Managers Writing Custom Resource Manager Plugins

4.6.5. Writing Custom Resource Manager Plugins

Up one level
System administrators can write their own RM Connector Plugins to interface with other Resource Managers.

What are they?

RM Connector Plugins are classes written in Python that handle all communication with the Resource Manager. The GRIA Job Service comes with three RM Connector Plugins that can be used as examples. These can be found inside the webapp:

TOMCAT_DIR/webapps/gria-basic-app-services/WEB-INF/rm-connectors/plugins

When writing your own plugins, you should not put them inside the webapp directory as they will be lost whenever you redeploy or upgrade the GRIA Job Service. Instead, place them in a new directory outside the webapp (eg. /opt/gria/rm-connectors) and enter this path into the Job Service configuration:

Setting additional plugin directories

Figure 1: Setting additional plugin directories

Plugins usually consist of one Python script (.py) and one or more template files. These templates are used when creating new jobs - values are substituted into them and they are written back into the new job directory. The Condor plugin consists of the following files:

  • Condor.py - the main Python script. Contains functions for interacting with the Resource Manager.
  • CondorTemplate.frame - template for job wrapper "frames".
  • CondorTemplate.jdf - template for new Job Description Files.

A Sample plugin

The code listing below is a sample RM Connector Plugin that you can use as a starting point for writing your own. It describes what you need to do to implement the five main functions in any plugin:

  • submit - submits a new job to the resource mananger.
  • jobStatus - checks whether a job is still running.
  • jobUsage - gets usage reports.
  • killJob - terminates a job.
  • canRunJob - checks if the RM can run the requested job.

For more complete documentation on the API, see RMConnector.

#!/usr/bin/env python -tt
# -*- coding: UTF-8 -*-

from RMConnector import RMConnector, ScriptNotFound
from Logger import logsys, loguser
import platformUtils

class Sample(RMConnector):
	MIN_API_VERSION=1

	def submit(self, job):
		RMConnector.submit(self, job)

		logsys.info("Executable we're running is " + job.executableName)
		logsys.info("Our arguments are " + repr(job.arguments))

		# TODO: Submit the job to the resource manager

	def jobStatus(self):
		# TODO: Check whether our job is really running.  If not, write an
		# empty file called .FAILED in the current directory.

		pass

	def jobUsage(self, appWrapperDir):
		appUsageReports = RMConnector.jobUsage(self, appWrapperDir)

		# TODO: Get any usage information from the RM, and append it to
		# appUsageReports

		return appUsageReports

	def killJob(self, appWrapperDir):
		# Try using the application wrapper scripts to kill the job gracefully
		try:
			RMConnector.killJob(self, appWrapperDir)
		except ScriptNotFound:
			pass

		# TODO: Check if the job is still running.  If it is, it means there
		# wasn't an application wrapper script, or they couldn't kill the job
		# So kill the job forcefully.

		# Write a file telling GRIA we killed the job
		platformUtils.writeToFile(".KILLED", "")

	def canRunJob(self, job):
		# TODO: Check if this RM has enough resources to run the job.
		# If we can't, return False with a reason, eg:
		# return (False, "Not enough memory")
		return (True, None)