123 lines
3.1 KiB
Python
123 lines
3.1 KiB
Python
import subprocess
|
|
import threading
|
|
import io
|
|
import json
|
|
import sys
|
|
import os
|
|
import pprint
|
|
import traceback
|
|
import time
|
|
|
|
|
|
def forward(config_dir, config):
|
|
server_address = config['server_address']
|
|
username = config['username']
|
|
target_address = config['target_address']
|
|
blank_endpoint = config['blank_endpoint']
|
|
target_ports = config['target_ports']
|
|
app_name = config['app_name']
|
|
ssh_key = os.path.join(
|
|
config_dir,
|
|
config['ssh_key']
|
|
)
|
|
ssh_command = [
|
|
'ssh',
|
|
'-o', 'ExitOnForwardFailure yes',
|
|
'-o', 'StrictHostKeyChecking no',
|
|
'-o', 'ServerAliveInterval 1',
|
|
'-o', 'ConnectTimeout 1',
|
|
]
|
|
|
|
ports = dict(
|
|
target=[
|
|
*ssh_command,
|
|
'-i', ssh_key,
|
|
'%s@%s' % (username, server_address),
|
|
*sum([
|
|
[
|
|
'-R', '0.0.0.0:%d:%s:%d' % (
|
|
pair[0],
|
|
target_address,
|
|
pair[1],
|
|
)
|
|
]
|
|
for pair in target_ports
|
|
], []),
|
|
'-N'
|
|
],
|
|
blank=[
|
|
*ssh_command,
|
|
'-i', ssh_key,
|
|
'%s@%s' % (username, server_address),
|
|
*sum([
|
|
[
|
|
'-R', '0.0.0.0:%d:%s' % (
|
|
pair[0],
|
|
blank_endpoint,
|
|
)
|
|
]
|
|
for pair in target_ports
|
|
], []),
|
|
'-N'
|
|
]
|
|
)
|
|
|
|
has_server = lambda : subprocess.call([
|
|
'ping','-c', '1', target_address,
|
|
], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) == 0
|
|
|
|
#notify = lambda msg : subprocess.check_output(['notify-send', '-t', '5000', app_name, msg])
|
|
notify = lambda msg: subprocess.call(['echo', app_name, msg])
|
|
|
|
while True:
|
|
notify('started')
|
|
if has_server():
|
|
t6 = 'target'
|
|
notify('has_server')
|
|
else:
|
|
t6 = 'blank'
|
|
notify('blank_app')
|
|
t2 = ports[t6]
|
|
with subprocess.Popen(t2) as p:
|
|
try:
|
|
while True:
|
|
time.sleep(10)
|
|
t3 = has_server()
|
|
t4 = None
|
|
if t6 == 'target' and not t3:
|
|
t4 = 'no server'
|
|
elif t6 == 'blank' and t3:
|
|
t4 = 'server found'
|
|
if not t4 is None:
|
|
notify(t4)
|
|
raise RuntimeError(t4)
|
|
assert p.poll() is None
|
|
except KeyboardInterrupt:
|
|
break
|
|
except:
|
|
pprint.pprint(traceback.format_exc())
|
|
continue
|
|
finally:
|
|
p.terminate()
|
|
notify('stopped')
|
|
|
|
config_path = sys.argv[1]
|
|
config_dir = os.path.split(
|
|
config_path
|
|
)[0]
|
|
|
|
with io.open(config_path, 'r') as f:
|
|
configs = json.load(f)
|
|
|
|
t1 = []
|
|
for config in configs:
|
|
t2 = threading.Thread(
|
|
target=forward,
|
|
args=[config_dir, config],
|
|
)
|
|
t2.start()
|
|
t1.append(t2)
|
|
|
|
for o in t1:
|
|
o.join()
|