Skip to content

Commit f3777c6

Browse files
authored
Merge pull request #512 from minrk/sshproxy
Fixes and tests for SSHProxy
2 parents c429c0b + 2652468 commit f3777c6

File tree

3 files changed

+75
-16
lines changed

3 files changed

+75
-16
lines changed

ipyparallel/cluster/app.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import re
1111
import signal
1212
import sys
13+
from functools import partial
1314

1415
import zmq
1516
from IPython.core.profiledir import ProfileDir
@@ -308,18 +309,39 @@ def init_cluster(self):
308309

309310
def init_signal(self):
310311
# Setup signals
312+
for signame in ("SIGUSR1", "SIGUSR2", "SIGINFO"):
313+
try:
314+
signum = getattr(signal, signame)
315+
except AttributeError:
316+
self.log.debug(f"Not forwarding {signame}")
317+
pass
318+
else:
319+
self.log.debug(f"Forwarding {signame} to engines")
320+
signal.signal(signum, self.relay_signal)
311321
signal.signal(signal.SIGINT, self.sigint_handler)
322+
signal.signal(signal.SIGTERM, self.sigint_handler)
323+
324+
def relay_signal(self, signum, frame):
325+
self.log.debug(f"Received signal {signum} received, relaying to engines...")
326+
self.loop.add_callback_from_signal(partial(self.cluster.signal_engines, signum))
327+
328+
def sigint_handler(self, signum, frame):
329+
return self.relay_signal(signum, frame)
330+
331+
def sigterm_handler(self, signum, frame):
332+
self.log.debug(f"Received signal {signum} received, stopping launchers...")
333+
self.loop.add_callback_from_signal(self.stop_cluster)
312334

313335
def engines_started_ok(self):
314336
self.log.info("Engines appear to have started successfully")
315337
self.early_shutdown = 0
316338

317339
async def start_engines(self):
318340
try:
319-
await self.cluster.start_engines(self.n)
341+
await self.cluster.start_engines()
320342
except:
321343
self.log.exception("Engine start failed")
322-
raise
344+
self.exit(1)
323345

324346
if self.daemonize:
325347
self.loop.add_callback(self.loop.stop)
@@ -374,10 +396,6 @@ async def stop_cluster(self, r=None):
374396
await self.cluster.stop_cluster()
375397
self.loop.add_callback(self.loop.stop)
376398

377-
def sigint_handler(self, signum, frame):
378-
self.log.debug("SIGINT received, stopping launchers...")
379-
self.loop.add_callback_from_signal(self.stop_cluster)
380-
381399
def start_logging(self):
382400
# Remove old log files of the controller and engine
383401
if self.clean_logs:
@@ -463,6 +481,11 @@ def controller_stopped(self, stop_data):
463481
self.log.warning("Controller stopped. Shutting down.")
464482
self.loop.add_callback(self.stop_cluster)
465483

484+
def sigint_handler(self, signum, frame):
485+
"""Unlike engines, SIGINT shuts down `ipcluster start`"""
486+
self.log.debug(f"Received signal {signum} received, stopping launchers...")
487+
self.loop.add_callback_from_signal(self.stop_cluster)
488+
466489
def start(self):
467490
"""Start the app for the start subcommand."""
468491
# First see if the cluster is already running

ipyparallel/cluster/launcher.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,26 @@ def start(self, hostname=None, user=None, port=None):
967967
self.scp_args.append('-P')
968968
self.scp_args.append(str(port))
969969

970+
# create remote profile dir
971+
check_output(
972+
self.ssh_cmd
973+
+ self.ssh_args
974+
+ [
975+
self.location,
976+
shlex_join(
977+
[
978+
self.remote_python,
979+
"-m",
980+
"IPython",
981+
"profile",
982+
"create",
983+
"--profile-dir",
984+
self.remote_profile_dir,
985+
]
986+
),
987+
],
988+
input=None,
989+
)
970990
self.send_files()
971991
self.pid = sshx(
972992
self.ssh_cmd + self.ssh_args + [self.location],
@@ -1192,7 +1212,17 @@ class SSHProxyEngineSetLauncher(SSHLauncher):
11921212
"""
11931213

11941214
n = Integer().tag(to_dict=True)
1195-
ipcluster_cmd = List(['ipcluster'], config=True)
1215+
ipcluster_cmd = List(Unicode(), config=True)
1216+
1217+
@default("ipcluster_cmd")
1218+
def _default_ipcluster_cmd(self):
1219+
return [self.remote_python, "-m", "ipyparallel.cluster"]
1220+
1221+
ipcluster_args = List(
1222+
Unicode(),
1223+
config=True,
1224+
help="""Extra CLI arguments to pass to ipcluster engines""",
1225+
)
11961226

11971227
@property
11981228
def program(self):
@@ -1207,7 +1237,7 @@ def program_args(self):
12071237
self.remote_profile_dir,
12081238
'--cluster-id',
12091239
self.cluster_id,
1210-
]
1240+
] + self.ipcluster_args
12111241

12121242
@default("to_send")
12131243
def _to_send_default(self):

ipyparallel/tests/test_ssh.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,29 @@
1212
# import tests that use engine_launcher_class fixture
1313

1414

15-
@pytest.fixture
16-
def ssh_config(ssh_key):
15+
@pytest.fixture(params=["SSH", "SSHProxy"])
16+
def ssh_config(ssh_key, request):
1717
c = Config()
1818
c.Cluster.controller_ip = '0.0.0.0'
19-
c.Cluster.engine_launcher_class = 'SSH'
20-
c.SSHEngineSetLauncher.scp_args = c.SSHLauncher.ssh_args = [
19+
c.Cluster.engine_launcher_class = request.param
20+
engine_set_cfg = c[f"{request.param}EngineSetLauncher"]
21+
engine_set_cfg.ssh_args = [
2122
"-o",
2223
"UserKnownHostsFile=/dev/null",
2324
"-o",
2425
"StrictHostKeyChecking=no",
2526
"-i",
2627
ssh_key,
2728
]
29+
engine_set_cfg.scp_args = list(engine_set_cfg.ssh_args) # copy
30+
engine_set_cfg.remote_python = "/opt/conda/bin/python3"
31+
engine_set_cfg.remote_profile_dir = "/home/ciuser/.ipython/profile_default"
32+
engine_set_cfg.engine_args = ['--debug']
33+
c.SSHProxyEngineSetLauncher.hostname = "127.0.0.1"
34+
c.SSHProxyEngineSetLauncher.ssh_args.append("-p2222")
35+
c.SSHProxyEngineSetLauncher.scp_args.append("-P2222")
36+
c.SSHProxyEngineSetLauncher.user = "ciuser"
2837
c.SSHEngineSetLauncher.engines = {"[email protected]:2222": 4}
29-
c.SSHEngineSetLauncher.remote_python = "/opt/conda/bin/python3"
30-
c.SSHEngineSetLauncher.remote_profile_dir = "/home/ciuser/.ipython/profile_default"
31-
c.SSHEngineSetLauncher.engine_args = ['--debug']
3238
return c
3339

3440

@@ -41,4 +47,4 @@ def Cluster(ssh_config, BaseCluster): # noqa: F811
4147
# override engine_launcher_class
4248
@pytest.fixture
4349
def engine_launcher_class(ssh_config):
44-
return 'SSH'
50+
return ssh_config.Cluster.engine_launcher_class

0 commit comments

Comments
 (0)