From fbe27016f7028fa4980d5c49014c99f8b961bf92 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Sun, 17 Aug 2014 18:43:54 -0400 Subject: [PATCH] Dynamic destinations - pass job_conf.xml params to rule functions. In other words, send extra job destination parameters to dynamic rule functions as arguments (in addition to those dynamically populated by Galaxy itself). This enables greater parameterization of rule functions and should lead to cleaner separation of logic and data (i.e. sites can program rules that restrict access to users, but which users can be populated at a higher level in `job_conf.xml`). For example the following dynamic job rule: def cluster1(app, memory="4096", cores="1", hours="48"): native_spec = "--time=%s:00:00 --nodes=1 --ntasks=%s --mem=%s" % ( hours, cores, memory ) return JobDestination( "cluster1", params=dict( native_specification=native_spec ) ) Could then be called with various parameters in job_conf.xml as follows: cluster1 1 cluster1 8 32768 --- lib/galaxy/jobs/mapper.py | 13 +++++++++---- test/unit/jobs/test_mapper.py | 6 ++++++ test/unit/jobs/test_rules/10_site.py | 5 +++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/galaxy/jobs/mapper.py b/lib/galaxy/jobs/mapper.py index 62c30c61914..fa51fb4a547 100644 --- a/lib/galaxy/jobs/mapper.py +++ b/lib/galaxy/jobs/mapper.py @@ -69,7 +69,7 @@ class JobRunnerMapper( object ): names.append( rule_module_name ) return names - def __invoke_expand_function( self, expand_function ): + def __invoke_expand_function( self, expand_function, destination_params ): function_arg_names = inspect.getargspec( expand_function ).args app = self.job_wrapper.app possible_args = { @@ -83,6 +83,11 @@ class JobRunnerMapper( object ): actual_args = {} + # Send through any job_conf.xml defined args to function + for destination_param in destination_params.keys(): + if destination_param in function_arg_names: + actual_args[ destination_param ] = destination_params[ destination_param ] + # Populate needed args for possible_arg_name in possible_args: if possible_arg_name in function_arg_names: @@ -179,12 +184,12 @@ class JobRunnerMapper( object ): raise Exception( message ) expand_function = self.__get_expand_function( expand_function_name ) - return self.__handle_rule( expand_function ) + return self.__handle_rule( expand_function, destination ) else: raise Exception( "Unhandled dynamic job runner type specified - %s" % expand_type ) - def __handle_rule( self, rule_function ): - job_destination = self.__invoke_expand_function( rule_function ) + def __handle_rule( self, rule_function, destination ): + job_destination = self.__invoke_expand_function( rule_function, destination.params ) if not isinstance(job_destination, galaxy.jobs.JobDestination): job_destination_rep = str(job_destination) # Should be either id or url if '://' in job_destination_rep: diff --git a/test/unit/jobs/test_mapper.py b/test/unit/jobs/test_mapper.py index 73bf03f049d..f0a00ff1bc6 100644 --- a/test/unit/jobs/test_mapper.py +++ b/test/unit/jobs/test_mapper.py @@ -46,6 +46,12 @@ def test_dynamic_mapping_defaults_to_tool_id_as_rule(): assert mapper.job_config.rule_response == "tool1_dest_id" +def test_dynamic_mapping_job_conf_params(): + mapper = __mapper( __dynamic_destination( dict( function="check_job_conf_params", param1="7" ) ) ) + assert mapper.get_job_destination( {} ) is DYNAMICALLY_GENERATED_DESTINATION + assert mapper.job_config.rule_response == "sent_7_dest_id" + + def test_dynamic_mapping_function_parameters(): mapper = __mapper( __dynamic_destination( dict( function="check_rule_params" ) ) ) assert mapper.get_job_destination( {} ) is DYNAMICALLY_GENERATED_DESTINATION diff --git a/test/unit/jobs/test_rules/10_site.py b/test/unit/jobs/test_rules/10_site.py index 5f9d558a7f8..779d4edbdd1 100644 --- a/test/unit/jobs/test_rules/10_site.py +++ b/test/unit/jobs/test_rules/10_site.py @@ -40,6 +40,11 @@ def check_rule_params( return "all_passed" +def check_job_conf_params( param1 ): + assert param1 == "7" + return "sent_7_dest_id" + + def check_resource_params( resource_params ): assert resource_params["memory"] == "8gb" return "have_resource_params"