diff --git a/d1/forward.py b/d1/forward.py index 4fc36bf..0a3ebc2 100644 --- a/d1/forward.py +++ b/d1/forward.py @@ -1,4 +1,5 @@ import subprocess +import threading import io import json import sys @@ -8,86 +9,114 @@ import traceback import time -with io.open(sys.argv[1], 'r') as f: - config = json.load(f) - -server_address = config['server_address'] -username = config['username'] -target_address = config['target_address'] -blank_endpoint = config['blank_endpoint'] -target_ports = config['target_ports'] - -ports = dict( - target=r''' - ssh \ - %s@%s \ - %s \ - -v -N; - ''' % ( - username, - server_address, - ' '.join([ - '-R 0.0.0.0:%d:%s:%d' % ( - pair[0], - target_address, - pair[1], - ) - for pair in target_ports - ]), - ), - blank=r''' - ssh \ - %s@%s \ - %s \ - -v -N; - ''' % ( - username, - server_address, - ' '.join([ - '-R 0.0.0.0:%d:%s' % ( - pair[0], - blank_endpoint, - ) - for pair in target_ports - ]), +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"' -app_name = config['app_name'] -has_server = lambda : subprocess.call([ - 'ping','-c', '1', target_address, -]) == 0 + ports = dict( + target=r''' + %s -i %s \ + %s@%s \ + %s \ + -N; + ''' % ( + ssh_command, + ssh_key, + username, + server_address, + ' '.join([ + '-R 0.0.0.0:%d:%s:%d' % ( + pair[0], + target_address, + pair[1], + ) + for pair in target_ports + ]), + ), + blank=r''' + %s -i %s \ + %s@%s \ + %s \ + -N; + ''' % ( + ssh_command, + ssh_key, + username, + server_address, + ' '.join([ + '-R 0.0.0.0:%d:%s' % ( + pair[0], + blank_endpoint, + ) + for pair in target_ports + ]), + ) + ) -notify = lambda msg : subprocess.check_output(['notify-send', '-t', '5000', app_name, msg]) + has_server = lambda : subprocess.call([ + 'ping','-c', '1', target_address, + ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) == 0 -while True: - notify('started') - if has_server(): - t6 = ports['target'] - notify('has_server') - else: - t6 = ports['blank'] - notify('blank_app') - t2 = t6 - with subprocess.Popen(t2, shell=True) as p: - try: - while True: - time.sleep(10) - t3 = has_server() - t4 = None - if t6 == ports['target'] and not t3: - t4 = 'no server' - elif t6 == ports['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') + #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 = ports['target'] + notify('has_server') + else: + t6 = ports['blank'] + notify('blank_app') + t2 = t6 + with subprocess.Popen(t2, shell=True) as p: + try: + while True: + time.sleep(10) + t3 = has_server() + t4 = None + if t6 == ports['target'] and not t3: + t4 = 'no server' + elif t6 == ports['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() diff --git a/docker-compose.yml b/docker-compose.yml index 79d8e9c..d4d2865 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,8 +4,14 @@ services: build: context: . dockerfile: ./docker/blank-app/Dockerfile - ports: - - 80:80 volumes: - .:/app:rw restart: always + forward: + build: + context: . + dockerfile: ./docker/forward/Dockerfile + volumes: + - ./d1/forward.py:/app/d1/forward.py:ro + - ./tmp/cache/forward_data:/app/tmp/cache/forward_data:ro + restart: always diff --git a/docker/forward/Dockerfile b/docker/forward/Dockerfile new file mode 100644 index 0000000..0008749 --- /dev/null +++ b/docker/forward/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3 +WORKDIR /app +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get install -y iputils-ping +ENTRYPOINT sh -c ' \ + python d1/forward.py tmp/cache/forward_data/forward.config.json \ +'