def _start_tunnel(address, port, args, user, identity, prefix): """ Start an ssh tunnel process. """ if '@' in address: user, host = address.split('@') else: user = user or getpass.getuser() host = address if sys.platform == 'win32': # pragma no cover cmd = ['plink', '-batch', '-ssh'] else: cmd = ['ssh'] cmd += ['-l', user] if identity: cmd += ['-i', identity] cmd += ['-N', '-x', '-T'] # plink doesn't support '-n' (no stdin) cmd += args + [host] logname = '%s-%s-%s.log' % (prefix, host, port) logname = os.path.join(os.getcwd(), logname) stdout = open(logname, 'w') tunnel_proc = None try: tunnel_proc = ShellProc(cmd, stdout=stdout, stderr=STDOUT) except Exception as exc: raise RuntimeError("Can't create ssh tunnel process from %s: %s" % (cmd, exc)) time.sleep(1) exitcode = tunnel_proc.poll() if exitcode is not None: raise RuntimeError('ssh tunnel process for %s:%s exited with exitcode' ' %d, output in %s' % (address, port, exitcode, logname)) return (_cleanup_tunnel, tunnel_proc, stdout, logname, os.getpid())
def start_server(address='localhost', port=None, allowed_hosts=None, debug=False, server_out=None, args=()): """ Start server process at `address` and `port`. Returns ``(proc, port)``. address: string Server address to be used. port: int Server port to be used. Use zero for a system-selected port. allowed_hosts: list[string] Hosts to allow access. If None then ``['127.0.0.1', socket.gethostname()]`` is used. debug: bool Set logging level to ``DEBUG``, default is ``INFO``. args: iter of str Other command line args to pass to server. """ if port is None: port = get_open_address()[1] if allowed_hosts is None: allowed_hosts = ['127.0.0.1', socket.gethostname()] with open('hosts.allow', 'w') as out: for pattern in allowed_hosts: out.write('%s\n' % pattern) if sys.platform != 'win32' or HAVE_PYWIN32: make_private('hosts.allow') server_path = os.path.splitext(os.path.abspath(__file__))[0]+'.py' if server_out is None: server_out = 'as-%d.out' % port server_up = 'as-%d.up' % port if os.path.exists(server_up): os.remove(server_up) # Start process. args = [sys.executable, server_path, '-d', '--address', address, '--port', '%d' % port, '--up', server_up] + args if debug: args.append('--debug') logging.info("start_server: args=%s" % args) #print("starting ShellProc:",args) proc = ShellProc(args, stdout=server_out, stderr=STDOUT) # Wait for valid server_up file. timeout = 30 # Seconds. retry = 0 while (not os.path.exists(server_up)) or \ (os.path.getsize(server_up) == 0): return_code = proc.poll() if return_code: error_msg = proc.error_message(return_code) raise RuntimeError('Server startup failed: exit code %s (%s)' % (return_code, error_msg)) retry += 1 if retry < 10*timeout: time.sleep(.1) # Hard to cause a startup timeout. else: # pragma no cover proc.terminate(timeout) raise RuntimeError('Server startup timeout') # Read server information. with open(server_up, 'r') as inp: host = inp.readline().strip() port = int(inp.readline().strip()) pid = int(inp.readline().strip()) os.remove(server_up) return (proc, port)