Example #1
0
    def _onTeleOnMesg(self, sock, mesg):

        try:
            # set the socket tx method as the callback
            jid = mesg[1].get('jid')
            ons = mesg[1].get('ons')
            name = mesg[1].get('name')

            item = self.shared.get(name)
            if item is None:
                raise s_common.NoSuchObj(name=name)

            user = sock.get('syn:user')

            func = getattr(item, 'on', None)
            if func is None:
                return sock.tx(s_common.tufo('job:done', jid=jid, ret=False))

            self._reqUserAllowed(user, 'tele:call', name, 'on')

            for evnt, ontups in ons:  # (<evnt>, ( (<iden>,<filt>), ... ))
                onhelp, new = self._getOnHelp(name, evnt)
                if new:
                    func(evnt, onhelp.dist)

                for iden, filt in ontups:
                    onhelp.addOnInst(sock, iden, filt)

            return sock.tx(s_common.tufo('job:done', jid=jid, ret=True))

        except Exception as e:
            sock.tx(s_common.tufo('job:done', jid=jid, **s_common.excinfo(e)))
Example #2
0
    def _onTeleOffMesg(self, sock, mesg):
        # set the socket tx method as the callback
        try:

            jid = mesg[1].get('jid')
            evnt = mesg[1].get('evnt')
            name = mesg[1].get('name')
            iden = mesg[1].get('iden')

            item = self.shared.get(name)
            if item is None:
                raise s_common.NoSuchObj(name=name)

            onhelp, new = self._getOnHelp(name, evnt)
            onhelp.delOnInst(sock, iden)

            return sock.tx(s_common.tufo('job:done', jid=jid, ret=True))

        except Exception as e:
            errinfo = s_common.excinfo(e)
            sock.tx(
                s_common.tufo('job:done',
                              jid=jid,
                              err=errinfo.get('err'),
                              errinfo=errinfo))
Example #3
0
    def loadDmonConf(self, conf):
        '''
        Process Daemon specific dmon config elements.

        # examples of additional config elements

        {
            "sessions":{

                "comment":"Maxtime (if set) sets the maxtime for the session cache (in seconds)",
                "maxtime":12345,

                "comment":"Curator (if set) uses dmoneval to set the session curator",
                "curator":"tcp://host.com:8899/synsess",

                "comment":"Comment (if set) saves sessions to the given path (sqlite cortex)",
                "savefile":"sessions.sql3"

            },

            "share":(
                ('fooname',{'optname':optval}),
                ...
            ),

            "listen":(
                'tcp://0.0.0.0:8899',
                ...
            ),

        }

        '''
        DmonConf.loadDmonConf(self, conf)

        for name, opts in conf.get('share', ()):
            asname = opts.get('name', name)

            item = self.locs.get(name)
            if item is None:
                raise s_common.NoSuchObj(name)

            # keeping as "onfini" for backward compat
            # FIXME CHANGE WITH MAJOR REV
            fini = opts.get('onfini', False)
            self.share(asname, item, fini=fini)

        # process the sessions config info
        sessinfo = conf.get('sessions')
        if sessinfo is not None:
            self._loadSessConf(sessinfo)

        # process a few daemon specific options
        for url in conf.get('listen', ()):
            if s_compat.isstr(url):
                self.listen(url)
                continue

            url, opts = url
            self.listen(url, **opts)
Example #4
0
    def test_eventbus_exc(self):

        logs = []
        with s_eventbus.EventBus() as ebus:
            ebus.on('log', logs.append)

            try:
                raise s_common.NoSuchObj(name='hehe')
            except Exception as e:
                ebus.exc(e)

        mesg = logs[0]
        self.eq(mesg[1].get('err'), 'NoSuchObj')
Example #5
0
    def callByIden(self, iden, func, *args, **kwargs):
        '''
        Call a specific object on the service bus by iden.

        Example:

            ret = svcprox.callByIden(iden,'getFooByBar',bar)

        '''
        svcfo = self.byiden.get(iden)
        if svcfo is None:
            raise s_common.NoSuchObj(iden)

        dyntask = (func, args, kwargs)
        job = self.sbus.callx(iden, dyntask)
        self.sbus._waitTeleJob(job, timeout=self.timeout)
        return s_async.jobret(job)
Example #6
0
    def loadDmonConf(self, conf):
        '''
        Process Daemon specific dmon config elements.

        # examples of additional config elements

        {
            "share":(
                ('fooname',{'optname':optval}),
                ...
            ),

            "listen":(
                'tcp://0.0.0.0:8899',
                ...
            ),

        }

        '''
        DmonConf.loadDmonConf(self, conf)

        for name, opts in conf.get('share', ()):
            asname = opts.get('name', name)

            item = self.locs.get(name)
            if item is None:
                raise s_common.NoSuchObj(name)

            # keeping as "onfini" for backward compat
            # FIXME CHANGE WITH MAJOR REV
            fini = opts.get('onfini', False)
            self.share(asname, item, fini=fini)

        # process a few daemon specific options
        for url in conf.get('listen', ()):
            if isinstance(url, str):
                self.listen(url)
                continue

            url, opts = url
            self.listen(url, **opts)
Example #7
0
    def callByName(self, name, dyntask, timeout=None):
        '''
        Call a specific object on the service bus by name.

        Example:

            # dyntask tuple is (name,args,kwargs)

            dyntask = gentask('getFooByBar',bar)
            ret = svcprox.callByName('foo0', dyntask)

        '''
        if timeout is None:
            timeout = self.timeout

        svcfo = self.getSynSvcByName(name)
        if svcfo is None:
            raise s_common.NoSuchObj(name)

        job = self.sbus.callx(svcfo[0], dyntask)
        self.sbus._waitTeleJob(job, timeout=timeout)
        return s_async.jobret(job)
Example #8
0
    def _onTeleCallMesg(self, sock, mesg):

        # tele:call - call a method on a shared object

        jid = mesg[1].get('jid')
        sid = mesg[1].get('sid')

        # check if the socket knows about their auth
        # ( most likely via SSL client cert )
        user = sock.get('syn:user')

        with s_scope.enter({
                'dmon': self,
                'sock': sock,
                'syn:user': user,
                'syn:auth': self.auth
        }):

            try:

                name = mesg[1].get('name')

                item = self.shared.get(name)
                if item is None:
                    # is it a pushed object?
                    pushsock = self.pushed.get(name)
                    if pushsock is not None:
                        # pass along how to reply
                        mesg[1]['suid'] = sock.iden
                        return pushsock.tx(mesg)
                    raise s_common.NoSuchObj(name)

                task = mesg[1].get('task')
                meth, args, kwargs = task

                self._reqUserAllowed(user, 'tele:call', name, meth)

                func = getattr(item, meth, None)
                if func is None:
                    raise s_common.NoSuchMeth(meth)

                if getattr(func, '_tele_clientside', False):
                    name = s_reflect.getMethName(func)
                    raise s_common.TeleClientSide(name=name)

                ret = func(*args, **kwargs)

                # handle generator returns specially
                if isinstance(ret, types.GeneratorType):

                    iden = s_common.guid()

                    txwait = threading.Event()
                    # start off set...
                    txwait.set()

                    self._dmon_yields.add(iden)
                    sock.tx(
                        s_common.tufo('tele:yield:init', jid=jid, iden=iden))

                    # FIXME opt
                    maxsize = 100000000

                    def ontxsize(m):
                        size = m[1].get('size')
                        if size >= maxsize:
                            txwait.clear()
                        else:
                            txwait.set()

                    try:

                        sock.onfini(txwait.set)
                        sock.on('sock:tx:size', ontxsize)

                        for item in ret:

                            txwait.wait()

                            # check if we woke due to fini
                            if sock.isfini:
                                break

                            sock.tx(
                                s_common.tufo('tele:yield:item',
                                              iden=iden,
                                              item=item))
                            if iden not in self._dmon_yields:
                                break

                    finally:
                        sock.off('sock:tx:size', ontxsize)
                        self._dmon_yields.discard(iden)
                        sock.tx(s_common.tufo('tele:yield:fini', iden=iden))

                    return

                sock.tx(s_common.tufo('job:done', jid=jid, ret=ret))

            except Exception as e:
                sock.tx(
                    s_common.tufo('job:done', jid=jid, **s_common.excinfo(e)))
Example #9
0
    def _loadDmonConf(self, conf):

        checkConfDict(conf)
        self.locs.update(conf.get('vars', {}))

        # handle forks first to prevent socket bind weirdness
        for name, subconf in conf.get('forks', ()):
            self._fireDmonFork(name, subconf)

        title = conf.get('title')
        if title is not None:
            s_thisplat.setProcName('dmon: %s' % title)

        # handle explicit module load requests
        for name, info in conf.get('modules', ()):
            modu = s_dyndeps.getDynMod(name)
            if modu is None:
                logger.warning('dmon mod not loaded: %s', name)

        # handle includes next
        for path in conf.get('includes', ()):
            fullpath = os.path.expanduser(path)
            try:
                self.loadDmonFile(fullpath)
            except Exception as e:
                raise Exception('Include Error (%s): %s' % (path, e))

        configs = conf.get('configs', {})

        for row in conf.get('ctors', ()):

            copts = {}  # ctor options
            if len(row) == 2:
                name, url = row
            elif len(row) == 3:
                name, url, copts = row
            else:
                raise Exception('Invalid ctor row: %r' % (row, ))

            if url.find('://') == -1:
                # this is a (name,dynfunc,config) formatted ctor...
                item = s_dyndeps.tryDynFunc(url, copts)
            else:
                item = self.dmoneval(url)

            self.locs[name] = item

            # check for a ctor opt that wants us to load a config dict by name
            cfgname = copts.get('config')
            if cfgname is not None:
                if not isinstance(item, s_config.Configable):
                    raise Exception('dmon ctor: %s does not support configs' %
                                    name)

                opts = configs.get(cfgname)
                if opts is None:
                    raise s_common.NoSuchConf(name=cfgname)

                item.setConfOpts(opts)

            # check for a ctor opt that wants us to "flatten" several configs in order
            cfgnames = copts.get('configs')
            if cfgnames is not None:

                if not isinstance(item, s_config.Configable):
                    raise Exception('dmon ctor: %s does not support configs' %
                                    name)

                opts = {}
                for cfgname in cfgnames:

                    cfgopts = configs.get(cfgname)
                    if cfgopts is None:
                        raise s_common.NoSuchConf(name=cfgname)

                    opts.update(cfgopts)

                item.setConfOpts(opts)

            # check for a match between config and ctor names
            opts = configs.get(name)
            if opts is not None:
                item.setConfOpts(opts)

            self.fire('dmon:conf:ctor', name=name, item=item)

        for busname, svcruns in conf.get('services', ()):

            svcbus = self.dmoneval(busname)
            if svcbus is None:
                raise s_common.NoSuchObj(name)

            for svcname, svcopts in svcruns:

                item = self.locs.get(svcname)
                if item is None:
                    raise s_common.NoSuchObj(svcname)

                svcname = svcopts.get('name', svcname)
                s_service.runSynSvc(svcname, item, svcbus, **svcopts)