mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-21 13:50:20 +08:00
Introduce strict shell command option.
Newer tool formats (CWL and YAML just enable this by default), but XML tools can add a strict="true" to the command block to force "set -e" handling on the shell part of tool execution. Run the framework tests verifying the new and older default behavior using the following commands: ``` ./run_tests.sh -framework -id strict_shell_default_off ./run_tests.sh -framework -id strict_shell ```
This commit is contained in:
@@ -793,6 +793,10 @@ class JobWrapper( object ):
|
||||
def shell(self):
|
||||
return self.job_destination.shell or getattr(self.app.config, 'default_job_shell', DEFAULT_JOB_SHELL)
|
||||
|
||||
@property
|
||||
def strict_shell(self):
|
||||
return self.tool.strict_shell
|
||||
|
||||
@property
|
||||
def commands_in_new_shell(self):
|
||||
return self.app.config.commands_in_new_shell
|
||||
|
||||
@@ -87,7 +87,15 @@ def __externalize_commands(job_wrapper, shell, commands_builder, remote_command_
|
||||
integrity_injection = ""
|
||||
if check_script_integrity(config):
|
||||
integrity_injection = INTEGRITY_INJECTION
|
||||
script_contents = u"#!%s\n%s%s" % (shell, integrity_injection, tool_commands)
|
||||
set_e = ""
|
||||
if job_wrapper.strict_shell:
|
||||
set_e = "set -e\n"
|
||||
script_contents = u"#!%s\n%s%s%s" % (
|
||||
shell,
|
||||
integrity_injection,
|
||||
set_e,
|
||||
tool_commands
|
||||
)
|
||||
write_script(local_container_script, script_contents, config)
|
||||
commands = local_container_script
|
||||
if 'working_directory' in remote_command_params:
|
||||
|
||||
@@ -562,6 +562,9 @@ class Tool( object, Dictifiable ):
|
||||
|
||||
# Parse result handling for tool exit codes and stdout/stderr messages:
|
||||
self.parse_stdio( tool_source )
|
||||
|
||||
self.strict_shell = tool_source.parse_strict_shell()
|
||||
|
||||
# Any extra generated config files for the tool
|
||||
self.__parse_config_files(tool_source)
|
||||
# Action
|
||||
|
||||
@@ -61,6 +61,9 @@ class CwlToolSource(ToolSource):
|
||||
def parse_help(self):
|
||||
return ""
|
||||
|
||||
def parse_strict_shell(self):
|
||||
return True
|
||||
|
||||
def parse_stdio(self):
|
||||
# TODO: remove duplication with YAML
|
||||
from galaxy.jobs.error_level import StdioErrorLevel
|
||||
|
||||
@@ -139,6 +139,12 @@ class ToolSource(object):
|
||||
dictionaries for use by Tool.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def parse_strict_shell(self):
|
||||
""" Return True if tool commands should be executed with
|
||||
set -e.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def parse_stdio(self):
|
||||
""" Builds lists of ToolStdioExitCode and ToolStdioRegex objects
|
||||
|
||||
@@ -281,6 +281,13 @@ class XmlToolSource(ToolSource):
|
||||
parser = StdioParser(self.root)
|
||||
return parser.stdio_exit_codes, parser.stdio_regexes
|
||||
|
||||
def parse_strict_shell(self):
|
||||
command_el = self._command_el
|
||||
if command_el is not None:
|
||||
return string_as_bool(command_el.get("strict", "False"))
|
||||
else:
|
||||
return False
|
||||
|
||||
def parse_help(self):
|
||||
help_elem = self.root.find( 'help' )
|
||||
return help_elem.text if help_elem is not None else None
|
||||
|
||||
@@ -64,6 +64,10 @@ class YamlToolSource(ToolSource):
|
||||
page_source = YamlPageSource(self.root_dict.get("inputs", {}))
|
||||
return PagesSource([page_source])
|
||||
|
||||
def parse_strict_shell(self):
|
||||
# TODO: Add ability to disable this.
|
||||
return True
|
||||
|
||||
def parse_stdio(self):
|
||||
return error_on_exit_code()
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
<tool file="metadata.xml" />
|
||||
<tool file="metadata_bam.xml" />
|
||||
<tool file="metadata_bcf.xml" />
|
||||
<tool file="strict_shell.xml" />
|
||||
<tool file="strict_shell_default_off.xml" />
|
||||
<tool file="detect_errors_aggressive.xml" />
|
||||
<tool file="md5sum.xml" />
|
||||
<!--
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<tool id="strict_shell" name="strict_shell" version="1.0.0">
|
||||
<command strict="true" detect_errors="exit_code">
|
||||
echo "Hello" > $out_file1
|
||||
; sh -c "exit $exit_code"
|
||||
; sh -c "exit 0"
|
||||
</command>
|
||||
<inputs>
|
||||
<param name="exit_code" type="integer" value="0" label="exit code"/>
|
||||
</inputs>
|
||||
<outputs>
|
||||
<data name="out_file1" />
|
||||
</outputs>
|
||||
<tests>
|
||||
<test expect_exit_code="0" expect_failure="false">
|
||||
<param name="exit_code" value="0" />
|
||||
</test>
|
||||
<test expect_exit_code="1" expect_failure="true">
|
||||
<param name="exit_code" value="1" />
|
||||
</test>
|
||||
</tests>
|
||||
<help>
|
||||
</help>
|
||||
</tool>
|
||||
@@ -0,0 +1,20 @@
|
||||
<tool id="strict_shell_default_off" name="strict_shell_default_off" version="1.0.0">
|
||||
<command detect_errors="exit_code">
|
||||
echo "Hello" > $out_file1
|
||||
; sh -c "exit $exit_code"
|
||||
; sh -c "exit 0"
|
||||
</command>
|
||||
<inputs>
|
||||
<param name="exit_code" type="integer" value="0" label="exit code"/>
|
||||
</inputs>
|
||||
<outputs>
|
||||
<data name="out_file1" />
|
||||
</outputs>
|
||||
<tests>
|
||||
<test expect_exit_code="0" expect_failure="false">
|
||||
<param name="exit_code" value="1" />
|
||||
</test>
|
||||
</tests>
|
||||
<help>
|
||||
</help>
|
||||
</tool>
|
||||
@@ -155,6 +155,7 @@ class TestCommandFactory(TestCase):
|
||||
class MockJobWrapper(object):
|
||||
|
||||
def __init__(self, job_dir):
|
||||
self.strict_shell = False
|
||||
self.write_version_cmd = None
|
||||
self.command_line = MOCK_COMMAND_LINE
|
||||
self.dependency_shell_commands = []
|
||||
|
||||
Reference in New Issue
Block a user