Files
galaxy/scripts/drmaa_external_runner.py
T
John Chilton 5e36bde9c8 Rework contribution from pull request #267 to be optional.
To obtain the behavior (assigning all groups for a given user for each job submission) change the property - 'drmaa_external_runjob_script' from  'scripts/drmaa_external_runner.py' to 'scripts/drmaa_external_runner.py --assign_all_groups'.

Making this optional because my concern is that this could be an expensive operation on some clusters.
2013-12-10 08:26:22 -06:00

143 lines
3.9 KiB
Python
Executable File

#!/usr/bin/env python
"""
Submit a DRMAA job given a user id and a job template file (in JSON format)
defining any or all of the following: args, remoteCommand, outputPath,
errorPath, nativeSpecification, name, email, project
"""
import os
import sys
import errno
import pwd
#import simplejson as json
#import drmaa
new_path = [ os.path.join( os.getcwd(), "lib" ) ]
new_path.extend( sys.path[1:] ) # remove scripts/ from the path
sys.path = new_path
from galaxy import eggs
import pkg_resources
pkg_resources.require("simplejson")
import simplejson as json
pkg_resources.require("drmaa")
import drmaa
DRMAA_jobTemplate_attributes = [ 'args', 'remoteCommand', 'outputPath', 'errorPath', 'nativeSpecification',
'jobName', 'email', 'project' ]
def load_job_template_from_file(jt, filename):
f = open(filename, 'r')
data = json.load(f)
for attr in DRMAA_jobTemplate_attributes:
if attr in data:
setattr(jt, attr, data[attr])
def valid_numeric_userid(userid):
try:
uid = int(userid)
except:
return False
try:
pwd.getpwuid(uid)
except KeyError:
sys.stderr.write("error: User-ID (%d) is not valid.\n" % uid)
exit(1)
return True
def get_user_id_by_name(username):
try:
pw = pwd.getpwnam(username)
except KeyError:
sys.stderr.write("error: User name (%s) is not valid.\n" % username)
exit(1)
return pw.pw_uid
def json_file_exists(json_filename):
if not os.path.exists(json_filename):
sys.stderr.write("error: JobTemplate file (%s) doesn't exist\n" % ( json_filename ) )
exit(1)
return True
def validate_paramters():
assign_all_groups = False
if "--assign_all_groups" in sys.argv:
assign_all_groups = True
sys.argv.remove("--assign_all_groups")
if len(sys.argv) < 3:
sys.stderr.write("usage: %s [USER-ID] [JSON-JOB-TEMPLATE-FILE]\n" % sys.argv[0])
exit(1)
userid = sys.argv[1]
json_filename = sys.argv[2]
if valid_numeric_userid(userid):
uid = int(userid)
else:
uid = get_user_id_by_name(userid)
if uid == 0:
sys.stderr.write("error: userid must not be 0 (root)\n")
exit(1)
return uid, json_filename, assign_all_groups
def set_user(uid, assign_all_groups):
try:
# Get user's default group and set it to current process to make sure file permissions are inherited correctly
# Solves issue with permission denied for JSON files
gid = pwd.getpwuid(uid).pw_gid
import grp
os.setgid(gid)
if assign_all_groups:
# Added lines to assure read/write permission for groups
user = pwd.getpwuid(uid).pw_name
groups = [g.gr_gid for g in grp.getgrall() if user in g.gr_mem]
os.setgroups(groups)
os.setuid(uid)
except OSError, e:
if e.errno == errno.EPERM:
sys.stderr.write( "error: setuid(%d) failed: permission denied. Did you setup 'sudo' correctly for this script?\n" % uid )
exit(1)
else:
pass
if os.getuid() == 0:
sys.stderr.write( "error: UID is 0 (root) after changing user. This script should not be run as root. aborting.\n" )
exit(1)
if os.geteuid() == 0:
sys.stderr.write( "error: EUID is 0 (root) after changing user. This script should not be run as root. aborting.\n" )
exit(1)
def main():
userid, json_filename, assign_all_groups = validate_paramters()
set_user(userid, assign_all_groups)
json_file_exists(json_filename)
s = drmaa.Session()
s.initialize()
jt = s.createJobTemplate()
load_job_template_from_file(jt, json_filename)
# runJob will raise if there's a submittion error
jobId = s.runJob(jt)
s.deleteJobTemplate(jt)
s.exit()
# Print the Job-ID and exit. Galaxy will pick it up from there.
print jobId
if __name__ == "__main__":
main()