diff --git a/batchspawner/batchspawner.py b/batchspawner/batchspawner.py index 5d72a9d9..5ab0f9a6 100644 --- a/batchspawner/batchspawner.py +++ b/batchspawner/batchspawner.py @@ -90,6 +90,10 @@ class BatchSpawnerBase(Spawner): # override default server ip since batch jobs normally running remotely ip = Unicode("0.0.0.0", help="Address for singleuser server to listen at").tag(config=True) + exec_prefix = Unicode('sudo -E -u {username}', \ + help="Standard executon prefix (e.g. the default sudo -E -u {username})" + ).tag(config=True) + # all these req_foo traits will be available as substvars for templated strings req_queue = Unicode('', \ help="Queue name to submit job to resource manager" @@ -177,7 +181,8 @@ def cmd_formatted_for_batch(self): @gen.coroutine def submit_batch_script(self): subvars = self.get_req_subvars() - cmd = self.batch_submit_cmd.format(**subvars) + cmd = self.exec_prefix + ' ' + self.batch_submit_cmd + cmd = cmd.format(**subvars) subvars['cmd'] = self.cmd_formatted_for_batch() if hasattr(self, 'user_options'): subvars.update(self.user_options) @@ -207,7 +212,8 @@ def read_job_state(self): return self.job_status subvars = self.get_req_subvars() subvars['job_id'] = self.job_id - cmd = self.batch_query_cmd.format(**subvars) + cmd = self.exec_prefix + ' ' + self.batch_query_cmd + cmd = cmd.format(**subvars) self.log.debug('Spawner querying job: ' + cmd) try: out = yield run_command(cmd) @@ -226,7 +232,8 @@ def read_job_state(self): def cancel_batch_job(self): subvars = self.get_req_subvars() subvars['job_id'] = self.job_id - cmd = self.batch_cancel_cmd.format(**subvars) + cmd = self.exec_prefix + ' ' + self.batch_cancel_cmd + cmd = cmd.format(**subvars) self.log.info('Cancelling job ' + self.job_id + ': ' + cmd) yield run_command(cmd) @@ -420,10 +427,10 @@ class TorqueSpawner(BatchSpawnerRegexStates): """).tag(config=True) # outputs job id string - batch_submit_cmd = Unicode('sudo -E -u {username} qsub').tag(config=True) + batch_submit_cmd = Unicode('qsub').tag(config=True) # outputs job data XML string - batch_query_cmd = Unicode('sudo -E -u {username} qstat -x {job_id}').tag(config=True) - batch_cancel_cmd = Unicode('sudo -E -u {username} qdel {job_id}').tag(config=True) + batch_query_cmd = Unicode('qstat -x {job_id}').tag(config=True) + batch_cancel_cmd = Unicode('qdel {job_id}').tag(config=True) # search XML string for job_state - [QH] = pending, R = running, [CE] = done state_pending_re = Unicode(r'[QH]').tag(config=True) state_running_re = Unicode(r'R').tag(config=True) @@ -431,10 +438,10 @@ class TorqueSpawner(BatchSpawnerRegexStates): class MoabSpawner(TorqueSpawner): # outputs job id string - batch_submit_cmd = Unicode('sudo -E -u {username} msub').tag(config=True) + batch_submit_cmd = Unicode('msub').tag(config=True) # outputs job data XML string - batch_query_cmd = Unicode('sudo -E -u {username} mdiag -j {job_id} --xml').tag(config=True) - batch_cancel_cmd = Unicode('sudo -E -u {username} mjobctl -c {job_id}').tag(config=True) + batch_query_cmd = Unicode('mdiag -j {job_id} --xml').tag(config=True) + batch_cancel_cmd = Unicode('mjobctl -c {job_id}').tag(config=True) state_pending_re = Unicode(r'State="Idle"').tag(config=True) state_running_re = Unicode(r'State="Running"').tag(config=True) state_exechost_re = Unicode(r'AllocNodeList="([^\r\n\t\f :"]*)').tag(config=True) @@ -487,10 +494,10 @@ class SlurmSpawner(UserEnvMixin,BatchSpawnerRegexStates): {cmd} """).tag(config=True) # outputs line like "Submitted batch job 209" - batch_submit_cmd = Unicode('sudo -E -u {username} sbatch --parsable').tag(config=True) + batch_submit_cmd = Unicode('sbatch --parsable').tag(config=True) # outputs status and exec node like "RUNNING hostname" - batch_query_cmd = Unicode("sudo -E -u {username} squeue -h -j {job_id} -o '%T %B'").tag(config=True) # - batch_cancel_cmd = Unicode('sudo -E -u {username} scancel {job_id}').tag(config=True) + batch_query_cmd = Unicode("squeue -h -j {job_id} -o '%T %B'").tag(config=True) # + batch_cancel_cmd = Unicode('scancel {job_id}').tag(config=True) # use long-form states: PENDING, CONFIGURING = pending # RUNNING, COMPLETING = running state_pending_re = Unicode(r'^(?:PENDING|CONFIGURING)').tag(config=True) @@ -532,10 +539,10 @@ class GridengineSpawner(BatchSpawnerBase): """).tag(config=True) # outputs job id string - batch_submit_cmd = Unicode('sudo -E -u {username} qsub').tag(config=True) + batch_submit_cmd = Unicode('qsub').tag(config=True) # outputs job data XML string - batch_query_cmd = Unicode('sudo -E -u {username} qstat -xml').tag(config=True) - batch_cancel_cmd = Unicode('sudo -E -u {username} qdel {job_id}').tag(config=True) + batch_query_cmd = Unicode('qstat -xml').tag(config=True) + batch_cancel_cmd = Unicode('qdel {job_id}').tag(config=True) def parse_job_id(self, output): return output.split(' ')[2] @@ -582,10 +589,10 @@ class CondorSpawner(UserEnvMixin,BatchSpawnerRegexStates): """).tag(config=True) # outputs job id string - batch_submit_cmd = Unicode('sudo -E -u {username} condor_submit').tag(config=True) + batch_submit_cmd = Unicode('condor_submit').tag(config=True) # outputs job data XML string batch_query_cmd = Unicode('condor_q {job_id} -format "%s, " JobStatus -format "%s" RemoteHost -format "\n" True').tag(config=True) - batch_cancel_cmd = Unicode('sudo -E -u {username} condor_rm {job_id}').tag(config=True) + batch_cancel_cmd = Unicode('condor_rm {job_id}').tag(config=True) # job status: 1 = pending, 2 = running state_pending_re = Unicode(r'^1,').tag(config=True) state_running_re = Unicode(r'^2,').tag(config=True) @@ -618,9 +625,9 @@ class LsfSpawner(BatchSpawnerBase): ''').tag(config=True) - batch_submit_cmd = Unicode('sudo -E -u {username} bsub').tag(config=True) - batch_query_cmd = Unicode('sudo -E -u {username} bjobs -a -noheader -o "STAT EXEC_HOST" {job_id}').tag(config=True) - batch_cancel_cmd = Unicode('sudo -E -u {username} bkill {job_id}').tag(config=True) + batch_submit_cmd = Unicode('bsub').tag(config=True) + batch_query_cmd = Unicode('bjobs -a -noheader -o "STAT EXEC_HOST" {job_id}').tag(config=True) + batch_cancel_cmd = Unicode('bkill {job_id}').tag(config=True) def get_env(self): env = super().get_env() diff --git a/batchspawner/tests/test_spawners.py b/batchspawner/tests/test_spawners.py index 93460325..57f26303 100644 --- a/batchspawner/tests/test_spawners.py +++ b/batchspawner/tests/test_spawners.py @@ -17,6 +17,7 @@ testjob = "12345" class BatchDummy(BatchSpawnerRegexStates): + exec_prefix = '' batch_submit_cmd = Unicode('cat > /dev/null; echo '+testjob) batch_query_cmd = Unicode('echo RUN '+testhost) batch_cancel_cmd = Unicode('echo STOP')