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)))
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))
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)
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')
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)
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)
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)
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)))
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)