async def docStormsvc(ctor): cls = s_dyndeps.tryDynLocal(ctor) if not hasattr(cls, 'cellapi'): raise Exception('ctor must have a cellapi attr') clsname = cls.__name__ cellapi = cls.cellapi if not issubclass(cellapi, s_stormsvc.StormSvc): raise Exception('cellapi must be a StormSvc implementation') # Make a dummy object class MockSess: def __init__(self): self.user = None class DummyLink: def __init__(self): self.info = {'sess': MockSess()} def get(self, key): return self.info.get(key) async with await cellapi.anit(s_common.novalu, DummyLink(), s_common.novalu) as obj: svcinfo = await obj.getStormSvcInfo() rst = s_autodoc.RstHelp() # Disable default python highlighting rst.addLines('.. highlight:: none\n') rst.addHead(f'{clsname} Storm Service') lines = ['The following Storm Packages and Commands are available from this service.', f'This documentation is generated for version ' f'{s_version.fmtVersion(*svcinfo.get("vers"))} of the service.', f'The Storm Service name is ``{svcinfo.get("name")}``.', ] rst.addLines(*lines) for pkg in svcinfo.get('pkgs'): pname = pkg.get('name') pver = pkg.get('version') commands = pkg.get('commands') hname = pname if ':' in pname: hname = pname.replace(':', raw_back_slash_colon) rst.addHead(f'Storm Package\\: {hname}', lvl=1) rst.addLines(f'This documentation for {pname} is generated for version {s_version.fmtVersion(*pver)}') if commands: await processStormCmds(rst, pname, commands) # TODO: Modules are not currently documented. return rst, clsname
async def _initLayr(self, layrinfo): iden = layrinfo.get('iden') ctorname = layrinfo.get('ctor') ctor = s_dyndeps.tryDynLocal(ctorname) layrinfo['readonly'] = True layr = await self._ctorLayr(ctor, layrinfo) self.onfini(layr) self.layers[iden] = layr
async def _workloop(spawninfo, todo, done): ''' Workloop executed by the multiprocessing target. Args: spawninfo (dict): Spawninfo dictionary. todo (multiprocessing.Queue): RX Queue done (multiprocessing.Queue): TX Queue Returns: None: Returns None. ''' s_glob.iAmLoop() ctorname = spawninfo.get('spawncorector') ctor = s_dyndeps.tryDynLocal(ctorname) async with await ctor.anit(spawninfo) as core: while not core.isfini: if not await _innerloop(core, todo, done): break
async def docConfdefs(ctor, reflink=':ref:`devops-cell-config`', doc_title=None): cls = s_dyndeps.tryDynLocal(ctor) if not hasattr(cls, 'confdefs'): raise Exception('ctor must have a confdefs attr') rst = s_autodoc.RstHelp() clsname = cls.__name__ conf = cls.initCellConf() # type: s_config.Config if doc_title is None: doc_title = clsname rst.addHead(f'{doc_title} Configuration Options', lvl=0, link=f'.. _autodoc-{clsname.lower()}-conf:') rst.addLines(f'The following are boot-time configuration options for the cell.') rst.addLines(f'See {reflink} for details on how to set these options.') # access raw config data # Get envar and argparse mapping name2envar = conf.getEnvarMapping() name2cmdline = conf.getCmdlineMapping() schema = conf.json_schema.get('properties', {}) for name, conf in sorted(schema.items(), key=lambda x: x[0]): if conf.get('hideconf'): continue nodesc = f'No description available for ``{name}``.' hname = name if ':' in name: hname = name.replace(':', raw_back_slash_colon) rst.addHead(hname, lvl=1) desc = conf.get('description', nodesc) if not desc.endswith('.'): # pragma: no cover logger.warning(f'Description for [{name}] is missing a period.') lines = [] lines.append(desc) extended_description = conf.get('extended_description') if extended_description: lines.append('\n') lines.append(extended_description) # Type/additional information lines.append('\n') ctyp = conf.get('type') lines.append('Type') lines.append(f' ``{ctyp}``\n') if ctyp == 'object': if conf.get('properties'): lines.append('Properties') lines.append(' The object expects the following properties:') data = {k: v for k, v in conf.items() if k not in ( 'description', 'default', 'type', 'hideconf', 'hidecmdl', )} parts = json.dumps(data, sort_keys=True, indent=2).split('\n') lines.append(' ::') lines.append('\n') lines.extend([f' {p}' for p in parts]) lines.append('\n') defval = conf.get('default', s_common.novalu) if defval is not s_common.novalu: lines.append('Default Value') lines.append(f' ``{repr(defval)}``\n') envar = name2envar.get(name) if envar: lines.append('Environment Variable') lines.append(f' ``{envar}``\n') cmdline = name2cmdline.get(name) if cmdline: lines.append('Command Line Argument') lines.append(f' ``--{cmdline}``\n') rst.addLines(*lines) return rst, clsname
async def __anit__(self, spawninfo): await s_base.Base.__anit__(self) self.pid = os.getpid() self.views = {} self.layers = {} self.nexsroot = None self.spawninfo = spawninfo self.conf = spawninfo.get('conf') self.iden = spawninfo.get('iden') self.dirn = spawninfo.get('dirn') self.stormcmds = {} self.storm_cmd_ctors = {} self.storm_cmd_cdefs = {} self.stormmods = spawninfo['storm']['mods'] self.pkginfo = spawninfo['storm']['pkgs'] self.stormpkgs = {} # name: pkgdef for pkgdef in self.pkginfo: await self._tryLoadStormPkg(pkgdef) for name, ctor in spawninfo['storm']['cmds']['ctors']: self.stormcmds[name] = ctor for name, cdef in spawninfo['storm']['cmds']['cdefs']: ctor = functools.partial(s_storm.PureCmd, cdef) self.stormcmds[name] = ctor self.libroot = spawninfo.get('storm').get('libs') self.boss = await s_boss.Boss.anit() self.onfini(self.boss.fini) self.model = s_datamodel.Model() self.model.addDataModels(spawninfo.get('model')) self.prox = await s_telepath.openurl(f'cell://{self.dirn}') self.onfini(self.prox.fini) self.hive = await s_hive.openurl(f'cell://{self.dirn}', name='*/hive') self.onfini(self.hive) # TODO cortex configured for remote auth... node = await self.hive.open(('auth',)) self.auth = await s_hiveauth.Auth.anit(node) self.onfini(self.auth.fini) for layrinfo in self.spawninfo.get('layers'): iden = layrinfo.get('iden') ctorname = layrinfo.get('ctor') ctor = s_dyndeps.tryDynLocal(ctorname) layrinfo['readonly'] = True layrdirn = s_common.genpath(self.dirn, 'layers', iden) layr = await ctor.anit(layrinfo, layrdirn) self.onfini(layr) self.layers[iden] = layr for viewinfo in self.spawninfo.get('views'): iden = viewinfo.get('iden') path = ('cortex', 'views', iden) node = await self.hive.open(path) view = await s_view.View.anit(self, node) self.onfini(view) self.views[iden] = view self.addStormDmon = self.prox.addStormDmon self.delStormDmon = self.prox.delStormDmon self.getStormDmon = self.prox.getStormDmon self.getStormDmons = self.prox.getStormDmons
async def docStormsvc(ctor): cls = s_dyndeps.tryDynLocal(ctor) if not hasattr(cls, 'cellapi'): raise Exception('ctor must have a cellapi attr') clsname = cls.__name__ cellapi = cls.cellapi if not issubclass(cellapi, s_stormsvc.StormSvc): raise Exception('cellapi must be a StormSvc implementation') # Make a dummy object class MockSess: def __init__(self): self.user = None class DummyLink: def __init__(self): self.info = {'sess': MockSess()} def get(self, key): return self.info.get(key) async with await cellapi.anit(s_common.novalu, DummyLink(), s_common.novalu) as obj: svcinfo = await obj.getStormSvcInfo() rst = s_autodoc.RstHelp() # Disable default python highlighting rst.addLines('.. highlight:: none\n') rst.addHead(f'{clsname} Storm Service') lines = [ 'The following Storm Packages and Commands are available from this service.', f'This documentation is generated for version ' f'{s_version.fmtVersion(*svcinfo.get("vers"))} of the service.', f'The Storm Service name is ``{svcinfo.get("name")}``.', ] rst.addLines(*lines) for pkg in svcinfo.get('pkgs'): pname = pkg.get('name') pver = pkg.get('version') commands = pkg.get('commands') hname = pname if ':' in pname: hname = pname.replace(':', raw_back_slash_colon) rst.addHead(f'Storm Package\\: {hname}', lvl=1) rst.addLines( f'This documentation for {pname} is generated for version {s_version.fmtVersion(*pver)}' ) if commands: rst.addHead('Storm Commands', lvl=2) rst.addLines( f'This package implements the following Storm Commands.\n') for cdef in commands: cname = cdef.get('name') cdesc = cdef.get('descr') cargs = cdef.get('cmdargs') # command names cannot have colons in them thankfully cref = f'.. _stormcmd-{pname.replace(":", "-")}-{cname.replace(".", "-")}:' rst.addHead(cname, lvl=3, link=cref) # Form the description lines = ['::\n'] # Generate help from args pars = s_storm.Parser(prog=cname, descr=cdesc) if cargs: for (argname, arginfo) in cargs: pars.add_argument(argname, **arginfo) pars.help() for line in pars.mesgs: if '\n' in line: for subl in line.split('\n'): lines.append(f' {subl}') else: lines.append(f' {line}') lines.append('\n') forms = cdef.get('forms', {}) iforms = forms.get('input') oforms = forms.get('output') nodedata = forms.get('nodedata') if iforms: line = 'The command is aware of how to automatically handle the following forms as input nodes:\n' lines.append(line) for form in iforms: lines.append(f'- ``{form}``') lines.append('\n') if oforms: line = 'The command may make the following types of nodes in the graph as a result of its execution:\n' lines.append(line) for form in oforms: lines.append(f'- ``{form}``') lines.append('\n') if nodedata: line = 'The command may add nodedata with the following keys to the corresponding forms:\n' lines.append(line) for key, form in nodedata: lines.append(f'- ``{key}`` on ``{form}``') lines.append('\n') rst.addLines(*lines) # TODO: Modules are not currently documented. return rst, clsname