mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-01 15:37:32 +08:00
5e36bde9c8
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.
143 lines
3.9 KiB
Python
Executable File
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()
|