Exemple #1
0
    def serve(self):
        # Add event processor
        amqp = PluginRegistry.getInstance('AMQPHandler')
        EventConsumer(self.env,
            amqp.getConnection(),
            xquery="""
                declare namespace f='http://www.gonicus.de/Events';
                let $e := ./f:Event
                return $e/f:ClientAnnounce
                    or $e/f:ClientSignature
                    or $e/f:ClientPing
                    or $e/f:ClientLeave
                    or $e/f:UserSession
            """,
            callback=self.__eventProcessor)

        # Get registry - we need it later on
        self.__cr = PluginRegistry.getInstance("CommandRegistry")

        # Start maintainence with a delay of 5 seconds
        timer = Timer(5.0, self.__refresh)
        timer.start()
        self.env.threads.append(timer)

        # Register scheduler task to remove outdated clients
        sched = PluginRegistry.getInstance('SchedulerService').getScheduler()
        sched.add_interval_job(self.__gc, minutes=1, tag='_internal', jobstore="ram")
Exemple #2
0
    def serve(self):
        # Establish the database connection
        self.db = self.env.get_mongo_db("clacks").inventory

        # Eventually add index
        if not 'HardwareUUID' in self.db.index_information().values():
            self.db.ensure_index('HardwareUUID')
            self.db.ensure_index('Checksum')

        # Create event consumer
        amqp = PluginRegistry.getInstance('AMQPHandler')
        EventConsumer(self.env,
            amqp.getConnection(),
            xquery="""
                declare namespace f='http://www.gonicus.de/Events';
                let $e := ./f:Event
                return $e/f:Inventory
            """,
            callback=self.process)

        self.log.info("listening for incoming inventory notifications")

        # Register a listener for potential client registries
        cs = PluginRegistry.getInstance("ClientService")
        cs.register_listener('request_inventory', self.client_listener)
Exemple #3
0
    def addClient(self, device_uuid):
        cfg_file = os.path.join(self.__repo_path, "config")
        config = self._git_get_config(cfg_file)

        section = 'remote "%s"' % device_uuid
        if not config.has_section(section):
            cs = PluginRegistry.getInstance("ClientService")
            key = self._get_public_key()

            if not key[1] in [p["data"] for p in cs.clientDispatch(device_uuid, "puppetListKeys").values()]:
                cs.clientDispatch(device_uuid, "puppetAddKey", [key])

            # Update git if needed
            release = self.__get_client_release(device_uuid)
            self.gitPush(self.getBaseDir(release))

            # Update nodes.pp
            self.__update_node(device_uuid)

            # Add git configuration
            config.add_section(section)

            # Build push URL for client, it needs to be online
            try:
                url = cs.clientDispatch(device_uuid, "puppetGetPushPath")
                config.set(section, "url", url)
                with open(cfg_file, "w") as f:
                    config.write(f)
            except:
                return False

            # Reset "P" flag for client
            cs = PluginRegistry.getInstance("ClientService")
            cs.systemSetStatus(device_uuid, "-P")
            return True
Exemple #4
0
    def serve(self):
        self.log.info("listening for asterisk events...")
        amqp = PluginRegistry.getInstance('AMQPHandler')
        EventConsumer(self.env,
            amqp.getConnection(),
            xquery="""
                declare namespace f='http://www.gonicus.de/Events';
                let $e := ./f:Event/f:AMINotification
                return $e/f:Call
            """,
            callback=self.process)

        self.__cr = PluginRegistry.getInstance("CommandRegistry")
Exemple #5
0
def shutdown(a=None, b=None):
    """ Function to shut down the client. """
    global loop

    env = Environment.getInstance()
    env.log.info("Clacks DBUS is shutting down")

    # Shutdown plugins
    PluginRegistry.shutdown()
    if loop:
        loop.quit()

    logging.shutdown()
    exit(0)
Exemple #6
0
    def notifyUser(self, users, title, message, timeout=10, level='normal', icon="dialog-information"):
        """
        Send a notification request to the user client.
        """

        if icon is None:
            icon = "_no_icon_"

        if users:
            # Notify a single / group of users
            if type(users) != types.ListType:
                users = [users]

            for user in users:
                clients = self.getUserClients(user)
                if clients:
                    for client in clients:
                        try:
                            self.clientDispatch(client, "notify", user, title, message,
                                    timeout, icon)
                        #pylint: disable=W0141
                        except Exception as e:
                            import traceback
                            traceback.print_exc()
                            self.log.error("sending message failed: %s" % str(e))
                else:
                    self.log.error("sending message failed: no client found for user '%s'" % user)

                # Notify websession user if available
                jsrpc = PluginRegistry.getInstance("JSONRPCService")
                if jsrpc.user_sessions_available(user):
                    amqp = PluginRegistry.getInstance("AMQPHandler")
                    amqp.sendEvent(self.notification2event(user, title, message, timeout, icon))

        else:
            # Notify all users
            for client in self.__client.keys():
                try:
                    self.clientDispatch(client, "notify_all", title, message,
                            timeout, icon)
                #pylint: disable=W0141
                except Exception:
                    pass

            # Notify all websession users if any
            jsrpc = PluginRegistry.getInstance("JSONRPCService")
            if jsrpc.user_sessions_available():
                amqp = PluginRegistry.getInstance("AMQPHandler")
                amqp.sendEvent(self.notification2event("*", title, message, timeout, icon))
Exemple #7
0
    def _handleClientAnnounce(self, data):
        data = data.ClientAnnounce
        client = data.Id.text
        self.log.info("client '%s' is joining us" % client)
        self.systemSetStatus(client, "+O")

        # Assemble network information
        network = {}
        for interface in data.NetworkInformation.NetworkDevice:
            network[interface.Name.text] = {
                'IPAddress': interface.IPAddress.text,
                'IPv6Address': interface.IPv6Address.text,
                'MAC': interface.MAC.text,
                'Netmask': interface.Netmask.text,
                'Broadcast': interface.Broadcast.text}

        # Add recieve time to be able to sort out dead nodes
        t = datetime.datetime.utcnow()
        info = {
            'name': data.Name.text,
            'last-seen': t,
            'online': True,
            'caps': {},
            'network': network
        }

        self.__client[data.Id.text] = info

        # Handle pending "P"repare actions for that client
        if "P" in self.systemGetStatus(client):
            try:
                rm = PluginRegistry.getInstance("RepositoryManager")
                rm.prepareClient(client)
            except ValueError:
                pass
Exemple #8
0
 def process_IN_CREATE(self, event):
     self.log.debug("logwatch detected change for '%s'" % event.pathname)
     if event.pathname.endswith(".yaml"):
         sleep(1)
         amqp = PluginRegistry.getInstance("AMQPClientHandler")
         self.log.debug("puppet logwatch detected change for '%s', producing event" % event.pathname)
         amqp.sendEvent(self.report_to_event(event.pathname))
Exemple #9
0
 def ping():
     while self.env.active:
         e = EventMaker()
         amqp = PluginRegistry.getInstance("AMQPClientHandler")
         info = e.Event(e.ClientPing(e.Id(uuid)))
         amqp.sendEvent(info)
         time.sleep(timeout)
Exemple #10
0
    def report_to_event(self, file_name):
        e = EventMaker()
        PluginRegistry.getInstance("AMQPClientService")

        with open(file_name, "r") as f:
            yml = yaml.load(f)
            logs = [e.Id(self.env.id)]

            for log in yml.logs:
                data = [
                    e.Timestamp(str(mktime(log.time.timetuple()))),
                    e.Level(log.level),
                    e.Message(log.message),
                ]

                # Append <Tag> tag
                try:
                    tags = e.Tag()
                    for tag in log.tags:
                        tags.append(e.value(tag))
                    data.append(tags)
                except:
                    pass

                # Add optional tags
                try:
                    data.append[e.Source(log.source)]
                except:
                    pass
                try:
                    data.append[e.Line(log.line)]
                except:
                    pass
                try:
                    data.append[e.File(log.file)]
                except:
                    pass
                try:
                    data.append[e.Version(log.version)]
                except:
                    pass

                logs.append(e.PuppetLog(*data))

        return e.Event(e.PuppetReport(*logs))
Exemple #11
0
def shutdown(a=None, b=None):
    global dr

    env = Environment.getInstance()
    log = logging.getLogger(__name__)

    # Function to shut down the client. Do some clean up and close sockets.
    amqp = PluginRegistry.getInstance("AMQPClientHandler")

    # Tell others that we're away now
    e = EventMaker()
    goodbye = e.Event(e.ClientLeave(e.Id(env.uuid)))
    if amqp:
        amqp.sendEvent(goodbye)
        amqp.close()

    # Shutdown plugins
    PluginRegistry.shutdown()

    #TODO: remove this hack
    wait = 1
    for t in env.threads:
        if t.isAlive():
            log.warning("thread %s still alive" % t.getName())
            if hasattr(t, 'stop'):
                log.warning("calling 'stop' for thread %s" % t.getName())
                t.stop()
            if hasattr(t, 'cancel'):
                log.warning("calling 'cancel' for thread %s" % t.getName())
                t.cancel()
            t.join(wait)

        if t.isAlive():
            try:
                log.warning("calling built in 'stop' for thread %s" % t.getName())
                t._Thread__stop()
            except:
                log.error("could not stop thread %s" % t.getName())

    dr.stop()

    log.info("shut down")
    logging.shutdown()
Exemple #12
0
    def client_listener(self, client, method, mode):
        if mode:
            # Send an inventory information with the current checksum
            self.log.info("requesting inventory from client %s" % client)
            cs = PluginRegistry.getInstance("ClientService")

            entry = self.db.find_one({'ClientUUID': client}, {'Checksum': 1})
            if entry:
                cs.clientDispatch(client, "request_inventory", entry['Checksum'])
            else:
                cs.clientDispatch(client, "request_inventory")
Exemple #13
0
    def sendSessionNotification(self):
        # Build event
        amqp = PluginRegistry.getInstance("AMQPClientHandler")
        e = EventMaker()
        more = set([x['uid'] for x in self.__sessions.values()])
        more = map(e.Name, more)
        info = e.Event(
            e.UserSession(
                e.Id(self.env.uuid),
                e.User(*more)))

        amqp.sendEvent(info)
Exemple #14
0
    def __init__(self):
        super(DebianPreseed, self).__init__()
        self.env = Environment.getInstance()
        self.path = self.env.config.get('libinst.path', default="/preseed")

        try:
            # Get http service instance
            self.__http = PluginRegistry.getInstance('HTTPService')

            # Register ourselves
            self.__http.register(self.path, self)

        except:
            pass
Exemple #15
0
    def sendEvent(self, data, user=None):
        """
        Send and validate an event thru AMQP service.

        =============== ============
        Parameter       Description
        =============== ============
        data            XML string or etree object representing the event.
        =============== ============

        ``Return:`` Bool, success or failure
        """
        try:
            event = u"<?xml version='1.0'?>\n"
            if isinstance(data, basestring):
                event += data
            else:
                event += etree.tostring(data, pretty_print=True)

            # Validate event
            if hasattr(self, '_parser'):
                xml = objectify.fromstring(event, self._parser)
            else:
                #TODO: retrieve schema from server
                xml = objectify.fromstring(event)

            # If a user was supplied, check if she's authorized...
            if user:
                acl = PluginRegistry.getInstance("ACLResolver")
                topic = ".".join([self.env.domain, 'event', xml.__dict__.keys()[0]])
                if not acl.check(user, topic, "x"):
                    raise EventNotAuthorized("sending the event '%s' is not permitted" % topic)

            return self._eventProvider.send(event)

        except etree.XMLSyntaxError as e:
            if not isinstance(data, basestring):
                data = data.content
            if self.env:
                self.log.error("event rejected (%s): %s" % (str(e), data))
            raise
Exemple #16
0
def netactivity(online):
    global netstate
    if online:
        netstate = True

    else:
        env = Environment.getInstance()
        netstate = False

        # Function to shut down the client. Do some clean up and close sockets.
        amqp = PluginRegistry.getInstance("AMQPClientHandler")

        # Tell others that we're away now
        e = EventMaker()
        goodbye = e.Event(e.ClientLeave(e.Id(env.uuid)))
        if amqp:
            amqp.sendEvent(goodbye)
            amqp.close()

        env.reset_requested = True
        env.active = False
Exemple #17
0
    def __refresh(self):
        # Initially check if we need to ask for client caps or if there's someone
        # who knows...
        if not self.__client:
            nodes = self.__cr.getNodes()
            if not nodes:
                return

            # If we're alone, please clients to announce themselves
            if len(nodes) == 1 and self.env.id in nodes:
                amqp = PluginRegistry.getInstance('AMQPHandler')
                e = EventMaker()
                amqp.sendEvent(e.Event(e.ClientPoll()))

            # Elseways, ask other servers for more client info
            else:
                #TODO: get from host
                #take a random node and:
                # ... for all clients
                #     ... load client capabilities and store them localy
                raise NotImplementedError("getting client information from other nodes is not implemented!")
Exemple #18
0
    def clientDispatch(self, client, method, *arg, **larg):
        """
        Dispatch a method on the client.

        ========= ================================
        Parameter Description
        ========= ================================
        client    Device UUID of the client
        method    Method name to call
        *         Method arguments
        ========= ================================

        ``Return:`` varies
        """

        # Bail out if the client is not available
        if not client in self.__client:
            raise JSONRPCException("client '%s' not available" % client)
        if not self.__client[client]['online']:
            raise JSONRPCException("client '%s' is offline" % client)
        if not method in self.__client[client]['caps']:
            raise JSONRPCException("client '%s' has no method '%s' exported" % (client, method))

        # Generate tage queue name
        queue = '%s.client.%s' % (self.env.domain, client)
        self.log.debug("got client dispatch: '%s(%s)', sending to %s" % (method, arg, queue))

        # client queue -> amqp rpc proxy
        if not client in self.__proxy:
            amqp = PluginRegistry.getInstance("AMQPHandler")
            self.__proxy[client] = AMQPServiceProxy(amqp.url['source'], queue)

        # Call her to the moon...
        methodCall = getattr(self.__proxy[client], method)

        # Do the call
        res = methodCall(*arg, **larg)
        return res
Exemple #19
0
    def __init__(self):
        env = Environment.getInstance()
        self.log = logging.getLogger(__name__)
        self.log.debug("initializing AMQP handler")
        self.env = env
        self.config = env.config

        # Initialize parser
        schema_root = etree.XML(PluginRegistry.getEventSchema())
        schema = etree.XMLSchema(schema_root)
        self._parser = objectify.makeparser(schema=schema)

        # Evaluate username
        user = self.env.uuid
        password = self.config.get("amqp.key")

        # Load configuration
        self.url = parseURL(makeAuthURL(self.config.get('amqp.url'), user, password))
        self.reconnect = self.config.get('amqp.reconnect', True)
        self.reconnect_interval = self.config.get('amqp.reconnect_interval', 3)
        self.reconnect_limit = self.config.get('amqp.reconnect_limit', 0)

        # Go for it
        self.start()
Exemple #20
0
 def setConfigParameters(self, device_uuid, data, current_data=None):
     super(PuppetInstallMethod, self).setConfigParameters(device_uuid, data, current_data)
     if not self.addClient(device_uuid):
         cs = PluginRegistry.getInstance("ClientService")
         cs.systemSetStatus(device_uuid, "+P")
Exemple #21
0
    def SvcDoRun(self):
        pythoncom.CoInitialize()
        servicemanager.LogMsg(
            servicemanager.EVENTLOG_INFORMATION_TYPE,
            servicemanager.PYS_SERVICE_STARTED,
            (self._svc_name_, ''))

        # Start main loop thread here
        Environment.config = "C:/gosa-client.conf"
        Environment.noargs = True
        self.env = Environment.getInstance()
        self.env.log.info("Clacks client is starting up")
        env = self.env

        try:
            # Load plugins
            PluginRegistry(component='client.module')
            amqp = PluginRegistry.getInstance("AMQPClientHandler") #@UnusedVariable

            #TODO:
            # Check if we're a client
            # -> no: shutdown, client should be joined by administrator before
            #        calling the client

            # Sleep and slice
            wait = 2
            while True:
                # Threading doesn't seem to work well with python...
                for p in env.threads:

                    # Bail out if we're active in the meanwhile
                    if not env.active:
                        break

                    p.join(wait)

                # No break, go to main loop
                else:
                    continue

                # Break, leave main loop
                break

        except Exception as detail:
            env.log.critical("unexpected error in mainLoop")
            env.log.exception(detail)
            env.log.debug(traceback.format_exc())
        finally:
            pythoncom.CoUninitialize()

        # Signalize main thread to shut down
        win32api.Sleep(500)

        # Pull down system
        amqp = PluginRegistry.getInstance("AMQPClientHandler")
        amqp_service = PluginRegistry.getInstance("AMQPClientService")

        # Tell others that we're away now
        e = EventMaker()
        goodbye = e.Event(e.ClientLeave(e.Id(amqp_service.id)))
        amqp.sendEvent(goodbye)

        # Shutdown plugins
        PluginRegistry.shutdown()

        # Write another event log record.
        servicemanager.LogMsg(
                servicemanager.EVENTLOG_INFORMATION_TYPE,
                servicemanager.PYS_SERVICE_STOPPED,
                (self._svc_name_, ''))
Exemple #22
0
    def __announce(self, initial=False):
        amqp = PluginRegistry.getInstance("AMQPClientHandler")
        e = EventMaker()

        # Assemble network information
        more = []
        netinfo = []
        for interface in netifaces.interfaces():
            i_info = netifaces.ifaddresses(interface)

            # Skip lo interfaces
            if not netifaces.AF_INET in i_info:
                continue

            # Skip lo interfaces
            if not netifaces.AF_LINK in i_info:
                continue
            if i_info[netifaces.AF_LINK][0]["addr"] == "00:00:00:00:00:00":
                continue

            # Assemble ipv6 information
            ip6 = ""
            if netifaces.AF_INET6 in i_info:
                ip = IPNetwork(
                    "%s/%s"
                    % (i_info[netifaces.AF_INET6][0]["addr"].split("%", 1)[0], i_info[netifaces.AF_INET6][0]["netmask"])
                )
                ip6 = str(ip)

            netinfo.append(
                e.NetworkDevice(
                    e.Name(interface),
                    e.IPAddress(i_info[netifaces.AF_INET][0]["addr"]),
                    e.IPv6Address(ip6),
                    e.MAC(i_info[netifaces.AF_LINK][0]["addr"]),
                    e.Netmask(i_info[netifaces.AF_INET][0]["netmask"]),
                    e.Broadcast(i_info[netifaces.AF_INET][0]["broadcast"]),
                )
            )

        more.append(e.NetworkInformation(*netinfo))

        # Build event
        if initial:
            info = e.Event(e.ClientAnnounce(e.Id(self.env.uuid), e.Name(self.env.id), *more))

            amqp.sendEvent(info)

        # Assemble capabilities
        more = []
        caps = []
        for command, dsc in self.__cr.commands.iteritems():
            caps.append(
                e.ClientMethod(
                    e.Name(command), e.Path(dsc["path"]), e.Signature(",".join(dsc["sig"])), e.Documentation(dsc["doc"])
                )
            )
        more.append(e.ClientCapabilities(*caps))

        info = e.Event(e.ClientSignature(e.Id(self.env.uuid), e.Name(self.env.id), *more))

        amqp.sendEvent(info)

        if not initial:
            try:
                sk = PluginRegistry.getInstance("SessionKeeper")
                sk.sendSessionNotification()
            except:
                pass
Exemple #23
0
    def serve(self):
        """ Start AMQP service for this clacks service provider. """
        # Load AMQP and Command registry instances
        amqp = PluginRegistry.getInstance("AMQPClientHandler")
        self.__cr = PluginRegistry.getInstance("ClientCommandRegistry")

        # Add private processor for client queue
        # pylint: disable=E1101
        self.__cmdWorker = AMQPWorker(
            self.env,
            connection=amqp.getConnection(),
            r_address="""%s.client.%s; {
                    create:always,
                    node:{
                        type:queue,
                        durable: False,
                        x-declare: {
                            exclusive: True,
                            auto-delete: True },
                        x-bindings:[ {
                                exchange:"amq.direct",
                                queue:"%s.client.%s" } ]
                        }
                    }"""
            % (self.env.domain, self.env.uuid, self.env.domain, self.env.uuid),
            workers=self.env.config.get("amqp.worker", default=1),
            callback=self.commandReceived,
        )

        # Add event processor
        try:
            EventConsumer(
                self.env,
                amqp.getConnection(),
                xquery="""
                    declare namespace f='http://www.gonicus.de/Events';
                    let $e := ./f:Event
                    return $e/f:ClientPoll
                """,
                callback=self.__handleClientPoll,
            )

            # Gather interface information
            self.__announce(True)

        except NotFound as e:
            self.env.log.critical("queue gone: %s" % str(e))

        # Send a ping on a regular base
        uuid = self.env.uuid
        timeout = float(self.env.config.get("client.ping-interval", default=600))

        def ping():
            while self.env.active:
                e = EventMaker()
                amqp = PluginRegistry.getInstance("AMQPClientHandler")
                info = e.Event(e.ClientPing(e.Id(uuid)))
                amqp.sendEvent(info)
                time.sleep(timeout)

        pinger = Timer(10.0, ping)
        pinger.start()
        self.env.threads.append(pinger)
Exemple #24
0
    def process(self, data):
        dat = data.AMINotification['Call']

        # Load information into dict
        event = {}
        for t in dat.iterchildren():
            tag = re.sub(r"^\{.*\}(.*)$", r"\1", t.tag)
            if t.tag == 'From':
                event[tag] = t.text.split(" ")[0]
            else:
                event[tag] = str(t.text)

        # Simple debouncing
        if self.last_event and self.last_event['From'] == event['From'] and self.last_event['To'] == event['To'] and self.last_event['Type'] == event['Type'] and (float(event['Timestamp']) - float(self.last_event['Timestamp'])) < 1:
            return

        self.last_event = event

        #TODO: wrong place here - workaround
        if event['From'] == "+49":
            event['From'] = "Unbekannter Teilnehmer"
        if event['To'] == "+49":
            event['To'] = "Unbekannter Teilnehmer"

        # Resolve numbers with all resolvers, sorted by priority
        i_from = None
        i_to = None

        for mod, info in sorted(self.resolver.iteritems(),
                key=lambda k: k[1]['priority']):
            if not i_from:
                i_from = info['object'].resolve(event['From'])
            if not i_to:
                i_to = info['object'].resolve(event['To'])
            if i_from and i_to:
                break

        # Fallback to original number if nothing has been found
        if not i_from:
            i_from = {'contact_phone': event['From'], 'contact_name': event['From'],
                    'company_name': None, 'resource': 'none'}
        if not i_to:
            i_to = {'contact_phone': event['To'], 'contact_name': event['To'],
                    'company_name': None, 'resource': 'none'}

        # Render messages
        to_msg = from_msg = ""
        for mod, info in sorted(self.renderer.iteritems(),
                key=lambda k: k[1]['priority']):

            if 'ldap_uid' in i_to and i_to['ldap_uid']:
                to_msg += info['object'].getHTML(i_from, i_to, event)
                to_msg += "\n\n"

            if 'ldap_uid' in i_from and i_from['ldap_uid'] and event['Type'] == 'CallEnded':
                from_msg += info['object'].getHTML(i_to, i_from, event)
                from_msg += "\n\n"

        # encode as ASCII with hexadecimal HTML entities for non-latin1 chars
        to_msg = to_msg.encode('ascii', 'xmlcharrefreplace')
        from_msg = from_msg.encode('ascii', 'xmlcharrefreplace')

        # Define avatar view
        if 'avatar' in i_from and i_from['avatar']:
            f_img = Image.open(StringIO(i_from['avatar']))
        else:
            f_img = self.__default_image
        if 'avatar' in i_to and i_to['avatar']:
            t_img = Image.open(StringIO(i_to['avatar']))
        else:
            t_img = self.__default_image

        # Scale image to a reasonable size and convert it to base64
        mw = int(self.env.config.get("amires.avatar-size", default="96"))
        sx, sy = f_img.size
        if sx >= sy:
            f_img.thumbnail((mw, int(sy * mw / sx)))
        else:
            f_img.thumbnail((int(sx * mw / sy), mw))
        sx, sy = t_img.size
        if sx >= sy:
            t_img.thumbnail((mw, int(sy * mw / sx)))
        else:
            t_img.thumbnail((int(sx * mw / sy), mw))

        out = StringIO()
        f_img.save(out, format="PNG")
        out.seek(0)
        f_image_data = "base64:" + base64.b64encode(out.read())

        out = StringIO()
        t_img.save(out, format="PNG")
        out.seek(0)
        t_image_data = "base64:" + base64.b64encode(out.read())

        # Send from/to messages as needed
        amqp = PluginRegistry.getInstance('AMQPHandler')
        if from_msg:
            self.__cr.call("notifyUser", i_from['ldap_uid'],
            self.TYPE_MAP[event['Type']], from_msg.strip(), timeout=10, level='normal', icon=t_image_data)

        if to_msg:
            self.__cr.call("notifyUser", i_to['ldap_uid'],
            self.TYPE_MAP[event['Type']], to_msg.strip(), timeout=10, level='normal', icon=f_image_data)
Exemple #25
0
def mainLoop(env):
    global netstate, dr

    # Enable DBus runner
    dr = DBusRunner()
    dr.start()

    # Do network monitoring
    nm = Monitor(netactivity)
    netstate = nm.is_online()

    """ Main event loop which will process all registerd threads in a loop.
        It will run as long env.active is set to True."""
    try:
        log = logging.getLogger(__name__)

        while True:

            # Check netstate and wait until we're back online
            if not netstate:
                log.info("waiting for network connectivity")
            while not netstate:
                time.sleep(1)

            # Load plugins
            PluginRegistry(component='client.module')

            # Sleep and slice
            wait = 2
            while True:
                # Threading doesn't seem to work well with python...
                for p in env.threads:

                    # Bail out if we're active in the meanwhile
                    if not env.active:
                        break

                    p.join(wait)

                # No break, go to main loop
                else:
                    continue

                # Break, leave main loop
                break

            # Break, leave main loop
            if not env.reset_requested:
                break

            # Wait for threads to shut down
            for t in env.threads:
                if hasattr(t, 'stop'):
                    t.stop()
                if hasattr(t, 'cancel'):
                    t.cancel()
                t.join(wait)

                #TODO: remove me
                if t.isAlive():
                    try:
                        t._Thread__stop()
                    except:
                        print(str(t.getName()) + ' could not be terminated')

            # Lets do an environment reset now
            PluginRegistry.shutdown()

            # Make us active and loop from the beginning
            env.reset_requested = False
            env.active = True

            if not netstate:
                log.info("waiting for network connectivity")
            while not netstate:
                time.sleep(1)

            sleep = randint(30, 60)
            env.log.info("waiting %s seconds to try an AMQP connection recovery" % sleep)
            time.sleep(sleep)

    except Exception as detail:
        log.critical("unexpected error in mainLoop")
        log.exception(detail)
        log.debug(traceback.format_exc())

    except KeyboardInterrupt:
        log.info("console requested shutdown")

    finally:
        shutdown()