def test_errormsg(self): logging.debug('') logging.debug('test_errormsg') cmd = 'dir' if sys.platform == 'win32' else 'ls' try: proc = ShellProc(cmd, stdout='stdout', stderr='stderr') proc.wait() finally: if os.path.exists('stdout'): os.remove('stdout') if os.path.exists('stderr'): os.remove('stderr') msg = proc.error_message(-signal.SIGTERM) if sys.platform == 'win32': self.assertEqual(msg, '') else: self.assertEqual(msg, ': SIGTERM')
def start_server(authkey='PublicKey', address=None, port=0, prefix='server', allowed_hosts=None, allowed_users=None, allow_shell=False, allowed_types=None, timeout=None, tunnel=False, resources=None, log_prefix=None): """ Start an :class:`ObjServerFactory` service in a separate process in the current directory. authkey: string Authorization key, must be matched by clients. address: string IPv4 address, hostname, or pipe name. Default is the host's default IPv4 address. port: int Server port (default of 0 implies next available port). Note that ports below 1024 typically require special privileges. If port is negative, then a local pipe is used for communication. prefix: string Prefix for server config file and stdout/stderr file. allowed_hosts: list(string) Host address patterns to check against. Required if `port` >= 0. Ignored if `allowed_users` is specified. allowed_users: dict Dictionary of users and corresponding public keys allowed access. If None, *any* user may access. If empty, no user may access. The host portions of user strings are used for address patterns. allow_shell: bool If True, :meth:`execute_command` and :meth:`load_model` are allowed. Use with caution! allowed_types: list(string) Names of types which may be created. If None, then allow types listed by :meth:`get_available_types`. If empty, no types are allowed. timeout: int Seconds to wait for server to start. Note that public key generation can take a while. The default value of None will use an internally computed value based on host type (and for Windows, the availability of pyWin32). tunnel: bool If True, report host IP address but listen for connections from a local SSH tunnel. resources: string Filename for resource configuration. log_prefix: string Name used to identify remote remote logging messages from server. Implies that the local process will be receiving the messages. Returns ``(server_proc, config_filename)``. """ if timeout is None: if sys.platform == 'win32' and not HAVE_PYWIN32: #pragma no cover timeout = 120 else: timeout = 30 server_key = prefix+'.key' server_cfg = prefix+'.cfg' server_out = prefix+'.out' for path in (server_cfg, server_out): if os.path.exists(path): os.remove(path) with open(server_key, 'w') as out: out.write('%s\n' % authkey) factory_path = pkg_resources.resource_filename('openmdao.main', 'objserverfactory.py') args = ['python', factory_path, '--port', str(port), '--prefix', prefix] if address is not None: args.extend(['--address', address]) if tunnel: args.append('--tunnel') if resources is not None: args.append('--resources') args.append(resources) if allowed_users is not None: write_authorized_keys(allowed_users, 'users.allow', logging.getLogger()) args.extend(['--users', 'users.allow']) else: args.append('--allow-public') if port >= 0: if allowed_hosts is None: allowed_hosts = [socket.gethostbyname(socket.gethostname())] if allowed_hosts[0].startswith('127.') and \ '127.0.0.1' not in allowed_hosts: allowed_hosts.append('127.0.0.1') 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') else: #pragma no cover logging.warning("Can't make hosts.allow private") if allow_shell: args.append('--allow-shell') if allowed_types is not None: with open('types.allow', 'w') as out: for typname in allowed_types: out.write('%s\n' % typname) if sys.platform != 'win32' or HAVE_PYWIN32: make_private('types.allow') else: #pragma no cover logging.warning("Can't make types.allow private") args.extend(['--types', 'types.allow']) if log_prefix is not None: log_host = socket.gethostname() log_port = logging_port(log_host, log_host) args.extend(['--log-host', log_host, '--log-port', str(log_port)]) if log_prefix: # Could be null (for default). args.extend(['--log-prefix', log_prefix]) proc = ShellProc(args, stdout=server_out, stderr=STDOUT) try: # Wait for valid server_cfg file. retry = 0 while (not os.path.exists(server_cfg)) or \ (os.path.getsize(server_cfg) == 0): return_code = proc.poll() if return_code: error_msg = proc.error_message(return_code) raise RuntimeError('Server startup failed %s' % 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') return (proc, server_cfg) finally: if os.path.exists(server_key): os.remove(server_key)
def start_server(authkey='PublicKey', address=None, port=0, prefix='server', allowed_hosts=None, allowed_users=None, allow_shell=False, allowed_types=None, timeout=None, tunnel=False, resources=None, log_prefix=None): """ Start an :class:`ObjServerFactory` service in a separate process in the current directory. authkey: string Authorization key; must be matched by clients. address: string IPv4 address, hostname, or pipe name. Default is the host's default IPv4 address. port: int Server port (default of 0 implies next available port). Note that ports below 1024 typically require special privileges. If port is negative, then a local pipe is used for communication. prefix: string Prefix for server config file and stdout/stderr file. allowed_hosts: list(string) Host address patterns to check against. Required if `port` >= 0. Ignored if `allowed_users` is specified. allowed_users: dict Dictionary of users and corresponding public keys allowed access. If None, *any* user may access. If empty, no user may access. The host portions of user strings are used for address patterns. allow_shell: bool If True, :meth:`execute_command` and :meth:`load_model` are allowed. Use with caution! allowed_types: list(string) Names of types which may be created. If None, then allow types listed by :meth:`get_available_types`. If empty, no types are allowed. timeout: int Seconds to wait for server to start. Note that public key generation can take a while. The default value of None will use an internally computed value based on host type (and for Windows, the availability of pyWin32). tunnel: bool If True, report host IP address but listen for connections from a local SSH tunnel. resources: string Filename for resource configuration. log_prefix: string Name used to identify remote remote logging messages from server. Implies that the local process will be receiving the messages. Returns ``(server_proc, config_filename)``. """ if timeout is None: if sys.platform == 'win32' and not HAVE_PYWIN32: # pragma no cover timeout = 120 else: timeout = 30 server_key = prefix + '.key' server_cfg = prefix + '.cfg' server_out = prefix + '.out' for path in (server_cfg, server_out): if os.path.exists(path): os.remove(path) with open(server_key, 'w') as out: out.write('%s\n' % authkey) factory_path = pkg_resources.resource_filename('openmdao.main', 'objserverfactory.py') args = ['python', factory_path, '--port', str(port), '--prefix', prefix] if address is not None: args.extend(['--address', address]) if tunnel: args.append('--tunnel') if resources is not None: args.append('--resources') args.append(resources) if allowed_users is not None: write_authorized_keys(allowed_users, 'users.allow', logging.getLogger()) args.extend(['--users', 'users.allow']) else: args.append('--allow-public') if port >= 0: if allowed_hosts is None: allowed_hosts = [socket.gethostbyname(socket.gethostname())] if allowed_hosts[0].startswith('127.') and \ '127.0.0.1' not in allowed_hosts: allowed_hosts.append('127.0.0.1') 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') else: # pragma no cover logging.warning("Can't make hosts.allow private") if allow_shell: args.append('--allow-shell') if allowed_types is not None: with open('types.allow', 'w') as out: for typname in allowed_types: out.write('%s\n' % typname) if sys.platform != 'win32' or HAVE_PYWIN32: make_private('types.allow') else: # pragma no cover logging.warning("Can't make types.allow private") args.extend(['--types', 'types.allow']) if log_prefix is not None: log_host = socket.gethostname() log_port = logging_port(log_host, log_host) args.extend(['--log-host', log_host, '--log-port', str(log_port)]) if log_prefix: # Could be null (for default). args.extend(['--log-prefix', log_prefix]) proc = ShellProc(args, stdout=server_out, stderr=STDOUT) try: # Wait for valid server_cfg file. retry = 0 while (not os.path.exists(server_cfg)) or \ (os.path.getsize(server_cfg) == 0): return_code = proc.poll() if return_code: error_msg = proc.error_message(return_code) raise RuntimeError('Server startup failed %s' % 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') return (proc, server_cfg) finally: if os.path.exists(server_key): os.remove(server_key)