def __init__(self, configuration): self.daemon = Daemon(self) self.processes = Processes(self) self.configuration = Configuration(configuration) self.watchdogs = {} self._peers = {} self._shutdown = False self._reload = False self._restart = False self._route_update = False self._commands = {} self._saved_pid = False self.reload() signal.signal(signal.SIGTERM, self.sigterm) signal.signal(signal.SIGHUP, self.sighup) signal.signal(signal.SIGALRM, self.sigalrm)
def __init__ (self,configuration): self.daemon = Daemon(self) self.processes = Processes(self) self.configuration = Configuration(configuration) self.watchdogs = {} self._peers = {} self._shutdown = False self._reload = False self._restart = False self._route_update = False self._commands = {} self._saved_pid = False self.reload() signal.signal(signal.SIGTERM, self.sigterm) signal.signal(signal.SIGHUP, self.sighup) signal.signal(signal.SIGALRM, self.sigalrm)
class Supervisor(object): # [hex(ord(c)) for c in os.popen('clear').read()] clear = ''.join([ chr(int(c, 16)) for c in ['0x1b', '0x5b', '0x48', '0x1b', '0x5b', '0x32', '0x4a'] ]) def __init__(self, configuration): self.daemon = Daemon(self) self.processes = Processes(self) self.configuration = Configuration(configuration) self.watchdogs = {} self._peers = {} self._shutdown = False self._reload = False self._restart = False self._route_update = False self._commands = {} self._saved_pid = False self.reload() signal.signal(signal.SIGTERM, self.sigterm) signal.signal(signal.SIGHUP, self.sighup) signal.signal(signal.SIGALRM, self.sigalrm) def sigterm(self, signum, frame): logger.supervisor("SIG TERM received") self._shutdown = True def sighup(self, signum, frame): logger.supervisor("SIG HUP received") self._reload = True def sigalrm(self, signum, frame): logger.supervisor("SIG ALRM received") self._restart = True def run(self, supervisor_speed=0.5): if self.daemon.drop_privileges(): logger.supervisor( "Could not drop privileges to '%s' refusing to run as root" % self.daemon.user) logger.supervisor( "Set the environmemnt value USER to change the unprivileged user" ) return self.daemon.daemonise() self.daemon.savepid() # did we complete the run of updates caused by the last SIGHUP ? reload_completed = True while True: try: while self._peers: start = time.time() self.handle_commands(self.processes.received()) if self._shutdown: self._shutdown = False self.shutdown() elif self._reload and reload_completed: self._reload = False self.reload() elif self._restart: self._restart = False self.restart() elif self._route_update: self._route_update = False self.route_update() elif self._commands: self.commands(self._commands) self._commands = {} reload_completed = True # Handle all connection peers = self._peers.keys() ios = [] while peers: for key in peers[:]: peer = self._peers[key] # there was no routes to send for this peer, we performed keepalive checks if peer.run() is not True: # no need to come back to it before a a full cycle if peer.bgp and peer.bgp.connection: ios.append(peer.bgp.connection.io) peers.remove(key) # send the route we parsed (if we parsed any to our child processes) # This is a generator and can only be run once try: for route in peer.received_routes(): # This is a generator which content does only change at config reload for name in self.processes.receive_routes( ): # using str(key) as we should not manipulate it and assume its format self.processes.write( name, 'neighbor %s %s\n' % (str(key), route)) except ProcessError: # Can not find any better error code that 6,0 ! raise Notify(6, 0, 'ExaBGP Internal error, sorry.') # otherwise process as many routes as we can within a second for the remaining peers duration = time.time() - start # RFC state that we MUST not more than one KEEPALIVE / sec # And doing less could cause the session to drop if duration >= 1.0: reload_completed = False ios = [] break duration = time.time() - start if ios: try: read, _, _ = select.select( ios, [], [], max(supervisor_speed - duration, 0)) except select.error, e: errno, message = e.args if not errno in errno_block: raise else: if duration < supervisor_speed: time.sleep(max(supervisor_speed - duration, 0)) self.processes.terminate() self.daemon.removepid() break except KeyboardInterrupt: logger.supervisor("^C received") self._shutdown = True except IOError: logger.supervisor( "I/O Error received, most likely ^C during IO") self._shutdown = True
class Supervisor (object): # [hex(ord(c)) for c in os.popen('clear').read()] clear = ''.join([chr(int(c,16)) for c in ['0x1b', '0x5b', '0x48', '0x1b', '0x5b', '0x32', '0x4a']]) def __init__ (self,configuration): self.daemon = Daemon(self) self.processes = Processes(self) self.configuration = Configuration(configuration) self.watchdogs = {} self._peers = {} self._shutdown = False self._reload = False self._restart = False self._route_update = False self._commands = {} self._saved_pid = False self.reload() signal.signal(signal.SIGTERM, self.sigterm) signal.signal(signal.SIGHUP, self.sighup) signal.signal(signal.SIGALRM, self.sigalrm) def sigterm (self,signum, frame): logger.supervisor("SIG TERM received") self._shutdown = True def sighup (self,signum, frame): logger.supervisor("SIG HUP received") self._reload = True def sigalrm (self,signum, frame): logger.supervisor("SIG ALRM received") self._restart = True def run (self,supervisor_speed=0.5): if self.daemon.drop_privileges(): logger.supervisor("Could not drop privileges to '%s' refusing to run as root" % self.daemon.user) logger.supervisor("Set the environmemnt value USER to change the unprivileged user") return self.daemon.daemonise() self.daemon.savepid() # did we complete the run of updates caused by the last SIGHUP ? reload_completed = True while True: try: while self._peers: start = time.time() self.handle_commands(self.processes.received()) if self._shutdown: self._shutdown = False self.shutdown() elif self._reload and reload_completed: self._reload = False self.reload() elif self._restart: self._restart = False self.restart() elif self._route_update: self._route_update = False self.route_update() elif self._commands: self.commands(self._commands) self._commands = {} reload_completed = True # Handle all connection peers = self._peers.keys() ios = [] while peers: for key in peers[:]: peer = self._peers[key] # there was no routes to send for this peer, we performed keepalive checks if peer.run() is not True: # no need to come back to it before a a full cycle if peer.bgp and peer.bgp.connection: ios.append(peer.bgp.connection.io) peers.remove(key) # send the route we parsed (if we parsed any to our child processes) # This is a generator and can only be run once try: for route in peer.received_routes(): # This is a generator which content does only change at config reload for name in self.processes.receive_routes(): # using str(key) as we should not manipulate it and assume its format self.processes.write(name,'neighbor %s %s\n' % (str(key),route)) except ProcessError: # Can not find any better error code that 6,0 ! raise Notify(6,0,'ExaBGP Internal error, sorry.') # otherwise process as many routes as we can within a second for the remaining peers duration = time.time() - start # RFC state that we MUST not more than one KEEPALIVE / sec # And doing less could cause the session to drop if duration >= 1.0: reload_completed = False ios=[] break duration = time.time() - start if ios: try: read,_,_ = select.select(ios,[],[],max(supervisor_speed-duration,0)) except select.error,e: errno,message = e.args if not errno in errno_block: raise else: if duration < supervisor_speed: time.sleep(max(supervisor_speed-duration,0)) self.processes.terminate() self.daemon.removepid() break except KeyboardInterrupt: logger.supervisor("^C received") self._shutdown = True except IOError: logger.supervisor("I/O Error received, most likely ^C during IO") self._shutdown = True