Skip to content

Commit a703c10

Browse files
committed
Check broadcasts for clashing methods of selecting remote hosts:
Do not allow `[remote]host` in broadcast if `platform` is set, or vice-versa.
1 parent d700c11 commit a703c10

File tree

4 files changed

+75
-5
lines changed

4 files changed

+75
-5
lines changed

changes.d/6711.fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Stop broadcast allowing `[remote]host` if `platform` set, or vice-versa

cylc/flow/broadcast_mgr.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
from cylc.flow.exceptions import PointParsingError
3333
from cylc.flow.parsec.util import listjoin, pdeepcopy, poverride
3434
from cylc.flow.parsec.validate import BroadcastConfigValidator
35+
from cylc.flow.platforms import (
36+
fail_if_platform_and_host_conflict,
37+
PlatformLookupError,
38+
)
39+
3540

3641
if TYPE_CHECKING:
3742
from cylc.flow.id import Tokens
@@ -62,9 +67,10 @@ class BroadcastMgr:
6267

6368
REC_SECTION = re.compile(r"\[([^\]]+)\]")
6469

65-
def __init__(self, workflow_db_mgr, data_store_mgr):
66-
self.workflow_db_mgr = workflow_db_mgr
67-
self.data_store_mgr = data_store_mgr
70+
def __init__(self, schd):
71+
self.schd = schd
72+
self.workflow_db_mgr = schd.workflow_db_mgr
73+
self.data_store_mgr = schd.data_store_mgr
6874
self.linearized_ancestors = {}
6975
self.broadcasts = {}
7076
self.ext_triggers = {} # Can use collections.Counter in future
@@ -304,6 +310,14 @@ def put_broadcast(
304310
if namespace not in self.linearized_ancestors:
305311
bad_namespaces.append(namespace)
306312
elif not bad_point:
313+
self.check_for_old_and_new_platform_settings(
314+
self.schd.config.get_config(
315+
['runtime', namespace]
316+
).copy(),
317+
namespace,
318+
coerced_setting,
319+
)
320+
307321
if namespace not in self.broadcasts[point_string]:
308322
self.broadcasts[point_string][namespace] = {}
309323

@@ -332,6 +346,21 @@ def put_broadcast(
332346
self.data_store_mgr.delta_broadcast()
333347
return modified_settings, bad_options
334348

349+
@staticmethod
350+
def check_for_old_and_new_platform_settings(
351+
task_config, namespace, coerced_setting
352+
):
353+
"""Check for combination of old ([remote]host) and new (platform)
354+
settings in the task config as it will be after merger.
355+
"""
356+
task_config.update(coerced_setting)
357+
try:
358+
fail_if_platform_and_host_conflict(
359+
task_config, namespace
360+
)
361+
except PlatformLookupError as exc:
362+
LOG.error('Cannot apply broadcast:\n' + '\n '.join(exc.args))
363+
335364
@staticmethod
336365
def _cancel_keys_in_prunes(prunes, cancel_keys):
337366
"""Is cancel_keys pruned?"""

cylc/flow/scheduler.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,7 @@ async def initialise(self):
402402
403403
"""
404404
self.data_store_mgr = DataStoreMgr(self)
405-
self.broadcast_mgr = BroadcastMgr(
406-
self.workflow_db_mgr, self.data_store_mgr)
405+
self.broadcast_mgr = BroadcastMgr(self)
407406

408407
self.server = WorkflowRuntimeServer(self)
409408

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# THIS FILE IS PART OF THE CYLC WORKFLOW ENGINE.
2+
# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
3+
#
4+
# This program is free software: you can redistribute it and/or modify
5+
# it under the terms of the GNU General Public License as published by
6+
# the Free Software Foundation, either version 3 of the License, or
7+
# (at your option) any later version.
8+
#
9+
# This program is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
"""Tests for Broadcast Manager."""
18+
19+
20+
async def test_reject_invalid_broadcast_is_remote_clash(
21+
one_conf, flow, start, scheduler, log_filter
22+
):
23+
"""`put_broadcast` gracefully rejects invalid broadcast:
24+
25+
Existing config = [task][remote]host = foo
26+
Broadcast = [task]platform = bar
27+
28+
https://github.com/cylc/cylc-flow/issues/6693
29+
"""
30+
conf = one_conf.copy()
31+
conf.update({'runtime': {'root': {'platform': 'foo'}}})
32+
wid = flow(conf)
33+
schd = scheduler(wid)
34+
async with start(schd):
35+
bc_mgr = schd.broadcast_mgr
36+
bc_mgr.put_broadcast(
37+
point_strings=['1'],
38+
namespaces=['one'],
39+
settings=[{'remote': {'host': 'bar'}}]
40+
)
41+
assert log_filter(contains='Cannot apply broadcast')

0 commit comments

Comments
 (0)