132 lines
4.6 KiB
Python
132 lines
4.6 KiB
Python
"""Base JobLauncher class
|
|
|
|
This should not be instantiated directly - rather, it should be extended by concrete
|
|
classes.
|
|
|
|
Classes that extend this should provide implementations of run_command_impl and
|
|
run_command_logger_message.
|
|
"""
|
|
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class JobLauncherBase(object):
|
|
"""Base class for job launchers. Not meant to be instantiated directly"""
|
|
|
|
def __init__(
|
|
self,
|
|
queue=None,
|
|
walltime=None,
|
|
account=None,
|
|
required_args=None,
|
|
extra_args=None,
|
|
):
|
|
"""Initialize a job launcher object.
|
|
|
|
Note that some of these arguments (e.g., queue and walltime) aren't needed by some
|
|
job launcher types. They are included in the base class so that users of the class
|
|
can call the getter methods without needing to worry about knowing what type they
|
|
have (e.g., this is used to print default values in help messages; if we're using
|
|
a class that doesn't have a particular value, it might simply print a default of
|
|
'None').
|
|
|
|
For a job launcher type that expects a particular argument (e.g., extra_args): if
|
|
that argument is unneeded in a given instance, use an empty string rather than
|
|
None. None should be reserved for job launcher types that do not reference that
|
|
argument at all.
|
|
|
|
Args:
|
|
queue: str or None
|
|
walltime: str or None
|
|
account: str or None
|
|
required_args: str or None: arguments to the job launcher that cannot be
|
|
overridden by the user
|
|
extra_args: str or None: arguments to the job launcher that can be set or
|
|
overridden by the user
|
|
|
|
(required_args and extra_args are separated so that extra_args can be completely
|
|
replaced without affecting required_args)
|
|
"""
|
|
self._queue = queue
|
|
self._walltime = walltime
|
|
self._account = account
|
|
self._required_args = required_args
|
|
self._extra_args = extra_args
|
|
|
|
def get_queue(self):
|
|
"""Return the queue (str or None)"""
|
|
return self._queue
|
|
|
|
def get_walltime(self):
|
|
"""Return the walltime (str or None)"""
|
|
return self._walltime
|
|
|
|
def get_account(self):
|
|
"""Return the account (str or None)"""
|
|
return self._account
|
|
|
|
def get_required_args(self):
|
|
"""Return the launcher's required arguments (str or None)
|
|
|
|
These are arguments to the job launcher that cannot be overridden by the user
|
|
"""
|
|
return self._required_args
|
|
|
|
def get_extra_args(self):
|
|
"""Return the launcher's extra arguments (str or None)
|
|
|
|
These are arguments to the job launcher that can be set or overridden by the user
|
|
"""
|
|
return self._extra_args
|
|
|
|
def run_command(self, command, stdout_path, stderr_path, dry_run=False):
|
|
"""Run a command with this job launcher.
|
|
|
|
Command should be a list (as is typically passed to subprocess calls)
|
|
|
|
stdout_path and stderr_path are the paths to the files that will hold stdout and
|
|
stderr from the job
|
|
|
|
If dry_run is True, then just print the command to be run without actually running it.
|
|
"""
|
|
logger.info("%s", self.run_command_logger_message(command, stdout_path, stderr_path))
|
|
if not dry_run:
|
|
self.run_command_impl(command, stdout_path, stderr_path)
|
|
|
|
def run_command_impl(self, command, stdout_path, stderr_path):
|
|
"""Actually runs the command
|
|
|
|
stdout_path and stderr_path are the paths to the files that will hold stdout and
|
|
stderr from the job
|
|
|
|
Command should be a list (as is typically passed to subprocess calls)
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
def run_command_logger_message(self, command, stdout_path, stderr_path):
|
|
"""Return a string for output to the log describing the command that will be run
|
|
|
|
stdout_path and stderr_path are the paths to the files that will hold stdout and
|
|
stderr from the job
|
|
|
|
Command should be a list (as is typically passed to subprocess calls)
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
def __repr__(self):
|
|
return (
|
|
type(self).__name__ + "(queue='{queue}', "
|
|
"walltime='{walltime}', "
|
|
"account='{account}', "
|
|
"required_args='{required_args}', "
|
|
"extra_args='{extra_args}')".format(
|
|
queue=self._queue,
|
|
walltime=self._walltime,
|
|
account=self._account,
|
|
required_args=self._required_args,
|
|
extra_args=self._extra_args,
|
|
)
|
|
)
|