synapse 2.222.0__py311-none-any.whl → 2.223.0__py311-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of synapse might be problematic. Click here for more details.
- synapse/cortex.py +109 -30
- synapse/cryotank.py +1 -1
- synapse/lib/ast.py +5 -3
- synapse/lib/nexus.py +1 -1
- synapse/lib/snap.py +15 -9
- synapse/lib/storm.py +0 -190
- synapse/lib/stormlib/auth.py +1 -1
- synapse/lib/stormlib/mime.py +15 -5
- synapse/lib/stormlib/pkg.py +598 -0
- synapse/lib/stormlib/task.py +115 -0
- synapse/lib/stormtypes.py +24 -174
- synapse/lib/trigger.py +16 -14
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +17 -14
- synapse/models/files.py +1 -1
- synapse/tests/test_cortex.py +1 -1
- synapse/tests/test_lib_aha.py +68 -53
- synapse/tests/test_lib_ast.py +3 -0
- synapse/tests/test_lib_cell.py +12 -12
- synapse/tests/test_lib_storm.py +31 -248
- synapse/tests/test_lib_stormlib_mime.py +24 -0
- synapse/tests/test_lib_stormlib_pkg.py +456 -0
- synapse/tests/test_lib_stormlib_task.py +98 -0
- synapse/tests/test_lib_stormtypes.py +0 -100
- synapse/tests/test_lib_trigger.py +66 -3
- synapse/tests/test_lib_view.py +53 -0
- synapse/tests/test_model_files.py +11 -0
- synapse/tools/cryo/cat.py +2 -1
- synapse/tools/cryo/list.py +2 -0
- {synapse-2.222.0.dist-info → synapse-2.223.0.dist-info}/METADATA +1 -1
- {synapse-2.222.0.dist-info → synapse-2.223.0.dist-info}/RECORD +34 -30
- {synapse-2.222.0.dist-info → synapse-2.223.0.dist-info}/WHEEL +0 -0
- {synapse-2.222.0.dist-info → synapse-2.223.0.dist-info}/licenses/LICENSE +0 -0
- {synapse-2.222.0.dist-info → synapse-2.223.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,598 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
|
|
3
|
+
import synapse.exc as s_exc
|
|
4
|
+
|
|
5
|
+
import synapse.lib.stormtypes as s_stormtypes
|
|
6
|
+
|
|
7
|
+
stormcmds = [
|
|
8
|
+
{
|
|
9
|
+
'name': 'pkg.list',
|
|
10
|
+
'descr': 'List the storm packages loaded in the cortex.',
|
|
11
|
+
'cmdargs': (
|
|
12
|
+
('--verbose', {'default': False, 'action': 'store_true',
|
|
13
|
+
'help': 'Display build time for each package.'}),
|
|
14
|
+
),
|
|
15
|
+
'storm': '''
|
|
16
|
+
init {
|
|
17
|
+
$conf = ({
|
|
18
|
+
"columns": [
|
|
19
|
+
{"name": "name", "width": 40},
|
|
20
|
+
{"name": "vers", "width": 10},
|
|
21
|
+
],
|
|
22
|
+
"separators": {
|
|
23
|
+
"row:outline": false,
|
|
24
|
+
"column:outline": false,
|
|
25
|
+
"header:row": "#",
|
|
26
|
+
"data:row": "",
|
|
27
|
+
"column": "",
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
if $cmdopts.verbose {
|
|
31
|
+
$conf.columns.append(({"name": "time", "width": 20}))
|
|
32
|
+
}
|
|
33
|
+
$printer = $lib.tabular.printer($conf)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
$pkgs = $lib.pkg.list()
|
|
37
|
+
|
|
38
|
+
if $($pkgs.size() > 0) {
|
|
39
|
+
$lib.print('Loaded storm packages:')
|
|
40
|
+
$lib.print($printer.header())
|
|
41
|
+
for $pkg in $pkgs {
|
|
42
|
+
$row = (
|
|
43
|
+
$pkg.name, $pkg.version,
|
|
44
|
+
)
|
|
45
|
+
if $cmdopts.verbose {
|
|
46
|
+
try {
|
|
47
|
+
$row.append($lib.time.format($pkg.build.time, '%Y-%m-%d %H:%M:%S'))
|
|
48
|
+
} catch StormRuntimeError as _ {
|
|
49
|
+
$row.append('not available')
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
$lib.print($printer.row($row))
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
$lib.print('No storm packages installed.')
|
|
56
|
+
}
|
|
57
|
+
'''
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
'name': 'pkg.perms.list',
|
|
61
|
+
'descr': 'List any permissions declared by the package.',
|
|
62
|
+
'cmdargs': (
|
|
63
|
+
('name', {'help': 'The name (or name prefix) of the package.', 'type': 'str'}),
|
|
64
|
+
),
|
|
65
|
+
'storm': '''
|
|
66
|
+
$pdef = $lib.null
|
|
67
|
+
for $pkg in $lib.pkg.list() {
|
|
68
|
+
if $pkg.name.startswith($cmdopts.name) {
|
|
69
|
+
$pdef = $pkg
|
|
70
|
+
break
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (not $pdef) {
|
|
75
|
+
$lib.warn(`Package ({$cmdopts.name}) not found!`)
|
|
76
|
+
} else {
|
|
77
|
+
if $pdef.perms {
|
|
78
|
+
$lib.print(`Package ({$cmdopts.name}) defines the following permissions:`)
|
|
79
|
+
for $permdef in $pdef.perms {
|
|
80
|
+
$defv = $permdef.default
|
|
81
|
+
if ( $defv = $lib.null ) {
|
|
82
|
+
$defv = $lib.false
|
|
83
|
+
}
|
|
84
|
+
$text = `{('.').join($permdef.perm).ljust(32)} : {$permdef.desc} ( default: {$defv} )`
|
|
85
|
+
$lib.print($text)
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
$lib.print(`Package ({$cmdopts.name}) contains no permissions definitions.`)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
'''
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
'name': 'pkg.del',
|
|
95
|
+
'descr': 'Remove a storm package from the cortex.',
|
|
96
|
+
'cmdargs': (
|
|
97
|
+
('name', {'help': 'The name (or name prefix) of the package to remove.'}),
|
|
98
|
+
),
|
|
99
|
+
'storm': '''
|
|
100
|
+
|
|
101
|
+
$pkgs = $lib.set()
|
|
102
|
+
|
|
103
|
+
for $pkg in $lib.pkg.list() {
|
|
104
|
+
if $pkg.name.startswith($cmdopts.name) {
|
|
105
|
+
$pkgs.add($pkg.name)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if $($pkgs.size() = 0) {
|
|
110
|
+
|
|
111
|
+
$lib.print('No package names match "{name}". Aborting.', name=$cmdopts.name)
|
|
112
|
+
|
|
113
|
+
} elif $($pkgs.size() = 1) {
|
|
114
|
+
|
|
115
|
+
$name = $pkgs.list().index(0)
|
|
116
|
+
$lib.print('Removing package: {name}', name=$name)
|
|
117
|
+
$lib.pkg.del($name)
|
|
118
|
+
|
|
119
|
+
} else {
|
|
120
|
+
|
|
121
|
+
$lib.print('Multiple package names match "{name}". Aborting.', name=$cmdopts.name)
|
|
122
|
+
|
|
123
|
+
}
|
|
124
|
+
'''
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
'name': 'pkg.docs',
|
|
128
|
+
'descr': 'Display documentation included in a storm package.',
|
|
129
|
+
'cmdargs': (
|
|
130
|
+
('name', {'help': 'The name (or name prefix) of the package.'}),
|
|
131
|
+
),
|
|
132
|
+
'storm': '''
|
|
133
|
+
$pdef = $lib.null
|
|
134
|
+
for $pkg in $lib.pkg.list() {
|
|
135
|
+
if $pkg.name.startswith($cmdopts.name) {
|
|
136
|
+
$pdef = $pkg
|
|
137
|
+
break
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (not $pdef) {
|
|
142
|
+
$lib.warn("Package ({name}) not found!", name=$cmdopts.name)
|
|
143
|
+
} else {
|
|
144
|
+
if $pdef.docs {
|
|
145
|
+
for $doc in $pdef.docs {
|
|
146
|
+
$lib.print($doc.content)
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
$lib.print("Package ({name}) contains no documentation.", name=$cmdopts.name)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
'''
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
'name': 'pkg.load',
|
|
156
|
+
'descr': 'Load a storm package from an HTTP URL.',
|
|
157
|
+
'cmdargs': (
|
|
158
|
+
('url', {'help': 'The HTTP URL to load the package from.'}),
|
|
159
|
+
('--raw', {'default': False, 'action': 'store_true',
|
|
160
|
+
'help': 'Response JSON is a raw package definition without an envelope.'}),
|
|
161
|
+
('--verify', {'default': False, 'action': 'store_true',
|
|
162
|
+
'help': 'Enforce code signature verification on the storm package.'}),
|
|
163
|
+
('--ssl-noverify', {'default': False, 'action': 'store_true',
|
|
164
|
+
'help': 'Specify to disable SSL verification of the server.'}),
|
|
165
|
+
),
|
|
166
|
+
'storm': '''
|
|
167
|
+
init {
|
|
168
|
+
$ssl = $lib.true
|
|
169
|
+
if $cmdopts.ssl_noverify { $ssl = $lib.false }
|
|
170
|
+
|
|
171
|
+
$headers = ({'X-Synapse-Version': ('.').join($lib.version.synapse())})
|
|
172
|
+
|
|
173
|
+
$resp = $lib.inet.http.get($cmdopts.url, ssl_verify=$ssl, headers=$headers)
|
|
174
|
+
|
|
175
|
+
if ($resp.code != 200) {
|
|
176
|
+
$lib.warn("pkg.load got HTTP code: {code} for URL: {url}", code=$resp.code, url=$cmdopts.url)
|
|
177
|
+
$lib.exit()
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
$reply = $resp.json()
|
|
181
|
+
if $cmdopts.raw {
|
|
182
|
+
$pkg = $reply
|
|
183
|
+
} else {
|
|
184
|
+
if ($reply.status != "ok") {
|
|
185
|
+
$lib.warn("pkg.load got JSON error: {code} for URL: {url}", code=$reply.code, url=$cmdopts.url)
|
|
186
|
+
$lib.exit()
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
$pkg = $reply.result
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
$pkd = $lib.pkg.add($pkg, verify=$cmdopts.verify)
|
|
193
|
+
|
|
194
|
+
$lib.print("Loaded Package: {name} @{version}", name=$pkg.name, version=$pkg.version)
|
|
195
|
+
}
|
|
196
|
+
''',
|
|
197
|
+
},
|
|
198
|
+
]
|
|
199
|
+
|
|
200
|
+
@s_stormtypes.registry.registerLib
|
|
201
|
+
class LibPkg(s_stormtypes.Lib):
|
|
202
|
+
'''
|
|
203
|
+
A Storm Library for interacting with Storm Packages.
|
|
204
|
+
'''
|
|
205
|
+
_storm_locals = (
|
|
206
|
+
{'name': 'add', 'desc': 'Add a Storm Package to the Cortex.',
|
|
207
|
+
'type': {'type': 'function', '_funcname': '_libPkgAdd',
|
|
208
|
+
'args': (
|
|
209
|
+
{'name': 'pkgdef', 'type': 'dict', 'desc': 'A Storm Package definition.', },
|
|
210
|
+
{'name': 'verify', 'type': 'boolean', 'default': False,
|
|
211
|
+
'desc': 'Verify storm package signature.', },
|
|
212
|
+
),
|
|
213
|
+
'returns': {'type': 'null', }}},
|
|
214
|
+
{'name': 'get', 'desc': 'Get a Storm Package from the Cortex.',
|
|
215
|
+
'type': {'type': 'function', '_funcname': '_libPkgGet',
|
|
216
|
+
'args': (
|
|
217
|
+
{'name': 'name', 'type': 'str', 'desc': 'A Storm Package name.', },
|
|
218
|
+
),
|
|
219
|
+
'returns': {'type': 'dict', 'desc': 'The Storm package definition.', }}},
|
|
220
|
+
{'name': 'has', 'desc': 'Check if a Storm Package is available in the Cortex.',
|
|
221
|
+
'type': {'type': 'function', '_funcname': '_libPkgHas',
|
|
222
|
+
'args': (
|
|
223
|
+
{'name': 'name', 'type': 'str',
|
|
224
|
+
'desc': 'A Storm Package name to check for the existence of.', },
|
|
225
|
+
),
|
|
226
|
+
'returns': {'type': 'boolean',
|
|
227
|
+
'desc': 'True if the package exists in the Cortex, False if it does not.', }}},
|
|
228
|
+
{'name': 'del', 'desc': 'Delete a Storm Package from the Cortex.',
|
|
229
|
+
'type': {'type': 'function', '_funcname': '_libPkgDel',
|
|
230
|
+
'args': (
|
|
231
|
+
{'name': 'name', 'type': 'str', 'desc': 'The name of the package to delete.', },
|
|
232
|
+
),
|
|
233
|
+
'returns': {'type': 'null', }}},
|
|
234
|
+
{'name': 'list', 'desc': 'Get a list of Storm Packages loaded in the Cortex.',
|
|
235
|
+
'type': {'type': 'function', '_funcname': '_libPkgList',
|
|
236
|
+
'returns': {'type': 'list', 'desc': 'A list of Storm Package definitions.', }}},
|
|
237
|
+
{'name': 'deps', 'desc': 'Verify the dependencies for a Storm Package.',
|
|
238
|
+
'type': {'type': 'function', '_funcname': '_libPkgDeps',
|
|
239
|
+
'args': (
|
|
240
|
+
{'name': 'pkgdef', 'type': 'dict', 'desc': 'A Storm Package definition.', },
|
|
241
|
+
),
|
|
242
|
+
'returns': {'type': 'dict', 'desc': 'A dictionary listing dependencies and if they are met.', }}},
|
|
243
|
+
{'name': 'vars',
|
|
244
|
+
'desc': "Get a dictionary representing the package's persistent variables.",
|
|
245
|
+
'type': {'type': 'function', '_funcname': '_libPkgVars',
|
|
246
|
+
'args': (
|
|
247
|
+
{'name': 'name', 'type': 'str',
|
|
248
|
+
'desc': 'A Storm Package name to get vars for.', },
|
|
249
|
+
),
|
|
250
|
+
'returns': {'type': 'pkg:vars', 'desc': 'A dictionary representing the package variables.', }}},
|
|
251
|
+
{'name': 'queues',
|
|
252
|
+
'desc': "Access namespaced Queues for a package.",
|
|
253
|
+
'type': {'type': 'function', '_funcname': '_libPkgQueues',
|
|
254
|
+
'args': (
|
|
255
|
+
{'name': 'name', 'type': 'str',
|
|
256
|
+
'desc': 'A Storm Package name to access Queues for.', },
|
|
257
|
+
),
|
|
258
|
+
'returns': {'type': 'pkg:queues', 'desc': 'An object for accessing the package Queues.', }}},
|
|
259
|
+
)
|
|
260
|
+
_storm_lib_perms = (
|
|
261
|
+
{'perm': ('power-ups', '<name>', 'admin'), 'gate': 'cortex',
|
|
262
|
+
'desc': 'Controls the ability to interact with the vars or Queues for a Storm Package by name.'},
|
|
263
|
+
)
|
|
264
|
+
_storm_lib_path = ('pkg',)
|
|
265
|
+
|
|
266
|
+
def getObjLocals(self):
|
|
267
|
+
return {
|
|
268
|
+
'add': self._libPkgAdd,
|
|
269
|
+
'get': self._libPkgGet,
|
|
270
|
+
'has': self._libPkgHas,
|
|
271
|
+
'del': self._libPkgDel,
|
|
272
|
+
'list': self._libPkgList,
|
|
273
|
+
'deps': self._libPkgDeps,
|
|
274
|
+
'vars': self._libPkgVars,
|
|
275
|
+
'queues': self._libPkgQueues,
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async def _libPkgAdd(self, pkgdef, verify=False):
|
|
279
|
+
self.runt.confirm(('pkg', 'add'), None)
|
|
280
|
+
pkgdef = await s_stormtypes.toprim(pkgdef)
|
|
281
|
+
verify = await s_stormtypes.tobool(verify)
|
|
282
|
+
await self.runt.snap.core.addStormPkg(pkgdef, verify=verify)
|
|
283
|
+
|
|
284
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
285
|
+
async def _libPkgGet(self, name):
|
|
286
|
+
name = await s_stormtypes.tostr(name)
|
|
287
|
+
pkgdef = await self.runt.snap.core.getStormPkg(name)
|
|
288
|
+
if pkgdef is None:
|
|
289
|
+
return None
|
|
290
|
+
|
|
291
|
+
return s_stormtypes.Dict(pkgdef)
|
|
292
|
+
|
|
293
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
294
|
+
async def _libPkgHas(self, name):
|
|
295
|
+
name = await s_stormtypes.tostr(name)
|
|
296
|
+
pkgdef = await self.runt.snap.core.getStormPkg(name)
|
|
297
|
+
if pkgdef is None:
|
|
298
|
+
return False
|
|
299
|
+
return True
|
|
300
|
+
|
|
301
|
+
async def _libPkgDel(self, name):
|
|
302
|
+
self.runt.confirm(('pkg', 'del'), None)
|
|
303
|
+
await self.runt.snap.core.delStormPkg(name)
|
|
304
|
+
|
|
305
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
306
|
+
async def _libPkgList(self):
|
|
307
|
+
pkgs = await self.runt.snap.core.getStormPkgs()
|
|
308
|
+
return list(sorted(pkgs, key=lambda x: x.get('name')))
|
|
309
|
+
|
|
310
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
311
|
+
async def _libPkgDeps(self, pkgdef):
|
|
312
|
+
pkgdef = await s_stormtypes.toprim(pkgdef)
|
|
313
|
+
return await self.runt.snap.core.verifyStormPkgDeps(pkgdef)
|
|
314
|
+
|
|
315
|
+
async def _libPkgVars(self, name):
|
|
316
|
+
name = await s_stormtypes.tostr(name)
|
|
317
|
+
s_stormtypes.confirm(('power-ups', name, 'admin'))
|
|
318
|
+
return PkgVars(self.runt, name)
|
|
319
|
+
|
|
320
|
+
async def _libPkgQueues(self, name):
|
|
321
|
+
name = await s_stormtypes.tostr(name)
|
|
322
|
+
s_stormtypes.confirm(('power-ups', name, 'admin'))
|
|
323
|
+
return PkgQueues(self.runt, name)
|
|
324
|
+
|
|
325
|
+
@s_stormtypes.registry.registerType
|
|
326
|
+
class PkgVars(s_stormtypes.Prim):
|
|
327
|
+
'''
|
|
328
|
+
The Storm deref/setitem/iter convention on top of pkg vars information.
|
|
329
|
+
'''
|
|
330
|
+
_storm_typename = 'pkg:vars'
|
|
331
|
+
_ismutable = True
|
|
332
|
+
|
|
333
|
+
def __init__(self, runt, valu, path=None):
|
|
334
|
+
s_stormtypes.Prim.__init__(self, valu, path=path)
|
|
335
|
+
self.runt = runt
|
|
336
|
+
|
|
337
|
+
def _reqPkgAdmin(self):
|
|
338
|
+
s_stormtypes.confirm(('power-ups', self.valu, 'admin'))
|
|
339
|
+
|
|
340
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
341
|
+
async def deref(self, name):
|
|
342
|
+
self._reqPkgAdmin()
|
|
343
|
+
name = await s_stormtypes.tostr(name)
|
|
344
|
+
return await self.runt.snap.core.getStormPkgVar(self.valu, name)
|
|
345
|
+
|
|
346
|
+
async def setitem(self, name, valu):
|
|
347
|
+
self._reqPkgAdmin()
|
|
348
|
+
name = await s_stormtypes.tostr(name)
|
|
349
|
+
|
|
350
|
+
if valu is s_stormtypes.undef:
|
|
351
|
+
await self.runt.snap.core.popStormPkgVar(self.valu, name)
|
|
352
|
+
return
|
|
353
|
+
|
|
354
|
+
valu = await s_stormtypes.toprim(valu)
|
|
355
|
+
await self.runt.snap.core.setStormPkgVar(self.valu, name, valu)
|
|
356
|
+
|
|
357
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
358
|
+
async def iter(self):
|
|
359
|
+
self._reqPkgAdmin()
|
|
360
|
+
async for name, valu in self.runt.snap.core.iterStormPkgVars(self.valu):
|
|
361
|
+
yield name, valu
|
|
362
|
+
await asyncio.sleep(0)
|
|
363
|
+
|
|
364
|
+
@s_stormtypes.registry.registerType
|
|
365
|
+
class PkgQueues(s_stormtypes.Prim):
|
|
366
|
+
'''
|
|
367
|
+
A StormLib API instance for interacting with persistent Queues for a package in the Cortex.
|
|
368
|
+
'''
|
|
369
|
+
_storm_locals = (
|
|
370
|
+
{'name': 'add', 'desc': 'Add a Queue for the package with a given name.',
|
|
371
|
+
'type': {'type': 'function', '_funcname': '_methPkgQueueAdd',
|
|
372
|
+
'args': (
|
|
373
|
+
{'name': 'name', 'type': 'str', 'desc': 'The name of the Queue to add.'},
|
|
374
|
+
),
|
|
375
|
+
'returns': {'type': 'pkg:queue'}}},
|
|
376
|
+
{'name': 'gen', 'desc': 'Add or get a Queue in a single operation.',
|
|
377
|
+
'type': {'type': 'function', '_funcname': '_methPkgQueueGen',
|
|
378
|
+
'args': (
|
|
379
|
+
{'name': 'name', 'type': 'str', 'desc': 'The name of the Queue to add or get.'},
|
|
380
|
+
),
|
|
381
|
+
'returns': {'type': 'pkg:queue'}}},
|
|
382
|
+
{'name': 'del', 'desc': 'Delete a given Queue.',
|
|
383
|
+
'type': {'type': 'function', '_funcname': '_methPkgQueueDel',
|
|
384
|
+
'args': (
|
|
385
|
+
{'name': 'name', 'type': 'str', 'desc': 'The name of the Queue to delete.'},
|
|
386
|
+
),
|
|
387
|
+
'returns': {'type': 'null'}}},
|
|
388
|
+
{'name': 'get', 'desc': 'Get an existing Queue.',
|
|
389
|
+
'type': {'type': 'function', '_funcname': '_methPkgQueueGet',
|
|
390
|
+
'args': (
|
|
391
|
+
{'name': 'name', 'type': 'str', 'desc': 'The name of the Queue to get.'},
|
|
392
|
+
),
|
|
393
|
+
'returns': {'type': 'pkg:queue', 'desc': 'A ``pkg:queue`` object.'}}},
|
|
394
|
+
{'name': 'list', 'desc': 'Get a list of the Queues for the package in the Cortex.',
|
|
395
|
+
'type': {'type': 'function', '_funcname': '_methPkgQueueList',
|
|
396
|
+
'returns': {'name': 'yields', 'type': 'dict', 'desc': 'Queue definitions for the package.'}}},
|
|
397
|
+
)
|
|
398
|
+
_storm_typename = 'pkg:queues'
|
|
399
|
+
_ismutable = False
|
|
400
|
+
|
|
401
|
+
def __init__(self, runt, valu, path=None):
|
|
402
|
+
s_stormtypes.Prim.__init__(self, valu, path=path)
|
|
403
|
+
self.runt = runt
|
|
404
|
+
self.locls.update(self.getObjLocals())
|
|
405
|
+
|
|
406
|
+
def getObjLocals(self):
|
|
407
|
+
return {
|
|
408
|
+
'add': self._methPkgQueueAdd,
|
|
409
|
+
'gen': self._methPkgQueueGen,
|
|
410
|
+
'del': self._methPkgQueueDel,
|
|
411
|
+
'get': self._methPkgQueueGet,
|
|
412
|
+
'list': self._methPkgQueueList,
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
def _reqPkgAdmin(self):
|
|
416
|
+
s_stormtypes.confirm(('power-ups', self.valu, 'admin'))
|
|
417
|
+
|
|
418
|
+
async def _methPkgQueueAdd(self, name):
|
|
419
|
+
self._reqPkgAdmin()
|
|
420
|
+
name = await s_stormtypes.tostr(name)
|
|
421
|
+
|
|
422
|
+
await self.runt.snap.core.addStormPkgQueue(self.valu, name)
|
|
423
|
+
return StormPkgQueue(self.runt, self.valu, name)
|
|
424
|
+
|
|
425
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
426
|
+
async def _methPkgQueueGet(self, name):
|
|
427
|
+
self._reqPkgAdmin()
|
|
428
|
+
name = await s_stormtypes.tostr(name)
|
|
429
|
+
|
|
430
|
+
await self.runt.snap.core.getStormPkgQueue(self.valu, name)
|
|
431
|
+
return StormPkgQueue(self.runt, self.valu, name)
|
|
432
|
+
|
|
433
|
+
async def _methPkgQueueGen(self, name):
|
|
434
|
+
try:
|
|
435
|
+
return await self._methPkgQueueGet(name)
|
|
436
|
+
except s_exc.NoSuchName:
|
|
437
|
+
return await self._methPkgQueueAdd(name)
|
|
438
|
+
|
|
439
|
+
async def _methPkgQueueDel(self, name):
|
|
440
|
+
self._reqPkgAdmin()
|
|
441
|
+
name = await s_stormtypes.tostr(name)
|
|
442
|
+
|
|
443
|
+
await self.runt.snap.core.delStormPkgQueue(self.valu, name)
|
|
444
|
+
|
|
445
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
446
|
+
async def _methPkgQueueList(self):
|
|
447
|
+
self._reqPkgAdmin()
|
|
448
|
+
async for pkginfo in self.runt.snap.core.listStormPkgQueues(pkgname=self.valu):
|
|
449
|
+
yield pkginfo
|
|
450
|
+
|
|
451
|
+
@s_stormtypes.registry.registerType
|
|
452
|
+
class StormPkgQueue(s_stormtypes.StormType):
|
|
453
|
+
'''
|
|
454
|
+
A StormLib API instance for a package Queue.
|
|
455
|
+
'''
|
|
456
|
+
_storm_locals = (
|
|
457
|
+
{'name': 'name', 'desc': 'The name of the Queue.', 'type': 'str'},
|
|
458
|
+
{'name': 'pkgname', 'desc': 'The name of the package the Queue belongs to.', 'type': 'str'},
|
|
459
|
+
{'name': 'get', 'desc': 'Get a particular item from the Queue.',
|
|
460
|
+
'type': {'type': 'function', '_funcname': '_methPkgQueueGet',
|
|
461
|
+
'args': (
|
|
462
|
+
{'name': 'offs', 'type': 'int', 'desc': 'The offset to retrieve an item from.', 'default': 0},
|
|
463
|
+
{'name': 'wait', 'type': 'boolean', 'default': True,
|
|
464
|
+
'desc': 'Wait for the offset to be available before returning the item.'},
|
|
465
|
+
),
|
|
466
|
+
'returns': {'type': 'list',
|
|
467
|
+
'desc': 'A tuple of the offset and the item from the Queue. If wait is false and '
|
|
468
|
+
'the offset is not present, null is returned.'}}},
|
|
469
|
+
{'name': 'pop', 'desc': 'Pop an item from the Queue at a specific offset.',
|
|
470
|
+
'type': {'type': 'function', '_funcname': '_methPkgQueuePop',
|
|
471
|
+
'args': (
|
|
472
|
+
{'name': 'offs', 'type': 'int', 'default': None,
|
|
473
|
+
'desc': 'Offset to pop the item from. If not specified, the first item in the Queue will be'
|
|
474
|
+
' popped.', },
|
|
475
|
+
{'name': 'wait', 'type': 'boolean', 'default': False,
|
|
476
|
+
'desc': 'Wait for an item to be available to pop.'},
|
|
477
|
+
),
|
|
478
|
+
'returns': {'type': 'list',
|
|
479
|
+
'desc': 'The offset and item popped from the Queue. If there is no item at the '
|
|
480
|
+
'offset or the Queue is empty and wait is false, it returns null.'}}},
|
|
481
|
+
{'name': 'put', 'desc': 'Put an item into the Queue.',
|
|
482
|
+
'type': {'type': 'function', '_funcname': '_methPkgQueuePut',
|
|
483
|
+
'args': (
|
|
484
|
+
{'name': 'item', 'type': 'prim', 'desc': 'The item being put into the Queue.'},
|
|
485
|
+
),
|
|
486
|
+
'returns': {'type': 'int', 'desc': 'The Queue offset of the item.'}}},
|
|
487
|
+
{'name': 'puts', 'desc': 'Put multiple items into the Queue.',
|
|
488
|
+
'type': {'type': 'function', '_funcname': '_methPkgQueuePuts',
|
|
489
|
+
'args': (
|
|
490
|
+
{'name': 'items', 'type': 'list', 'desc': 'The items to put into the Queue.'},
|
|
491
|
+
),
|
|
492
|
+
'returns': {'type': 'int', 'desc': 'The Queue offset of the first item.'}}},
|
|
493
|
+
{'name': 'gets', 'desc': 'Get multiple items from the Queue as a iterator.',
|
|
494
|
+
'type': {'type': 'function', '_funcname': '_methPkgQueueGets',
|
|
495
|
+
'args': (
|
|
496
|
+
{'name': 'offs', 'type': 'int', 'desc': 'The offset to retrieve an items from.', 'default': 0},
|
|
497
|
+
{'name': 'wait', 'type': 'boolean', 'default': True,
|
|
498
|
+
'desc': 'Wait for the offset to be available before returning the item.'},
|
|
499
|
+
{'name': 'size', 'type': 'int', 'desc': 'The maximum number of items to yield',
|
|
500
|
+
'default': None},
|
|
501
|
+
),
|
|
502
|
+
'returns': {'name': 'Yields', 'type': 'list', 'desc': 'Yields tuples of the offset and item.'}}},
|
|
503
|
+
{'name': 'cull', 'desc': 'Remove items from the Queue up to, and including, the offset.',
|
|
504
|
+
'type': {'type': 'function', '_funcname': '_methPkgQueueCull',
|
|
505
|
+
'args': (
|
|
506
|
+
{'name': 'offs', 'type': 'int', 'desc': 'The offset which to cull records from the Queue.'},
|
|
507
|
+
),
|
|
508
|
+
'returns': {'type': 'null'}}},
|
|
509
|
+
{'name': 'size', 'desc': 'Get the number of items in the Queue.',
|
|
510
|
+
'type': {'type': 'function', '_funcname': '_methPkgQueueSize',
|
|
511
|
+
'returns': {'type': 'int', 'desc': 'The number of items in the Queue.'}}},
|
|
512
|
+
)
|
|
513
|
+
_storm_typename = 'pkg:queue'
|
|
514
|
+
_ismutable = False
|
|
515
|
+
|
|
516
|
+
def __init__(self, runt, pkgname, name):
|
|
517
|
+
|
|
518
|
+
s_stormtypes.StormType.__init__(self)
|
|
519
|
+
self.runt = runt
|
|
520
|
+
self.name = name
|
|
521
|
+
self.pkgname = pkgname
|
|
522
|
+
|
|
523
|
+
self.locls.update(self.getObjLocals())
|
|
524
|
+
self.locls['name'] = self.name
|
|
525
|
+
self.locls['pkgname'] = self.pkgname
|
|
526
|
+
|
|
527
|
+
def __hash__(self):
|
|
528
|
+
return hash((self._storm_typename, self.pkgname, self.name))
|
|
529
|
+
|
|
530
|
+
def __eq__(self, othr):
|
|
531
|
+
if not isinstance(othr, type(self)):
|
|
532
|
+
return False
|
|
533
|
+
return self.pkgname == othr.pkgname and self.name == othr.name
|
|
534
|
+
|
|
535
|
+
def getObjLocals(self):
|
|
536
|
+
return {
|
|
537
|
+
'get': self._methPkgQueueGet,
|
|
538
|
+
'pop': self._methPkgQueuePop,
|
|
539
|
+
'put': self._methPkgQueuePut,
|
|
540
|
+
'puts': self._methPkgQueuePuts,
|
|
541
|
+
'gets': self._methPkgQueueGets,
|
|
542
|
+
'cull': self._methPkgQueueCull,
|
|
543
|
+
'size': self._methPkgQueueSize,
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
def _reqPkgAdmin(self):
|
|
547
|
+
s_stormtypes.confirm(('power-ups', self.pkgname, 'admin'))
|
|
548
|
+
|
|
549
|
+
async def _methPkgQueueCull(self, offs):
|
|
550
|
+
self._reqPkgAdmin()
|
|
551
|
+
offs = await s_stormtypes.toint(offs)
|
|
552
|
+
await self.runt.snap.core.stormPkgQueueCull(self.pkgname, self.name, offs)
|
|
553
|
+
|
|
554
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
555
|
+
async def _methPkgQueueSize(self):
|
|
556
|
+
self._reqPkgAdmin()
|
|
557
|
+
return await self.runt.snap.core.stormPkgQueueSize(self.pkgname, self.name)
|
|
558
|
+
|
|
559
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
560
|
+
async def _methPkgQueueGets(self, offs=0, wait=True, size=None):
|
|
561
|
+
self._reqPkgAdmin()
|
|
562
|
+
offs = await s_stormtypes.toint(offs)
|
|
563
|
+
wait = await s_stormtypes.tobool(wait)
|
|
564
|
+
size = await s_stormtypes.toint(size, noneok=True)
|
|
565
|
+
|
|
566
|
+
async for item in self.runt.snap.core.stormPkgQueueGets(self.pkgname, self.name, offs, wait=wait, size=size):
|
|
567
|
+
yield item
|
|
568
|
+
|
|
569
|
+
async def _methPkgQueuePuts(self, items):
|
|
570
|
+
self._reqPkgAdmin()
|
|
571
|
+
items = await s_stormtypes.toprim(items)
|
|
572
|
+
return await self.runt.snap.core.stormPkgQueuePuts(self.pkgname, self.name, items)
|
|
573
|
+
|
|
574
|
+
@s_stormtypes.stormfunc(readonly=True)
|
|
575
|
+
async def _methPkgQueueGet(self, offs=0, wait=True):
|
|
576
|
+
self._reqPkgAdmin()
|
|
577
|
+
offs = await s_stormtypes.toint(offs)
|
|
578
|
+
wait = await s_stormtypes.tobool(wait)
|
|
579
|
+
return await self.runt.snap.core.stormPkgQueueGet(self.pkgname, self.name, offs, wait=wait)
|
|
580
|
+
|
|
581
|
+
async def _methPkgQueuePop(self, offs=None, wait=False):
|
|
582
|
+
self._reqPkgAdmin()
|
|
583
|
+
offs = await s_stormtypes.toint(offs, noneok=True)
|
|
584
|
+
wait = await s_stormtypes.tobool(wait)
|
|
585
|
+
|
|
586
|
+
core = self.runt.snap.core
|
|
587
|
+
if offs is None:
|
|
588
|
+
async for item in core.stormPkgQueueGets(self.pkgname, self.name, 0, wait=wait):
|
|
589
|
+
return await core.stormPkgQueuePop(self.pkgname, self.name, item[0])
|
|
590
|
+
return
|
|
591
|
+
|
|
592
|
+
return await core.stormPkgQueuePop(self.pkgname, self.name, offs)
|
|
593
|
+
|
|
594
|
+
async def _methPkgQueuePut(self, item):
|
|
595
|
+
return await self._methPkgQueuePuts((item,))
|
|
596
|
+
|
|
597
|
+
async def stormrepr(self):
|
|
598
|
+
return f'{self._storm_typename}: {self.pkgname} - {self.name}'
|