diff --git a/scripts/get_port.py b/scripts/get_port.py index 87fef6d..3f30dd9 100755 --- a/scripts/get_port.py +++ b/scripts/get_port.py @@ -1,28 +1,14 @@ - -import argparse import socket -def main(): - args = parse_arguments() - if args.ip: - print("{} {}".format(port(), ip())) - else: - print(port()) - -def parse_arguments(): - parser = argparse.ArgumentParser() - parser.add_argument("--ip", "-i", - help="Include IP address in output", - action="store_true") - return parser.parse_args() def port(): s = socket.socket() - s.bind(('', 0)) + s.bind(("", 0)) port = s.getsockname()[1] s.close() return port + def ip(address=("8.8.8.8", 80)): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(address) @@ -30,5 +16,6 @@ def ip(address=("8.8.8.8", 80)): s.close() return ip + if __name__ == "__main__": - main() + print(f"{ip()} {port()}") diff --git a/sshspawner/sshspawner.py b/sshspawner/sshspawner.py index 2a0882e..66c36d6 100644 --- a/sshspawner/sshspawner.py +++ b/sshspawner/sshspawner.py @@ -16,6 +16,9 @@ class SSHSpawner(Spawner): # http://traitlets.readthedocs.io/en/stable/migration.html#separation-of-metadata-and-keyword-arguments-in-traittype-contructors # config is an unrecognized keyword + # Change default ip value for SSHSpawners + ip = "0.0.0.0" + remote_hosts = List(trait=Unicode(), help="Possible remote hosts from which to choose remote_host.", config=True) @@ -114,7 +117,7 @@ async def start(self): c = asyncssh.read_certificate(cf) self.remote_host = self.choose_remote_host() - + self.remote_ip, port = await self.remote_random_port() if self.remote_ip is None or port is None or port == 0: return False @@ -149,9 +152,16 @@ async def start(self): for index, value in enumerate(cmd): if value == old: cmd[index] = new + + has_port = False for index, value in enumerate(cmd): if value[0:6] == '--port': cmd[index] = '--port=%d' % (port) + has_port = True + + # Always supply port option! + if not has_port: + cmd.append(f"--port={port}") remote_cmd = ' '.join(cmd) @@ -211,8 +221,8 @@ def _log_remote_ip(self, change): # FIXME this needs to now return IP and port too async def remote_random_port(self): - """Select unoccupied port on the remote host and return it. - + """Select unoccupied port on the remote host and return it. + If this fails for some reason return `None`.""" username = self.get_remote_user(self.user.name) @@ -257,7 +267,7 @@ async def exec_notebook(self, command): for item in env.items(): # item is a (key, value) tuple # command = ('export %s=%s;' % item) + command - bash_script_str += 'export %s=%s\n' % item + bash_script_str += "export %s='%s'\n" % item bash_script_str += 'unset XDG_RUNTIME_DIR\n' bash_script_str += 'touch .jupyter.log\n'