def __init__(self, name='', devices=(), backdoor=None): self.name = name self._log = logging.getLogger('{0}.{1}'.format(_log.name, name)) self._log.info('Bootstraping server') if backdoor: from gevent.backdoor import BackdoorServer banner = 'Welcome to Bliss emulator server console.\n' \ 'My name is {0!r}. You can access me through the ' \ '\'server()\' function. Have fun!'.format(name) self.backdoor = BackdoorServer( backdoor, banner=banner, locals=dict(server=weakref.ref(self))) self.backdoor.start() self._log.info('Backdoor opened at %r', backdoor) else: self._log.info('no backdoor declared') self.devices = {} for device in devices: try: self.create_device(device) except Exception as error: dname = device.get('name', device.get('class', 'unknown')) self._log.error( 'error creating device %s (will not be available): %s', dname, error) self._log.debug('details: %s', error, exc_info=1)
def __init__(self, addr, *args, **kwargs): if self.__class__.__instance is not None: raise RuntimeError( 'only one backdoor server allowed to be running') self.addr = addr self.server = BackdoorServer(addr) Greenlet.__init__(self, *args, **kwargs)
def start_backdoor(self): self.backdoor_server = BackdoorServer( ('127.0.0.1', 9999), banner='DebugService backdoor server', locals={'dispatcher': self.dispatcher}) gevent.spawn(self.backdoor_server.serve_forever)
class ServeBackdoor(Greenlet): __instance = None def __init__(self, addr, *args, **kwargs): if self.__class__.__instance is not None: raise RuntimeError( 'only one backdoor server allowed to be running') self.addr = addr self.server = BackdoorServer(addr) Greenlet.__init__(self, *args, **kwargs) @classmethod def get_instance(cls): return cls.__instance # pylint: disable=E0202 def _run(self): cls = self.__class__ try: cls.__instance = self logger.info("starting backdoor server on %r...", self.addr) self.server.serve_forever() finally: logger.info('backdoor server on %r stopped', self.addr) cls.__instance = None
def start_backdoor(self, backlog=50): """Start a backdoor server on a local UNIX domain socket. """ backdoor_path = self.get_backdoor_path() try: os.remove(backdoor_path) except OSError as error: if error.errno != errno.ENOENT: raise else: logger.warning("A backdoor socket has been found and deleted.") mkdir(os.path.dirname(backdoor_path)) backdoor_sock = gevent.socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) backdoor_sock.setblocking(0) backdoor_sock.bind(backdoor_path) user = pwd.getpwnam(config.cmsuser) # We would like to also set the user to "cmsuser" but only root # can do that. Therefore we limit ourselves to the group. os.chown(backdoor_path, os.getuid(), user.pw_gid) os.chmod(backdoor_path, 0o770) backdoor_sock.listen(backlog) self.backdoor = BackdoorServer(backdoor_sock, locals={'service': self}) self.backdoor.start()
def main(): global context global app parser = argparse.ArgumentParser() parser.add_argument("-p", "--pid-file", help="location to write process ID", required=False) args = parser.parse_args() if args.pid_file is not None: with open(args.pid_file, "w") as pid_file: pid_file.write(str(os.getpid()) + "\n") app = create_app() #from . import emergency # we do this late so app is available for import with app.app_context(): try: backdoor = BackdoorServer( ('127.0.0.1', app.config["BACKEND_BACKDOOR_SERVER_PORT"]), locals=locals()) backdoor.start() server() except KeyboardInterrupt as e: l.debug("shutting down")
def __init__(self, devices=(), backdoor=None): self._log = _log self._log.info("Bootstraping server") if backdoor: from gevent.backdoor import BackdoorServer banner = ("Welcome to Simulator server console.\n" "You can access me through the " "'server()' function. Have fun!") self.backdoor = BackdoorServer( backdoor, banner=banner, locals=dict(server=weakref.ref(self))) self.backdoor.start() self._log.info("Backdoor opened at %r", backdoor) else: self._log.info("no backdoor declared") self.devices = {} for device in devices: try: self.create_device(device) except Exception as error: dname = device.get("name", device.get("class", "unknown")) self._log.error( "error creating device %s (will not be available): %s", dname, error) self._log.debug("details: %s", error, exc_info=1)
class Warpgate(object): def init(self): import options from UnityEngine import Debug L = lambda s: Debug.Log("PyWrap: " + s) L("init") self.events = [] # should set them options.no_update options.show_hidden_mode options.freeplay = False if options.no_update: import autoupdate autoupdate.Autoupdate = autoupdate.DummyAutoupdate L("before gevent") from gevent import monkey monkey.patch_socket() monkey.patch_os() monkey.patch_select() L("after gevent") from game import autoenv autoenv.init('Client') import thb.ui.ui_meta # noqa, init ui_meta from client.core.executive import Executive self.executive = ExecutiveWrapper(Executive, self) def get_events(self): l = self.events self.events = [] return l def start_backdoor(self): from gevent.backdoor import BackdoorServer import gevent self.bds = BackdoorServer(('127.0.0.1', 12345)) self.gr_bds = gevent.spawn(self.bds.serve_forever) def stop_backdoor(self): self.gr_bds.kill() self.bds.close() def shutdown(self): from client.core.executive import Executive if Executive.state == 'connected': Executive.disconnect() def queue_system_event(self, evt_name, arg=None): self.events.append(('system_event', evt_name, arg))
def startbackdoor(host=None, port=8998): if get_config('DONT_USE_GEVENT'): raise('Backdoor is not available') if host is None: host=HOST from gevent.backdoor import BackdoorServer print('Backdoor is on %s:%s' % (host, port)) bs = BackdoorServer((host, port), locals()) bs.start()
def start_server(self, host='localhost', port=None): "Start a server on HOST and PORT." assert port is not None if self.where is not None: self.stop_server() self.where = host, port log.info("Installing backdoor on %s, port %d.", host, port) from gevent.backdoor import BackdoorServer server = BackdoorServer(self.where) server.start()
def start_backdoor(self): if not self.gevent: raise RpcException(errno.ENOTSUP, 'Not supported') from gevent import spawn from gevent.backdoor import BackdoorServer self.backdoor_server = BackdoorServer( ('127.0.0.1', 9999), banner='DebugService backdoor server', locals=self.backdoor_locals) spawn(self.backdoor_server.serve_forever())
def backdoor(self): self.logger.debug('Spawning Backdoor Greenlet') self.logger.warning( "The backdoor server should be used for dev purposes only!") if self.config.backdoor_host == "0.0.0.0": self.logger.warning( "Backdoor server should never bind to 0.0.0.0! This is extremely dangerous!" ) server = BackdoorServer( (self.config.backdoor_host, self.config.backdoor_port), locals={'bot': self}) server.serve_forever()
class BackdoorPlugin(BotPlugin): name = 'backdoor' defaults = { 'port': 1234, } def init(self): self.server = BackdoorServer(('localhost', self.config.port), locals={ 'clients': clients, }) self.server.start() def cleanup(self): super(BackdoorPlugin, self).cleanup() self.server.stop()
def run(self, auto_join=False): """ Runs Dissonance, loading all the modules, starting the web service, and starting the adapter. If auto_join=True, this function will not return, and will run until dissonance stops if starting dissonance from outside of a greenlet. """ if self.running: raise RuntimeError("Dissonance is already running!") logger.info("Starting Dissonance v%s", self.version) logger.info("Starting storage %s", self._storage) self._storage.start() logger.info("Loading modules") self.modules.load_all() if getattr(self.config, 'web', False) or str( self._opts.get('web', False)).upper() == 'TRUE': self._web = Web( self, EnvFallbackDict('web', getattr(self.config, 'web_opts', {}))) self._web.start() if getattr(self.config, 'manhole', False): from gevent.backdoor import BackdoorServer manhole_opts = EnvFallbackDict( 'manhole', getattr(self.config, 'manhole_opts', {})) self._manhole = BackdoorServer( (manhole_opts.get('listen_host', '127.0.0.1'), int(manhole_opts.get('listen_port', 9001))), locals={'client': self.client}) self._manhole.start() logger.info("Attempting to log in as %s" % self._opts['email']) self.client.login(self._opts['email'], self._opts['password']) logger.info("Starting connection to Discord") self.client.start() self._storage_sync_periodic.start(right_away=False) self._stop_event.clear() # If we are the main greenlet, chances are we probably want to never return, # so the main greenlet won't exit, and tear down everything with it. if auto_join and gevent.get_hub().parent == gevent.getcurrent(): self.join()
def __init__(self, name='', devices=(), backdoor=None): self.name = name self._log = logging.getLogger('{0}.{1}'.format(_log.name, name)) self._log.info('Bootstraping server') if backdoor: from gevent.backdoor import BackdoorServer banner = 'Welcome to Bliss emulator server console.\n' \ 'My name is {0!r}. You can access me through the ' \ '\'server()\' function. Have fun!'.format(name) self.backdoor = BackdoorServer(backdoor, banner=banner, locals=dict(server=weakref.ref(self))) self.backdoor.start() self._log.info('Backdoor opened at %r', backdoor) else: self._log.info('no backdoor declared') self.devices = {} for device in devices: try: self.create_device(device) except Exception as error: dname = device.get('name', device.get('class', 'unknown')) self._log.error('error creating device %s (will not be available): %s', dname, error) self._log.debug('details: %s', error, exc_info=1)
def run(self): from gevent.server import StreamServer from gevent.pywsgi import WSGIServer from gevent.backdoor import BackdoorServer import gm.app # NOQA from gm.init_app import application import settings as st # wait for proxy self.ping_proxy() threads = [] logger.info('listening 0.0.0.0:%d', st.WORLD['port']) self.mainServer = StreamServer(('0.0.0.0', st.WORLD['port']), self.handle_client) threads.append(Greenlet.spawn(self.mainServer.serve_forever)) logger.info('listening %s:%d', st.WORLD['managehost'], st.WORLD['manageport']) threads.append( Greenlet.spawn( WSGIServer((st.WORLD['managehost'], st.WORLD['manageport']), application, spawn=pool.Pool(10)).serve_forever)) if os.environ.get("DOCKER_MANAGEHOST"): backdoorhost = "0.0.0.0" else: backdoorhost = "127.0.0.1" logger.info('listening %s:%d', backdoorhost, st.WORLD['backdoorport']) threads.append( Greenlet.spawn( BackdoorServer( (backdoorhost, st.WORLD['backdoorport'])).serve_forever)) # start cron thread import cron_settings # NOQA threads.append(Greenlet.spawn(self.heart_beat)) joinall(threads)
def main(): parser = argparse.ArgumentParser('aya') parser.add_argument('--dbc-username') parser.add_argument('--dbc-password') parser.add_argument('--bearybot') parser.add_argument('--upyun-bucket') parser.add_argument('--upyun-username') parser.add_argument('--upyun-password') parser.add_argument('--redis-url', default='redis://*****:*****@sentry.thbattle.net/4' ) State.options = options = parser.parse_args() utils.logging.init_server(logging.DEBUG, options.sentry, 'aya-1.0', 'aya.log', with_gr_name=False) db.session.init(options.db) gevent.spawn(BackdoorServer(('127.0.0.1', 11111)).serve_forever) def loop(): State.aya = Aya() # State.aya.wait_ready() State.interconnect = AyaInterconnect.spawn('aya', options.redis_url) State.dao = AyaDAO(options.redis_url) State.aya.join() gevent.spawn(loop).join() gevent.sleep(10) # for sentry
def run(self): container = create_container(self.config) install_plugins(container, self.config.get('plugins', {})) install_interfaces(container, self.config.get('interfaces', {})) for cls_name in self.args.get('--interface', ()): cls = import_object(cls_name) container.install(cls) if self.args.get('--debug'): from gevent.backdoor import BackdoorServer backdoor = BackdoorServer(('127.0.0.1', 5005), locals={'container': container}) gevent.spawn(backdoor.serve_forever) def handle_signal(): logger.info('caught SIGINT/SIGTERM, pid=%s', os.getpid()) container.stop() container.join() sys.exit(0) gevent.signal(signal.SIGINT, handle_signal) gevent.signal(signal.SIGTERM, handle_signal) setproctitle('lymph-instance (identity: %s, endpoint: %s, config: %s)' % ( container.identity, container.endpoint, self.config.source, )) container.start(register=not self.args.get('--isolated', False)) if self.args.get('--reload'): set_source_change_callback(container.stop) container.join()
def main(): global interconnect, aya logging.basicConfig(level=logging.DEBUG) gevent.spawn(BackdoorServer(('127.0.0.1', 11111)).serve_forever) aya = Aya() # aya.wait_ready() interconnect = AyaInterconnect.spawn('aya', options.redis_url) aya.join()
def start_backdoor(self): self.backdoor_server = BackdoorServer( ('127.0.0.1', 9999), banner='DebugService backdoor server', locals={ 'dispatcher': self.dispatcher } ) gevent.spawn(self.backdoor_server.serve_forever)
def handle_run(args): store = Storage(args.root) transport = Transport(args.listen) node = LogicNode(transport.endpoint(), store) if args.backdoor: from gevent.backdoor import BackdoorServer BackdoorServer(('127.0.0.1', args.backdoor), banner="Hello from gevent backdoor!", locals={ 'node': node }).start() gevent.wait()
def start_server(): def _exit_handler(*a, **k): gevent.kill(MAIN, SystemExit) sig(signal.SIGTERM, _exit_handler) from game import autoenv import argparse parser = argparse.ArgumentParser(prog=sys.argv[0]) parser.add_argument('node', type=str) parser.add_argument('--host', default='0.0.0.0', type=str) parser.add_argument('--port', default=9999, type=int) parser.add_argument('--backdoor-host', default='127.0.0.1', type=str) parser.add_argument('--backdoor-port', default=19999, type=int) parser.add_argument('--no-backdoor', action='store_true') parser.add_argument('--freeplay', action='store_true') parser.add_argument('--log', default='INFO') parser.add_argument('--logfile', default='') parser.add_argument('--gidfile', default='') parser.add_argument('--credit-multiplier', type=float, default=1) parser.add_argument('--no-counting-flee', action='store_true') parser.add_argument('--archive-path', default='') parser.add_argument('--interconnect', action='store_true', default=False) parser.add_argument('--redis-url', default='redis://localhost:6379') parser.add_argument('--discuz-authkey', default='Proton rocks') parser.add_argument('--db', default='sqlite:////dev/shm/thb.sqlite3') options = parser.parse_args() import options as opmodule opmodule.options = options import db.session db.session.init(options.db) autoenv.init('Server') import settings utils.logging.init_server(getattr(logging, options.log.upper()), settings.SENTRY_DSN, settings.VERSION, options.logfile) if not options.no_backdoor: from gevent.backdoor import BackdoorServer gevent.spawn(BackdoorServer((options.backdoor_host, options.backdoor_port)).serve_forever) from server.core import Client root = logging.getLogger() root.info('=' * 20 + settings.VERSION + '=' * 20) server = StreamServer((options.host, options.port), Client.serve, None) server.serve_forever()
def init_device(self): Device.init_device(self) self.debug_stream("In init_device() of controller") self.group_dict = {} if self.BackdoorPort: print "Starting Backdoor server on port", self.BackdoorPort server = BackdoorServer(('127.0.0.1', self.BackdoorPort), banner="BlissAxisManager back door", locals={'axis_manager': self}) gevent.spawn(server.serve_forever) self.__backdoor_server = server else: print " no backdoor"
def start_backdoor(self): if not self.gevent: raise RpcException(errno.ENOTSUP, 'Not supported') from gevent import spawn from gevent.backdoor import BackdoorServer self.backdoor_server = BackdoorServer( ('127.0.0.1', 9999), banner='DebugService backdoor server', locals=self.backdoor_locals ) spawn(self.backdoor_server.serve_forever())
def run(self, auto_join=False): """ Runs Dissonance, loading all the modules, starting the web service, and starting the adapter. If auto_join=True, this function will not return, and will run until dissonance stops if starting dissonance from outside of a greenlet. """ if self.running: raise RuntimeError("Dissonance is already running!") logger.info("Starting Dissonance v%s", self.version) logger.info("Starting storage %s", self._storage) self._storage.start() logger.info("Loading modules") self.modules.load_all() if getattr(self.config, 'web', False) or str(self._opts.get('web', False)).upper() == 'TRUE': self._web = Web(self, EnvFallbackDict('web', getattr(self.config, 'web_opts', {}))) self._web.start() if getattr(self.config, 'manhole', False): from gevent.backdoor import BackdoorServer manhole_opts = EnvFallbackDict('manhole', getattr(self.config, 'manhole_opts', {})) self._manhole = BackdoorServer(( manhole_opts.get('listen_host', '127.0.0.1'), int(manhole_opts.get('listen_port', 9001)) ), locals={ 'client': self.client }) self._manhole.start() logger.info("Attempting to log in as %s" % self._opts['email']) self.client.login(self._opts['email'], self._opts['password']) logger.info("Starting connection to Discord") self.client.start() self._storage_sync_periodic.start(right_away=False) self._stop_event.clear() # If we are the main greenlet, chances are we probably want to never return, # so the main greenlet won't exit, and tear down everything with it. if auto_join and gevent.get_hub().parent == gevent.getcurrent(): self.join()
def _start_backdoor_terminal(self): # XXX(Mouad): Imported here since this is still broken in Python3.x from gevent.backdoor import BackdoorServer try: ip = self.config.get_raw('debug.backdoor_ip') except KeyError: ip = '127.0.0.1' port = get_unused_port() endpoint = '%s:%s' % (ip, port) banner = "Welcome to backdoor Terminal of %s" % self.container.service_name backdoor = BackdoorServer( endpoint, locals={'container': self.container, 'dump_stacks': dump_stacks}, banner=banner) gevent.spawn(backdoor.serve_forever) self.container.backdoor_endpoint = endpoint
def get_backdoor_server(self, listen_addr, **context): """Add a backdoor (debug) server.""" from django.conf import settings local_vars = { 'launcher': self, 'servers': self.servers, 'pgworker': self.pgworker, 'stop': self.stop, 'api': self.api, 'resource': self.resource, 'settings': settings, 'wsgi_app': self.wsgi_app, 'wsgi_name': self.wsgi_name, } local_vars.update(context) return BackdoorServer( listen_addr, banner='Django DDP', locals=local_vars, )
def start_backdoor(self, backlog=50): """Start a backdoor server on a local UNIX domain socket. """ backdoor_path = self.get_backdoor_path() try: os.remove(backdoor_path) except OSError as error: if error.errno != errno.ENOENT: raise else: logger.warning("A backdoor socket has been found and deleted.") mkdir(os.path.dirname(backdoor_path)) backdoor_sock = _socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) backdoor_sock.setblocking(0) backdoor_sock.bind(backdoor_path) user = pwd.getpwnam("cmsuser") # We would like to also set the user to "cmsuser" but only root # can do that. Therefore we limit ourselves to the group. os.chown(backdoor_path, os.getuid(), user.pw_gid) os.chmod(backdoor_path, 0o770) backdoor_sock.listen(backlog) self.backdoor = BackdoorServer(backdoor_sock, locals={'service': self}) self.backdoor.start()
class DebugService(RpcService): def __init__(self, gevent=False, builtins=None): self.gevent = gevent self.backdoor_locals = builtins or {} self.backdoor_server = None @private def attach(self, host, port): import pydevd pydevd.settrace(host, port=port, stdoutToServer=True, stderrToServer=True) @private def detach(self): import pydevd pydevd.stoptrace() @private def dump_stacks(self): if self.gevent: from greenlet import greenlet # If greenlet is present, let's dump each greenlet stack dump = [] for ob in gc.get_objects(): if not isinstance(ob, greenlet): continue if not ob: continue # not running anymore or not started dump.append(''.join(traceback.format_stack(ob.gr_frame))) return dump else: dump = [] for frame in list(sys._current_frames().values()): dump.append(''.join(traceback.format_stack(frame))) return dump @private def start_backdoor(self): if not self.gevent: raise RpcException(errno.ENOTSUP, 'Not supported') from gevent import spawn from gevent.backdoor import BackdoorServer self.backdoor_server = BackdoorServer( ('127.0.0.1', 9999), banner='DebugService backdoor server', locals=self.backdoor_locals ) spawn(self.backdoor_server.serve_forever()) @private def stop_backdoor(self): if not self.gevent: raise RpcException(errno.ENOTSUP, 'Not supported') if self.backdoor_server: self.backdoor_server.close() self.backdoor_server = None
(rec.msg, rec.args)), ) fmter = ServerLogFormatter() root = logging.getLogger() root.setLevel(getattr(logging, options.log.upper())) std = logging.StreamHandler(stream=sys.stdout) std.setFormatter(fmter) root.handlers = [] root.addHandler(std) if options.logfile: from logging.handlers import WatchedFileHandler filehdlr = WatchedFileHandler(options.logfile) filehdlr.setFormatter(fmter) root.addHandler(filehdlr) if not options.no_backdoor: from gevent.backdoor import BackdoorServer gevent.spawn( BackdoorServer(('127.0.0.1', options.backdoor_port)).serve_forever) from server.core import Client root.info('=' * 20 + settings.VERSION + '=' * 20) server = StreamServer(('0.0.0.0', options.port), Client.spawn, None) server.serve_forever()
self.msg(user.nick, "Yahoo answers cannot answer %r" % match.group(1)) self.msg(user.nick, "Try: \"Does napping make you smarter?\"") else: self.msg(user.nick, "Can't understand your command: \"%s\"" % message) if __name__ == '__main__': from girclib.helpers import setup_logging setup_logging(level=5) client = YahooAnswerBot('irc.freenode.net', 6667, 'girclib', 'gIRClib') # Just for the fun, start telnet backdoor on port 2000 from gevent.backdoor import BackdoorServer server = BackdoorServer(('127.0.0.1', 2000), locals=locals()) server.start() @signals.on_signed_on.connect def _on_motd(emitter): log.info("Signed on. Let's join #ufs") client.join("#ufs") @signals.on_disconnected.connect def disconnected(emitter): log.info("Exited!?") try: gevent.shutdown() except AssertionError: # Shutting down is only possible from MAIN greenlet pass
import gevent.monkey from gevent.wsgi import WSGIServer from gevent.backdoor import BackdoorServer from webservice import app from ircservice import irc gevent.monkey.patch_all() backdoor = BackdoorServer(('127.0.0.1',18080)) backdoor.start() irc.init() http_server = WSGIServer(('', 8000), app) http_server.serve_forever()
class DebugService(RpcService): def __init__(self): super(DebugService, self).__init__() self.dispatcher = None self.backdoor_server = None def initialize(self, context): self.dispatcher = context.dispatcher @private def dump_stacks(self): from greenlet import greenlet # If greenlet is present, let's dump each greenlet stack dump = [] for ob in gc.get_objects(): if not isinstance(ob, greenlet): continue if not ob: continue # not running anymore or not started dump.append(''.join(traceback.format_stack(ob.gr_frame))) return dump @private def attach(self, host, port): sys.path.append('/usr/local/lib/dispatcher/pydev') import pydevd pydevd.settrace(host, port=port, stdoutToServer=True, stderrToServer=True) @private def detach(self): import pydevd pydevd.stoptrace() @private def set_tasks_debug(self, host, port, tasks=None): self.dispatcher.balancer.debugger = (host, port) self.dispatcher.balancer.debugged_tasks = tasks or ['*'] @private def cancel_tasks_debug(self): self.dispatcher.balancer.debugger = None self.dispatcher.balancer.debugged_tasks = None @private def start_backdoor(self): self.backdoor_server = BackdoorServer( ('127.0.0.1', 9999), banner='DebugService backdoor server', locals={ 'dispatcher': self.dispatcher } ) gevent.spawn(self.backdoor_server.serve_forever) @private def stop_backdoor(self): if self.backdoor_server: self.backdoor_server.close() self.backdoor_server = None @private def start_tracemalloc(self): tracemalloc.start() @private def stop_tracemalloc(self): tracemalloc.stop() @private def snapshot_tracemalloc(self): snap = tracemalloc.take_snapshot() return [str(i) for i in snap.statistics('lineno')[:100]]
def init(self): self.server = BackdoorServer(('localhost', self.config.port), locals={ 'clients': clients, }) self.server.start()
def main(stdscr, *args, **kwargs): global answer, feedback, candidates gevent.signal(signal.SIGUSR1, lambda *args: game_close.set()) # For standard/graceful restart # gevent.signal(signal.SIGINT, lambda *args: None) # Disable SIGINT # signal.signal(signal.SIGQUIT, signal.SIG_IGN) # Disable SIGQUIT # signal.signal(signal.SIGTSTP, signal.SIG_IGN) # Disable SIGTSTP logging.info("Window bounds: %s", stdscr.getmaxyx()) backdoor = BackdoorServer(('0.0.0.0', 4200)) backdoor.start() logging.info("Backdoor started") curses.curs_set(0) # Cursor invisible stdscr.nodelay(1) # Nonblocking input MAXY, MAXX = stdscr.getmaxyx() curses.init_pair(PAIR_MAIN, *DEFAULT_COLORS) curses.init_pair(PAIR_AI, curses.COLOR_RED, curses.COLOR_BLACK) curses.init_pair(PAIR_FEEDBACK, curses.COLOR_WHITE, curses.COLOR_BLACK) curses.init_pair(PAIR_TAGGED, curses.COLOR_YELLOW, curses.COLOR_BLACK) rightscr = stdscr.subwin(0, SPLIT) leftscr = stdscr.subwin(VERTSPLIT, SPLIT, 0, 0) logging.info("Right screen from %s, size %s", rightscr.getbegyx(), rightscr.getmaxyx()) logging.info("Left screen from %s, size %s", leftscr.getbegyx(), leftscr.getmaxyx()) feedback = SlowtypeWindow((VERTSPLIT, 1), (MAXY - VERTSPLIT - 1, SPLIT - 1)) answer = random.choice(get_words(WORDS_PATH)) candidates = get_closest(answer, WORDS_PATH, NUM_CANDIDATES - 1) + [answer] shuffle_main(leftscr, candidates) g_key_handler = spawn(key_handler, stdscr, leftscr) first_key.wait() g_chatter = spawn(timed_chat, rightscr, MAXY - 2) won = game_win_state.get() do_ai_fast.set() ai_done.wait() g_key_handler.kill() g_chatter.kill() feedback.wait() if not won: end(stdscr, "LOSS") attr = curses.color_pair(PAIR_MAIN) leftscr.move(0,0) leftscr.clear() leftscr.addstr("""WARNING Experiment 203 (Synthetic Reasoning, Combat) has breached containment. Please select a course of action. (1) Isolate system and scrub disks (This will destroy all research on Experiment 203) (2) Release remaining locks, allow experiment full access to base (MAY BE DANGEROUS) (3) Activate Emergency Base Procedure XK-682 """, attr) leftscr.refresh() first = True while 1: c = gevent_getch(sys.stdin, stdscr) if c == ord('1'): end(stdscr, "DESTROY") elif c == ord('2'): end(stdscr, "RELEASE") elif c == ord('3') and first: first = False logging.info("User attempted to arm the nukes") n = 3 leftscr.addstr("Arming nuclear warheads.\nActivation in ", attr) y,x = leftscr.getyx() for i in range(n, -1, -1): leftscr.move(y,x) leftscr.addstr("%d seconds..." % i, attr) leftscr.refresh() gevent.sleep(1) leftscr.addstr("\nERROR\nYou do not have security permissions\n to perform this action.", attr) leftscr.refresh()
class Service(object): def __init__(self, shard=0): signal.signal(signal.SIGINT, lambda unused_x, unused_y: self.exit()) self.name = self.__class__.__name__ self.shard = shard self._my_coord = ServiceCoord(self.name, self.shard) # Dictionaries of (to be) connected RemoteServiceClients. self.remote_services = {} self.initialize_logging() # We setup the listening address for services which want to # connect with us. try: address = get_service_address(self._my_coord) except KeyError: raise ConfigError("Unable to find address for service %r. " "Is it specified in core_services in cms.conf?" % (self._my_coord,)) self.rpc_server = StreamServer(address, self._connection_handler) self.backdoor = None def initialize_logging(self): """Set up additional logging handlers. What we do, in detail, is to add a logger to file (whose filename depends on the coords) and a remote logger to a LogService. We also attach the service coords to all log messages. """ filter_ = ServiceFilter(self.name, self.shard) # Update shell handler to attach service coords. shell_handler.addFilter(filter_) # Determine location of log file, and make directories. log_dir = os.path.join(config.log_dir, "%s-%d" % (self.name, self.shard)) mkdir(config.log_dir) mkdir(log_dir) log_filename = "%d.log" % int(time.time()) # Install a file handler. file_handler = FileHandler(os.path.join(log_dir, log_filename), mode='w', encoding='utf-8') if config.file_log_debug: file_log_level = logging.DEBUG else: file_log_level = logging.INFO file_handler.setLevel(file_log_level) file_handler.setFormatter(CustomFormatter(False)) file_handler.addFilter(filter_) root_logger.addHandler(file_handler) # Provide a symlink to the latest log file. try: os.remove(os.path.join(log_dir, "last.log")) except OSError: pass os.symlink(log_filename, os.path.join(log_dir, "last.log")) # Setup a remote LogService handler (except when we already are # LogService, to avoid circular logging). if self.name != "LogService": log_service = self.connect_to(ServiceCoord("LogService", 0)) remote_handler = LogServiceHandler(log_service) remote_handler.setLevel(logging.INFO) remote_handler.addFilter(filter_) root_logger.addHandler(remote_handler) def _connection_handler(self, sock, address): """Receive and act upon an incoming connection. A new RemoteServiceServer is spawned to take care of the new connection. """ try: ipaddr, port = address ipaddr = gevent.socket.gethostbyname(ipaddr) address = Address(ipaddr, port) except socket.error: logger.warning("Unexpected error.", exc_info=True) return remote_service = RemoteServiceServer(self, address) remote_service.handle(sock) def connect_to(self, coord, on_connect=None, on_disconnect=None, must_be_present=True): """Return a proxy to a remote service. Obtain a communication channel to the remote service at the given coord (reusing an existing one, if possible), attach the on_connect and on_disconnect handlers and return it. coord (ServiceCoord): the coord of the service to connect to. on_connect (function|None): to be called when the service connects. on_disconnect (function|None): to be called when it disconnects. must_be_present (bool): if True, the coord must be present in the configuration; otherwise, it can be missing and in that case the return value is a fake client (that is, a client that never connects and ignores all calls). return (RemoteServiceClient): a proxy to that service. """ if coord not in self.remote_services: try: service = RemoteServiceClient(coord, auto_retry=0.5) except KeyError: # The coordinates are invalid: raise a ConfigError if # the service was needed, or return a dummy client if # the service was optional. if must_be_present: raise ConfigError("Missing address and port for %s " "in cms.conf." % (coord, )) else: service = FakeRemoteServiceClient(coord, None) service.connect() self.remote_services[coord] = service else: service = self.remote_services[coord] if on_connect is not None: service.add_on_connect_handler(on_connect) return service def add_timeout(self, func, plus, seconds, immediately=False): """Register a function to be called repeatedly. func (function): the function to call. plus (object): additional data to pass to the function. seconds (float): the minimum interval between successive calls (may be larger if a call doesn't return on time). immediately (bool): whether to call right off or wait also before the first call. """ if plus is None: plus = {} func = functools.partial(func, **plus) if immediately: gevent.spawn(repeater, func, seconds) else: gevent.spawn_later(seconds, repeater, func, seconds) def exit(self): """Terminate the service at the next step. """ logger.warning("%r received request to shut down.", self._my_coord) self.rpc_server.stop() def get_backdoor_path(self): """Return the path for a UNIX domain socket to use as backdoor. """ return os.path.join(config.run_dir, "%s_%d" % (self.name, self.shard)) @rpc_method def start_backdoor(self, backlog=50): """Start a backdoor server on a local UNIX domain socket. """ backdoor_path = self.get_backdoor_path() try: os.remove(backdoor_path) except OSError as error: if error.errno != errno.ENOENT: raise else: logger.warning("A backdoor socket has been found and deleted.") mkdir(os.path.dirname(backdoor_path)) backdoor_sock = _socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) backdoor_sock.setblocking(0) backdoor_sock.bind(backdoor_path) user = pwd.getpwnam("cmsuser") # We would like to also set the user to "cmsuser" but only root # can do that. Therefore we limit ourselves to the group. os.chown(backdoor_path, os.getuid(), user.pw_gid) os.chmod(backdoor_path, 0o770) backdoor_sock.listen(backlog) self.backdoor = BackdoorServer(backdoor_sock, locals={'service': self}) self.backdoor.start() @rpc_method def stop_backdoor(self): """Stop a backdoor server started by start_backdoor. """ if self.backdoor is not None: self.backdoor.stop() backdoor_path = self.get_backdoor_path() try: os.remove(backdoor_path) except OSError as error: if error.errno != errno.ENOENT: raise def run(self): """Starts the main loop of the service. return (bool): True if successful. """ try: self.rpc_server.start() # This must come before socket.error, because socket.gaierror # extends socket.error except socket.gaierror: logger.critical("Service %s could not listen on " "specified address, because it cannot " "be resolved.", self.name) return False except socket.error as error: if error.errno == errno.EADDRINUSE: logger.critical("Listening port %s for service %s is " "already in use, quitting.", self.rpc_server.address.port, self.name) return False elif error.errno == errno.EADDRNOTAVAIL: logger.critical("Service %s could not listen on " "specified address, because it is not " "available.", self.name) return False else: raise if config.backdoor: self.start_backdoor() logger.info("%s %d up and running!", *self._my_coord) # This call will block until self.rpc_server.stop() is called. self.rpc_server.serve_forever() logger.info("%s %d is shutting down", *self._my_coord) if config.backdoor: self.stop_backdoor() self._disconnect_all() return True def _disconnect_all(self): """Disconnect all remote services. """ for service in self.remote_services.itervalues(): if service.connected: service.disconnect() @rpc_method def echo(self, string): """Simple RPC method. string (string): the string to be echoed. return (string): string, again. """ return string @rpc_method def quit(self, reason=""): """Shut down the service reason (string): why, oh why, you want me down? """ logger.info("Trying to exit as asked by another service (%s).", reason) self.exit()
def start_backdoor(self): from gevent.backdoor import BackdoorServer import gevent self.bds = BackdoorServer(('127.0.0.1', 12345)) self.gr_bds = gevent.spawn(self.bds.serve_forever)
class Dissonance(object): _name = None _web = None _manhole = None def __init__(self, config): opts_for = lambda name: EnvFallbackDict(name, getattr(config, '%s_opts' % name, {})) self._opts = EnvFallbackDict(None, getattr(config, 'dissonance_opts', {})) storage_class = get_storage_by_name(self._opts.get('storage', getattr(config, 'storage', 'shelve'))) self.config = config self.client = Client() self._storage = storage_class(self, opts_for('storage')) self.modules = Modules(self) self._storage_sync_periodic = Periodic(int(self._opts.get('storage_sync_interval', 600)), self.modules._save_loaded_module_data) self._stop_event = Event() self._stop_event.set() self.client.events.on('message-create', self._handle_message) def _handle_message(self, message, client): if message.author == client.me: return # Schedule the handling of the message to occur during the next iteration of the event loop. gevent.spawn_raw(self.__handle_message, message) def __handle_message(self, message): logger.debug("Incoming message %r", message) start = time.time() message._dissonance = self message.targeting_client = message.content.startswith('doot, ') self.modules._handle_message(message) end = time.time() logger.debug("Took %.5f seconds to handle message %r", end - start, message) def _get_module_data(self, module): logger.debug("Getting module data for module %s", module.name) return self._storage.get_data_for_module_name(module.name) @property def name(self): return self.client.me.username @property def running(self): return not self._stop_event.is_set() @property def stopped(self): return not self.running @property def version(self): return version def run(self, auto_join=False): """ Runs Dissonance, loading all the modules, starting the web service, and starting the adapter. If auto_join=True, this function will not return, and will run until dissonance stops if starting dissonance from outside of a greenlet. """ if self.running: raise RuntimeError("Dissonance is already running!") logger.info("Starting Dissonance v%s", self.version) logger.info("Starting storage %s", self._storage) self._storage.start() logger.info("Loading modules") self.modules.load_all() if getattr(self.config, 'web', False) or str(self._opts.get('web', False)).upper() == 'TRUE': self._web = Web(self, EnvFallbackDict('web', getattr(self.config, 'web_opts', {}))) self._web.start() if getattr(self.config, 'manhole', False): from gevent.backdoor import BackdoorServer manhole_opts = EnvFallbackDict('manhole', getattr(self.config, 'manhole_opts', {})) self._manhole = BackdoorServer(( manhole_opts.get('listen_host', '127.0.0.1'), int(manhole_opts.get('listen_port', 9001)) ), locals={ 'client': self.client }) self._manhole.start() logger.info("Attempting to log in as %s" % self._opts['email']) self.client.login(self._opts['email'], self._opts['password']) logger.info("Starting connection to Discord") self.client.start() self._storage_sync_periodic.start(right_away=False) self._stop_event.clear() # If we are the main greenlet, chances are we probably want to never return, # so the main greenlet won't exit, and tear down everything with it. if auto_join and gevent.get_hub().parent == gevent.getcurrent(): self.join() def join(self, timeout=None): """ Blocks until Dissonance is stopped. """ if self.stopped: raise RuntimeError("Dissonance is not running!") self._stop_event.wait(timeout) def stop(self): """ Stops dissonance, turning off the web listener, unloading modules, and stopping the adapter. """ if self.stopped: raise RuntimeError("Dissonance is not running!") logger.info('Stopping Dissonance') try: self.modules.unload_all() if self._web: self._web.stop() self._web = None if self._manhole: self._manhole.stop() self._manhole = None self.client.stop() self._storage_sync_periodic.stop() self._storage.stop() finally: self._stop_event.set() def on_module_error(self, module, e): print(module, e)
class Service(object): def __init__(self, shard=0): signal.signal(signal.SIGINT, lambda unused_x, unused_y: self.exit()) self.name = self.__class__.__name__ self.shard = shard cms.log.initialize_logging(self.name, self.shard) # Stores the function to call periodically. It is to be # managed with heapq. Format: (next_timeout, period, function, # plus) self._timeouts = [] # Whether we want to exit the main loop self._exit = False # Dictionaries of (to be) connected RemoteService, and # dictionaries of callback functions that are going to be # called every time the remote service becomes online. self.remote_services = {} self.on_remote_service_connected = {} # Event to signal that something happened and the sleeping in # run() must be interrupted self.event = gevent.event.Event() self.event.clear() self._my_coord = ServiceCoord(self.name, self.shard) # We setup the listening address for services which want to # connect with us. try: address = get_service_address(self._my_coord) except KeyError: address = None if address is not None: self.server = StreamServer(address, self._connection_handler) self.backdoor = None def _connection_handler(self, socket, address): """Receive and act upon an incoming connection. A new RemoteService is spawned to take care of the new connection. """ try: ipaddr, port = address ipaddr = gevent.socket.gethostbyname(ipaddr) address = Address(ipaddr, port) except: logger.warning("Error: %s" % (traceback.format_exc())) return remote_service = RemoteService(self, address=address) remote_service.initialize_channel(socket) def connect_to(self, service, on_connect=None): """Ask the service to connect to another service. A channel is established and connected. The connection will be reopened if closed. service (ServiceCoord): the service to connect to. on_connect (function): to be called when the service connects. return (RemoteService): the connected RemoteService istance. """ self.on_remote_service_connected[service] = on_connect self.remote_services[service] = RemoteService(self, service) return self.remote_services[service] def add_timeout(self, func, plus, seconds, immediately=False): """Registers a function to be called every x seconds. func (function): the function to call. plus (object): additional data to pass to the function. seconds (float): the function will be called every seconds seconds. immediately (bool): if True, func will be called also at the beginning. """ next_timeout = monotonic_time() if not immediately: next_timeout += seconds heapq.heappush(self._timeouts, (next_timeout, seconds, func, plus)) # Wake up the run() cycle self.event.set() def exit(self): """Terminate the service at the next step. """ logger.warning("%s %d received request to shut down" % self._my_coord) self._exit = True # Wake up the run() cycle self.event.set() def get_backdoor_path(self): """Return the path for a UNIX domain socket to use as backdoor. """ return os.path.join(config.run_dir, "%s_%d" % (self.name, self.shard)) @rpc_method def start_backdoor(self, backlog=50): """Start a backdoor server on a local UNIX domain socket. """ backdoor_path = self.get_backdoor_path() try: os.remove(backdoor_path) except OSError as error: if error.errno != errno.ENOENT: raise else: logger.warning("A backdoor socket has been found and deleted.") mkdir(os.path.dirname(backdoor_path)) backdoor_sock = _socket.socket(_socket.AF_UNIX, _socket.SOCK_STREAM) backdoor_sock.setblocking(0) backdoor_sock.bind(backdoor_path) user = pwd.getpwnam("cmsuser") # We would like to also set the user to "cmsuser" but only root # can do that. Therefore we limit ourselves to the group. os.chown(backdoor_path, os.getuid(), user.pw_gid) os.chmod(backdoor_path, 0o770) backdoor_sock.listen(backlog) self.backdoor = BackdoorServer(backdoor_sock, locals={'service': self}) self.backdoor.start() @rpc_method def stop_backdoor(self): """Stop a backdoor server started by start_backdoor. """ if self.backdoor is not None: self.backdoor.stop() backdoor_path = self.get_backdoor_path() try: os.remove(backdoor_path) except OSError as error: if error.errno != errno.ENOENT: raise def run(self): """Starts the main loop of the service. return (bool): True if successful. """ try: self.server.start() # This must come before socket.error, because socket.gaierror # extends socket.error except gevent.socket.gaierror: logger.critical("Service %s could not listen on " "specified address, because it cannot " "be resolved." % (self.name)) return False except gevent.socket.error as (error, unused_msg): if error == errno.EADDRINUSE: logger.critical("Listening port %s for service %s is " "already in use, quitting." % (self.server.address.port, self.name)) return False elif error == errno.EADDRNOTAVAIL: logger.critical("Service %s could not listen on " "specified address, because it is not " "available." % (self.name)) return False else: raise if config.backdoor: self.start_backdoor() logger.info("%s %d up and running!" % self._my_coord) try: while not self._exit: next_timeout = self._trigger(maximum=0.5) self.event.clear() self.event.wait(timeout=next_timeout) except Exception as error: err_msg = "Exception not managed, quitting. " \ "Exception `%s' and traceback `%s'" % \ (repr(error), traceback.format_exc()) logger.critical(err_msg) logger.info("%s %d is shutting down" % self._my_coord) if config.backdoor: self.stop_backdoor() self._disconnect_all() self.server.stop() return True
def main(json_helper = _JSON_HELPER): """main event loop""" # catch redis errors and keyboard interrupts logging.info('Worker started') if BACKDOOR_PORT: backdoor = BackdoorServer(('127.0.0.1', BACKDOOR_PORT), dict(globals())) logging.info('Backdoor server at 127.0.0.1:%d', BACKDOOR_PORT) backdoor.start() try: REDIS.sadd(WORKER_LIST, _PID) # main loop worker_pool = gevent.pool.Pool(WORKER_THREADS) while True: # if we're no longer welcome, break out of the main loop if not REDIS.sismember(WORKER_LIST, _PID): logging.info( 'Worker PID released, waiting for threads, then exiting.') for thread in _THREADS: thread.join() break # clean up completed tasks for thread in _THREADS: if thread.ready(): _THREADS.remove(thread) WORKER_STATS.gthreads -= 1 logging.debug('GC: %s', thread) # yield for outstanding threads gevent.sleep() # grab the next request from the worker queue, or wait request = REDIS.blpop(WORKER_QUEUE, 5) if not request: # timeout waiting for request, lets us run the loop # again and check if we should still be here continue # request should be JSON try: request = json.loads(request[1]) except ValueError: logging.error('Invalid JSON for request: %s', request[1]) continue WORKER_STATS.requests.inc() # request should be a dict and have a request key with list val if (type(request) is not dict or not request.has_key('method') or type(request['method']) not in [unicode, str]): logging.error('Missing or invalid method: %s', request) continue method = request['method'] # decode the arguments args = request.get('args', []) kwargs = request.get('kwargs', {}) reply_to = request.get('reply_channel', None) no_exec = request.get('no_exec', None) # attempt to resolve the requested function # keeping a cache of them along the way if _EXEC_CACHE.has_key(method): executable = _EXEC_CACHE[method] else: executable = route_to_class_or_function( method) _EXEC_CACHE[method] = executable if not executable: logging.error('Failed to find class or function at %s', method) if reply_to: REDIS.rpush(reply_to, json.dumps({ 'message' : \ 'Failed to find class or function at %s' % ( method), 'response_code' : 404, 'error' : True})) continue # instantiate if we're dealing with a class if type(executable) is type: if issubclass(executable, prototype.Cacheable): # inherits cacheable, we only need one if not _INST_CACHE.has_key(method): # we don't have one yet, so make one _INST_CACHE[method] = executable() logging.debug('New cacheable instance: %s', _INST_CACHE[method]) instance = _INST_CACHE[method] else: # instantiate a regular class every call instance = executable() logging.debug('New instance: %s', instance) # get the instance method we care about if hasattr(instance, method.split('.')[-1]): func = getattr(instance, method.split('.')[-1]) else: logging.error('Failed to find class or function at %s', method) if reply_to: REDIS.rpush(reply_to, json.dumps({ 'message' : \ 'Failed to find class or function at %s' % ( method), 'response_code' : 404, 'error' : True})) continue else: # a normal function (outside a class) func = executable # if no_exec, return just reference to object if no_exec: if reply_to: REDIS.rpush(reply_to, json.dumps({ 'found' : True, 'ref' : str(func)})) continue # execute the function in a greenlet _THREADS.append( worker_pool.spawn( child, func, args, kwargs, reply_to, json_helper)) WORKER_STATS.gthreads += 1 except redis.exceptions.ConnectionError, message: # redis isn't there or went away # wait 5 secs before exit to not upset upstart logging.error('Redis unavailable: %s', message) time.sleep(5) sys.exit(1)
def start_server(): def _exit_handler(*a, **k): gevent.kill(MAIN, SystemExit) sig(signal.SIGTERM, _exit_handler) from game import autoenv import argparse parser = argparse.ArgumentParser(prog=sys.argv[0]) parser.add_argument('node', type=str) parser.add_argument('--host', default='0.0.0.0', type=str) parser.add_argument('--port', default=9999, type=int) parser.add_argument('--backdoor-host', default='127.0.0.1', type=str) parser.add_argument('--backdoor-port', default=19999, type=int) parser.add_argument('--no-backdoor', action='store_true') parser.add_argument('--freeplay', action='store_true') parser.add_argument('--log', default='INFO') parser.add_argument('--logfile', default='') parser.add_argument('--gidfile', default='') parser.add_argument('--credit-multiplier', type=float, default=1) parser.add_argument('--no-counting-flee', action='store_true') parser.add_argument('--archive-path', default='') parser.add_argument('--interconnect', action='store_true', default=False) parser.add_argument('--redis-url', default='redis://localhost:6379') parser.add_argument('--member-service', default='localhost:7000') options = parser.parse_args() import options as opmodule opmodule.options = options autoenv.init('Server') import settings class ServerLogFormatter(logging.Formatter): def format(self, rec): if rec.exc_info: s = [] s.append('>>>>>>' + '-' * 74) s.append(self._format(rec)) import traceback s.append(u''.join(traceback.format_exception(*rec.exc_info)).strip()) s.append('<<<<<<' + '-' * 74) return u'\n'.join(s) else: return self._format(rec) def _format(self, rec): from game.autoenv import Game import time try: g = Game.getgame() except: g = gevent.getcurrent() gr_name = getattr(g, 'gr_name', None) or repr(g) gr_name = 'MAIN' if g is MAIN else gr_name return u'[%s %s %s] %s' % ( rec.levelname[0], time.strftime('%y%m%d %H:%M:%S'), gr_name.decode('utf-8'), rec.msg % rec.args if isinstance(rec.msg, basestring) else repr((rec.msg, rec.args)), ) fmter = ServerLogFormatter() root = logging.getLogger() root.setLevel(getattr(logging, options.log.upper())) std = logging.StreamHandler(stream=sys.stdout) std.setFormatter(fmter) root.handlers = [] root.addHandler(std) if options.logfile: from logging.handlers import WatchedFileHandler filehdlr = WatchedFileHandler(options.logfile) filehdlr.setFormatter(fmter) root.addHandler(filehdlr) if not options.no_backdoor: from gevent.backdoor import BackdoorServer gevent.spawn(BackdoorServer((options.backdoor_host, options.backdoor_port)).serve_forever) from server.core import Client root.info('=' * 20 + settings.VERSION + '=' * 20) server = StreamServer((options.host, options.port), Client.spawn, None) server.serve_forever()
class Server(object): """ The instrument simulator server Handles a set of devices """ def __init__(self, devices=(), backdoor=None): self._log = _log self._log.info("Bootstraping server") if backdoor: from gevent.backdoor import BackdoorServer banner = ("Welcome to Simulator server console.\n" "You can access me through the " "'server()' function. Have fun!") self.backdoor = BackdoorServer( backdoor, banner=banner, locals=dict(server=weakref.ref(self))) self.backdoor.start() self._log.info("Backdoor opened at %r", backdoor) else: self._log.info("no backdoor declared") self.devices = {} for device in devices: try: self.create_device(device) except Exception as error: dname = device.get("name", device.get("class", "unknown")) self._log.error( "error creating device %s (will not be available): %s", dname, error) self._log.debug("details: %s", error, exc_info=1) def create_device(self, device_info): klass_name = device_info.get("class") name = device_info.get("name", klass_name) self._log.info("Creating device %s (%r)", name, klass_name) device, transports = create_device(device_info) self.devices[device] = transports return device, transports def get_device_by_name(self, name): for device in self.devices: if device.name == name: return device def start(self): tasks = [] for device in self.devices: for interface in self.devices[device]: tasks.append(gevent.spawn(interface.serve_forever)) return tasks def stop(self): for device in self.devices: for transport in self.devices[device]: transport.stop() def serve_forever(self): tasks = self.start() try: gevent.joinall(tasks) finally: self.stop() def __str__(self): return "{0}({1})".format(self.__class__.__name__, self.name)
class Service(object): def __init__(self, shard=0, listen_on_address=None): signal.signal(signal.SIGINT, lambda unused_x, unused_y: self.exit()) self.name = self.__class__.__name__ self.shard = shard self._my_coord = ServiceCoord(self.name, self.shard) # Dictionaries of (to be) connected RemoteServiceClients. self.remote_services = {} self.initialize_logging() # We setup the listening address for services which want to # connect with us. try: address = get_service_address(self._my_coord) except KeyError: raise ConfigError("Unable to find address for service %r. " "Is it specified in core_services in cms.conf?" % (self._my_coord,)) logger.info("--- %s %s %s", self.name, listen_on_address, address) if listen_on_address is not None: self.rpc_server = StreamServer( Address(listen_on_address, address.port), self._connection_handler) else: self.rpc_server = StreamServer(address, self._connection_handler) self.backdoor = None def initialize_logging(self): """Set up additional logging handlers. What we do, in detail, is to add a logger to file (whose filename depends on the coords) and a remote logger to a LogService. We also attach the service coords to all log messages. """ filter_ = ServiceFilter(self.name, self.shard) # Update shell handler to attach service coords. shell_handler.addFilter(filter_) # Determine location of log file, and make directories. log_dir = os.path.join(config.log_dir, "%s-%d" % (self.name, self.shard)) mkdir(config.log_dir) mkdir(log_dir) log_filename = time.strftime("%Y-%m-%d-%H-%M-%S.log") # Install a file handler. file_handler = FileHandler(os.path.join(log_dir, log_filename), mode='w', encoding='utf-8') if config.file_log_debug: file_log_level = logging.DEBUG else: file_log_level = logging.INFO file_handler.setLevel(file_log_level) file_handler.setFormatter(DetailedFormatter(False)) file_handler.addFilter(filter_) root_logger.addHandler(file_handler) # Provide a symlink to the latest log file. try: os.remove(os.path.join(log_dir, "last.log")) except OSError: pass os.symlink(log_filename, os.path.join(log_dir, "last.log")) # Setup a remote LogService handler (except when we already are # LogService, to avoid circular logging). if self.name != "LogService": log_service = self.connect_to(ServiceCoord("LogService", 0)) remote_handler = LogServiceHandler(log_service) remote_handler.setLevel(logging.INFO) remote_handler.addFilter(filter_) root_logger.addHandler(remote_handler) def _connection_handler(self, sock, address): """Receive and act upon an incoming connection. A new RemoteServiceServer is spawned to take care of the new connection. """ logger.info("!!!!!!!! %s", address) try: ipaddr = address[0] port = address[1] logger.info("%s %s", ipaddr, port) ipaddr = gevent.socket.gethostbyname(ipaddr) address = Address(ipaddr, port) except socket.error: logger.warning("Unexpected error.", exc_info=True) return remote_service = RemoteServiceServer(self, address) remote_service.handle(sock) def connect_to(self, coord, on_connect=None, on_disconnect=None, must_be_present=True): """Return a proxy to a remote service. Obtain a communication channel to the remote service at the given coord (reusing an existing one, if possible), attach the on_connect and on_disconnect handlers and return it. coord (ServiceCoord): the coord of the service to connect to. on_connect (function|None): to be called when the service connects. on_disconnect (function|None): to be called when it disconnects. must_be_present (bool): if True, the coord must be present in the configuration; otherwise, it can be missing and in that case the return value is a fake client (that is, a client that never connects and ignores all calls). return (RemoteServiceClient): a proxy to that service. """ if coord not in self.remote_services: try: service = RemoteServiceClient(coord, auto_retry=0.5) except KeyError: # The coordinates are invalid: raise a ConfigError if # the service was needed, or return a dummy client if # the service was optional. if must_be_present: raise ConfigError("Missing address and port for %s " "in cms.conf." % (coord, )) else: service = FakeRemoteServiceClient(coord, None) service.connect() self.remote_services[coord] = service else: service = self.remote_services[coord] if on_connect is not None: service.add_on_connect_handler(on_connect) if on_disconnect is not None: service.add_on_disconnect_handler(on_disconnect) return service def add_timeout(self, func, plus, seconds, immediately=False): """Register a function to be called repeatedly. func (function): the function to call. plus (object): additional data to pass to the function. seconds (float): the minimum interval between successive calls (may be larger if a call doesn't return on time). immediately (bool): whether to call right off or wait also before the first call. """ if plus is None: plus = {} func = functools.partial(func, **plus) if immediately: gevent.spawn(repeater, func, seconds) else: gevent.spawn_later(seconds, repeater, func, seconds) def exit(self): """Terminate the service at the next step. """ logger.warning("%r received request to shut down.", self._my_coord) self.rpc_server.stop() def get_backdoor_path(self): """Return the path for a UNIX domain socket to use as backdoor. """ return os.path.join(config.run_dir, "%s_%d" % (self.name, self.shard)) @rpc_method def start_backdoor(self, backlog=50): """Start a backdoor server on a local UNIX domain socket. """ backdoor_path = self.get_backdoor_path() try: os.remove(backdoor_path) except OSError as error: if error.errno != errno.ENOENT: raise else: logger.warning("A backdoor socket has been found and deleted.") mkdir(os.path.dirname(backdoor_path)) backdoor_sock = gevent.socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) backdoor_sock.setblocking(0) backdoor_sock.bind(backdoor_path) user = pwd.getpwnam(config.cmsuser) # We would like to also set the user to "cmsuser" but only root # can do that. Therefore we limit ourselves to the group. os.chown(backdoor_path, os.getuid(), user.pw_gid) os.chmod(backdoor_path, 0o770) backdoor_sock.listen(backlog) self.backdoor = BackdoorServer(backdoor_sock, locals={'service': self}) self.backdoor.start() @rpc_method def stop_backdoor(self): """Stop a backdoor server started by start_backdoor. """ if self.backdoor is not None: self.backdoor.stop() backdoor_path = self.get_backdoor_path() try: os.remove(backdoor_path) except OSError as error: if error.errno != errno.ENOENT: raise def run(self): """Starts the main loop of the service. return (bool): True if successful. """ try: self.rpc_server.start() # This must come before socket.error, because socket.gaierror # extends socket.error except socket.gaierror: logger.critical("Service %s could not listen on " "specified address %s, because it cannot " "be resolved.", self.name, self.rpc_server.address.ip) return False except socket.error as error: if error.errno == errno.EADDRINUSE: logger.critical("Listening port %s for service %s is " "already in use, quitting.", self.rpc_server.address.port, self.name) return False elif error.errno == errno.EADDRNOTAVAIL: logger.critical("Service %s could not listen on " "specified address, because it is not " "available.", self.name) return False else: raise if config.backdoor: self.start_backdoor() logger.info("%s %d up and running!", *self._my_coord) # This call will block until self.rpc_server.stop() is called. self.rpc_server.serve_forever() logger.info("%s %d is shutting down", *self._my_coord) if config.backdoor: self.stop_backdoor() self._disconnect_all() return True def _disconnect_all(self): """Disconnect all remote services. """ for service in itervalues(self.remote_services): if service.connected: service.disconnect() @rpc_method def echo(self, string): """Simple RPC method. string (string): the string to be echoed. return (string): string, again. """ return string @rpc_method def quit(self, reason=""): """Shut down the service reason (string): why, oh why, you want me down? """ logger.info("Trying to exit as asked by another service (%s).", reason) self.exit()
def main(stdscr, *args, **kwargs): global answer, feedback, candidates gevent.signal( signal.SIGUSR1, lambda *args: game_close.set()) # For standard/graceful restart # gevent.signal(signal.SIGINT, lambda *args: None) # Disable SIGINT # signal.signal(signal.SIGQUIT, signal.SIG_IGN) # Disable SIGQUIT # signal.signal(signal.SIGTSTP, signal.SIG_IGN) # Disable SIGTSTP logging.info("Window bounds: %s", stdscr.getmaxyx()) backdoor = BackdoorServer(('0.0.0.0', 4200)) backdoor.start() logging.info("Backdoor started") curses.curs_set(0) # Cursor invisible stdscr.nodelay(1) # Nonblocking input MAXY, MAXX = stdscr.getmaxyx() curses.init_pair(PAIR_MAIN, *DEFAULT_COLORS) curses.init_pair(PAIR_AI, curses.COLOR_RED, curses.COLOR_BLACK) curses.init_pair(PAIR_FEEDBACK, curses.COLOR_WHITE, curses.COLOR_BLACK) curses.init_pair(PAIR_TAGGED, curses.COLOR_YELLOW, curses.COLOR_BLACK) rightscr = stdscr.subwin(0, SPLIT) leftscr = stdscr.subwin(VERTSPLIT, SPLIT, 0, 0) logging.info("Right screen from %s, size %s", rightscr.getbegyx(), rightscr.getmaxyx()) logging.info("Left screen from %s, size %s", leftscr.getbegyx(), leftscr.getmaxyx()) feedback = SlowtypeWindow((VERTSPLIT, 1), (MAXY - VERTSPLIT - 1, SPLIT - 1)) answer = random.choice(get_words(WORDS_PATH)) candidates = get_closest(answer, WORDS_PATH, NUM_CANDIDATES - 1) + [answer] shuffle_main(leftscr, candidates) g_key_handler = spawn(key_handler, stdscr, leftscr) first_key.wait() g_chatter = spawn(timed_chat, rightscr, MAXY - 2) won = game_win_state.get() do_ai_fast.set() ai_done.wait() g_key_handler.kill() g_chatter.kill() feedback.wait() if not won: end(stdscr, "LOSS") attr = curses.color_pair(PAIR_MAIN) leftscr.move(0, 0) leftscr.clear() leftscr.addstr( """WARNING Experiment 203 (Synthetic Reasoning, Combat) has breached containment. Please select a course of action. (1) Isolate system and scrub disks (This will destroy all research on Experiment 203) (2) Release remaining locks, allow experiment full access to base (MAY BE DANGEROUS) (3) Activate Emergency Base Procedure XK-682 """, attr) leftscr.refresh() first = True while 1: c = gevent_getch(sys.stdin, stdscr) if c == ord('1'): end(stdscr, "DESTROY") elif c == ord('2'): end(stdscr, "RELEASE") elif c == ord('3') and first: first = False logging.info("User attempted to arm the nukes") n = 3 leftscr.addstr("Arming nuclear warheads.\nActivation in ", attr) y, x = leftscr.getyx() for i in range(n, -1, -1): leftscr.move(y, x) leftscr.addstr("%d seconds..." % i, attr) leftscr.refresh() gevent.sleep(1) leftscr.addstr( "\nERROR\nYou do not have security permissions\n to perform this action.", attr) leftscr.refresh()
#!/usr/bin/env python #!encoding=utf8 from gevent.backdoor import BackdoorServer BackdoorServer(('127.0.0.1', 9000)).serve_forever()
class Server(object): """ The emulation server Handles a set of devices """ def __init__(self, name='', devices=(), backdoor=None): self.name = name self._log = logging.getLogger('{0}.{1}'.format(_log.name, name)) self._log.info('Bootstraping server') if backdoor: from gevent.backdoor import BackdoorServer banner = 'Welcome to Bliss emulator server console.\n' \ 'My name is {0!r}. You can access me through the ' \ '\'server()\' function. Have fun!'.format(name) self.backdoor = BackdoorServer(backdoor, banner=banner, locals=dict(server=weakref.ref(self))) self.backdoor.start() self._log.info('Backdoor opened at %r', backdoor) else: self._log.info('no backdoor declared') self.devices = {} for device in devices: try: self.create_device(device) except Exception as error: dname = device.get('name', device.get('class', 'unknown')) self._log.error('error creating device %s (will not be available): %s', dname, error) self._log.debug('details: %s', error, exc_info=1) def terminate(self): for device in self.devices: for tp in device.transports: tp.terminate() def create_device(self, device_info): klass_name = device_info.get('class') name = device_info.get('name', klass_name) self._log.info('Creating device %s (%r)', name, klass_name) device, transports = create_device(device_info) self.devices[device] = transports return device, transports def get_device_by_name(self, name): for device in self.devices: if device.name == name: return device def start(self): for device in self.devices: for interface in self.devices[device]: interface.start() def stop(self): for device in self.devices: for interface in self.devices[device]: interface.stop() def serve_forever(self): stop_events = [] for device in self.devices: for interface in self.devices[device]: stop_events.append(interface._stop_event) self.start() try: gevent.joinall(stop_events) finally: self.stop() def __str__(self): return '{0}({1})'.format(self.__class__.__name__, self.name)