1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 1997-2016 California Institute of Technology.
# Copyright (c) 2016-2025 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/pathos/blob/master/LICENSE
"""
connect to the specified machine and start a 'server', 'tunnel', or both
Notes:
Usage: pathos_connect [hostname] [server] [remoteport] [profile]
[hostname] - name of the host to connect to
[server] - name of RPC server (assumes is installed on host) or 'tunnel'
[remoteport] - remote port to use for communication or 'tunnel'
[profile] -- name of shell profile to source on remote environment
Examples::
$ pathos_connect computer.college.edu ppserver tunnel
Usage: pathos_connect [hostname] [server] [remoteport] [profile]
[hostname] - name of the host to connect to
[server] - name of RPC server (assumes is installed on host) or 'tunnel'
[remoteport] - remote port to use for communication or 'tunnel'
[profile] -- name of shell profile to source on remote environment
defaults are: "localhost" "tunnel" "" ""
executing {ssh -N -L 22921:computer.college.edu:15058}'
Server running at port=15058 with pid=4110
Connected to localhost at port=22921
Press <Enter> to kill server
"""
## tunnel: pathos_connect college.edu tunnel
## server: pathos_connect college.edu ppserver 12345 .profile
## both: pathos_connect college.edu ppserver tunnel .profile
from pathos.core import *
from pathos.hosts import get_profile, register_profiles
if __name__ == '__main__':
##### CONFIGURATION & INPUT ########################
# set the default remote host
rhost = 'localhost'
#rhost = 'foobar.internet.org'
#rhost = 'computer.college.edu'
# set any 'special' profiles (those which don't use default_profie)
profiles = {}
#profiles = {'foobar.internet.org':'.profile',
# 'computer.college.edu':'.cshrc'}
# set the default port
rport = ''
_rport = '98909'
# set the default server command
server = 'tunnel'
#server = 'ppserver' #XXX: "ppserver -p %s" % rport
#server = 'classic_server' #XXX: "classic_server -p %s" % rport
#server = 'registry_server' #XXX: "registry_server -p %s" % rport
print("""Usage: pathos_connect [hostname] [remoteport] [server] [profile]
Usage: pathos_connect [hostname] [server] [remoteport] [profile]
[hostname] - name of the host to connect to
[server] - name of RPC server (assumes is installed on host) or 'tunnel'
[remoteport] - remote port to use for communication or 'tunnel'
[profile] -- name of shell profile to source on remote environment
defaults are: "%s" "%s" "%s" "%s".""" % (rhost, server, rport, ''))
# get remote hostname from user
import sys
if '--help' in sys.argv:
sys.exit(0)
try:
myinp = sys.argv[1]
except: myinp = None
if myinp:
rhost = myinp #XXX: should test rhost validity here... (how ?)
else: pass # use default
del myinp
# get server to run from user
try:
myinp = sys.argv[2]
except: myinp = None
if myinp:
server = myinp #XXX: should test validity here... (filename)
else: pass # use default
del myinp
# set the default 'port'
if server == 'tunnel':
tunnel = True
server = None
else:
tunnel = False
rport = rport if tunnel else _rport
# get remote port to run server on from user
try:
myinp = sys.argv[3]
except: myinp = None
if myinp:
if tunnel: # tunnel doesn't take more inputs
msg = "port '%s' not valid for 'tunnel'" % myinp
raise ValueError(msg)
rport = myinp #XXX: should test validity here... (filename)
else: pass # use default
del myinp
# is it a tunneled server?
tunnel = True if (tunnel or rport == 'tunnel') else False
rport = '' if rport == 'tunnel' else rport
# get remote profile (this should go away soon)
try:
myinp = sys.argv[4]
except: myinp = None
if myinp:
rprof = myinp #XXX: should test validity here... (filename)
profiles = {rhost:rprof}
else: pass # use default
del myinp
# my remote environment (should be auto-detected)
register_profiles(profiles)
profile = get_profile(rhost)
##### CONFIGURATION & INPUT ########################
## tunnel: pathos_connect foo.college.edu tunnel
## server: pathos_connect foo.college.edu ppserver 12345 .profile
## both: pathos_connect foo.college.edu ppserver tunnel .profile
if tunnel:
# establish ssh tunnel
tunnel = connect(rhost)
lport = tunnel._lport
rport = tunnel._rport
print('executing {ssh -N -L %d:%s:%d}' % (lport, rhost, rport))
else:
lport = ''
if server:
# run server
rserver = serve(server, rhost, rport, profile=profile)
response = rserver.response()
if response:
if tunnel: tunnel.disconnect()
print(response)
raise OSError('Failure to start server')
# get server pid #FIXME: launcher.pid is not pid(server)
target = '[P,p]ython[^#]*'+server # filter w/ regex for python-based server
try:
pid = getpid(target, rhost)
except OSError:
print("Cleanup on host may be required...")
if tunnel: tunnel.disconnect()
raise
# test server
# XXX: add a simple one-liner...
print("\nServer running at port=%s with pid=%s" % (rport, pid))
if tunnel: print("Connected to localhost at port=%s" % (lport))
print('Press <Enter> to kill server')
else:
print('Press <Enter> to disconnect')
sys.stdin.readline()
if server:
# stop server
print(kill(pid,rhost))
# del rserver #XXX: delete should run self.kill (?)
if tunnel:
# disconnect tunnel
tunnel.disconnect()
# FIXME: just kills 'ssh', not the tunnel
# get local pid: ps u | grep "ssh -N -L%s:%s$s" % (lport,rhost,rport)
# kill -15 int(tunnelpid)
# EOF
|