Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes.d/6848.fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allow `flow.cylc[runtime][<task>]platform` setting to have a prefix/suffix around a subshell expression.
1 change: 1 addition & 0 deletions cylc/flow/cfgspec/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,7 @@ def get_script_common_text(this: str, example: Optional[str] = None):

# run a command to select the platform (or platform group):
platform = $(select-platform)
platform = prefix-$(select-platform)-suffix

.. versionadded:: 8.0.0
''')
Expand Down
2 changes: 1 addition & 1 deletion cylc/flow/platforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

# Regex to check whether a string is a command
HOST_REC_COMMAND = re.compile(r'(`|\$\()\s*(.*)\s*([`)])$')
PLATFORM_REC_COMMAND = re.compile(r'(\$\()\s*(.*)\s*([)])$')
PLATFORM_REC_COMMAND = re.compile(r'(\$\()\s*(.*)\s*(\))')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor] can prevent this first group from being captured using ?::

Suggested change
PLATFORM_REC_COMMAND = re.compile(r'(\$\()\s*(.*)\s*(\))')
PLATFORM_REC_COMMAND = re.compile(r'(?:\$\()\s*(.*)\s*(\))')


HOST_SELECTION_METHODS = {
'definition order': lambda goodhosts: goodhosts[0],
Expand Down
7 changes: 4 additions & 3 deletions cylc/flow/task_remote_mgr.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,18 @@ def _subshell_eval(
return 'localhost'

# Host selection command: $(command) or `command`
match = command_pattern.match(eval_str)
match = command_pattern.search(eval_str)
if match:
cmd_str = match.groups()[1]
cmd_str = match.group(2)
if cmd_str in self.remote_command_map:
# Command recently launched
value = self.remote_command_map[cmd_str]
if isinstance(value, PlatformError):
raise value # command failed
if value is None:
return None # command not yet ready
eval_str = value # command succeeded
# command succeeded
eval_str = eval_str.replace(match.group(0), value)
else:
# Command not launched (or already reset)
self.proc_pool.put_command(
Expand Down
14 changes: 9 additions & 5 deletions tests/functional/job-submission/19-platform_select.t
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#-------------------------------------------------------------------------------
# Test recovery of a failed host select command for a group of tasks.
. "$(dirname "$0")/test_header"
set_test_number 6
set_test_number 7

install_workflow "${TEST_NAME_BASE}"

Expand All @@ -29,20 +29,24 @@ logfile="${WORKFLOW_RUN_DIR}/log/scheduler/log"

# Check that host = $(cmd) is correctly evaluated
grep_ok \
"1/host_subshell.* evaluated as improbable host name$" \
"1/host_subshell/01:.* evaluated as improbable host name$" \
"${logfile}"
grep_ok \
"1/localhost_subshell.* evaluated as localhost$" \
"1/localhost_subshell/01:.* evaluated as localhost$" \
"${logfile}"

# Check that host = `cmd` is correctly evaluated
grep_ok \
"1/host_subshell_backticks.* evaluated as improbable host name$" \
"1/host_subshell_backticks/01:.* evaluated as improbable host name$" \
"${logfile}"

# Check that platform = $(cmd) correctly evaluated
grep_ok \
"1/platform_subshell.* evaluated as improbable platform name$" \
"1/platform_subshell:.* evaluated as improbable platform name$" \
"${logfile}"

grep_ok \
"1/platform_subshell_suffix:.* evaluated as prefix-middle-suffix$" \
"${logfile}"

purge
18 changes: 8 additions & 10 deletions tests/functional/job-submission/19-platform_select/flow.cylc
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ purpose = """
R1 = """
host_no_subshell
localhost_subshell
platform_subshell:submit-fail? => fin_platform
platform_no_subshell:submit-fail? => fin_platform
host_subshell:submit-fail? => fin_host
host_subshell_backticks:submit-fail? => fin_host
platform_subshell:submit-fail?
platform_no_subshell:submit-fail?
platform_subshell_suffix:submit-fail?
host_subshell:submit-fail?
host_subshell_backticks:submit-fail?
"""

[runtime]
Expand All @@ -35,6 +36,9 @@ purpose = """
[[platform_subshell]]
platform = $(echo "improbable platform name")

[[platform_subshell_suffix]]
platform = prefix-$( echo middle )-suffix

[[host_subshell]]
[[[remote]]]
host = $(echo "improbable host name")
Expand All @@ -46,9 +50,3 @@ purpose = """
[[localhost_subshell]]
[[[remote]]]
host = $(echo "localhost4.localdomain4")

[[fin_platform]]
script = cylc remove "${CYLC_WORKFLOW_ID}//1/platform_*"

[[fin_host]]
script = cylc remove "${CYLC_WORKFLOW_ID}//1/host_subshell*"
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@
1/host_subshell -triggered off [] in flow 1
1/host_subshell_backticks -triggered off [] in flow 1
1/localhost_subshell -triggered off [] in flow 1
1/fin_platform -triggered off ['1/platform_no_subshell', '1/platform_subshell'] in flow 1
1/fin_host -triggered off ['1/host_subshell', '1/host_subshell_backticks'] in flow 1
1/platform_subshell_suffix -triggered off [] in flow 1
1 change: 1 addition & 0 deletions tests/unit/test_platforms_get_platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ def test_get_platform_groups_basic(mock_glbl_cfg):
'task_conf, expected_err_msg',
[
({'platform': '$(host)'}, None),
({'platform': '$(host)-suffix'}, None),
({'platform': '`echo ${chamber}`'}, "backticks are not supported")
]
)
Expand Down
Loading