Beispiel #1
0
    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)
Beispiel #2
0
	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)
Beispiel #3
0
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
Beispiel #4
0
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