synapse 2.207.0__py311-none-any.whl → 2.209.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 +12 -3
- synapse/lib/boss.py +5 -1
- synapse/lib/layer.py +23 -1
- synapse/lib/modelrev.py +27 -4
- synapse/lib/rstorm.py +3 -1
- synapse/lib/storm.lark +2 -2
- synapse/lib/storm.py +5 -5
- synapse/lib/stormlib/auth.py +1 -1
- synapse/lib/stormlib/cortex.py +1 -1
- synapse/lib/stormlib/vault.py +1 -1
- synapse/lib/stormsvc.py +1 -1
- synapse/lib/stormtypes.py +31 -22
- synapse/lib/task.py +7 -1
- synapse/lib/time.py +8 -2
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +25 -7
- synapse/tests/test_cortex.py +4 -4
- synapse/tests/test_datamodel.py +1 -1
- synapse/tests/test_lib_ast.py +5 -5
- synapse/tests/test_lib_boss.py +2 -2
- synapse/tests/test_lib_nexus.py +5 -11
- synapse/tests/test_lib_rstorm.py +4 -3
- synapse/tests/test_lib_storm.py +83 -6
- synapse/tests/test_lib_stormhttp.py +8 -8
- synapse/tests/test_lib_stormlib_cache.py +2 -2
- synapse/tests/test_lib_stormlib_scrape.py +1 -1
- synapse/tests/test_lib_stormlib_storm.py +63 -0
- synapse/tests/test_lib_stormsvc.py +3 -0
- synapse/tests/test_lib_stormtypes.py +171 -12
- synapse/tests/test_lib_trigger.py +3 -4
- synapse/tests/test_lib_view.py +25 -3
- synapse/tests/test_tools_csvtool.py +1 -1
- {synapse-2.207.0.dist-info → synapse-2.209.0.dist-info}/METADATA +6 -6
- {synapse-2.207.0.dist-info → synapse-2.209.0.dist-info}/RECORD +37 -37
- {synapse-2.207.0.dist-info → synapse-2.209.0.dist-info}/WHEEL +1 -1
- {synapse-2.207.0.dist-info → synapse-2.209.0.dist-info}/licenses/LICENSE +0 -0
- {synapse-2.207.0.dist-info → synapse-2.209.0.dist-info}/top_level.txt +0 -0
synapse/cortex.py
CHANGED
|
@@ -1581,6 +1581,9 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
1581
1581
|
for layer in self.layers.values():
|
|
1582
1582
|
await layer.initLayerActive()
|
|
1583
1583
|
|
|
1584
|
+
for pkgdef in list(self.stormpkgs.values()):
|
|
1585
|
+
self._runStormPkgOnload(pkgdef)
|
|
1586
|
+
|
|
1584
1587
|
self.runActiveTask(_runMigrations())
|
|
1585
1588
|
|
|
1586
1589
|
await self.initStormPool()
|
|
@@ -2638,6 +2641,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2638
2641
|
return
|
|
2639
2642
|
|
|
2640
2643
|
self.loadStormPkg(pkgdef)
|
|
2644
|
+
self._runStormPkgOnload(pkgdef)
|
|
2641
2645
|
self.pkgdefs.set(name, pkgdef)
|
|
2642
2646
|
|
|
2643
2647
|
self._clearPermDefs()
|
|
@@ -2929,9 +2933,13 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2929
2933
|
self._initEasyPerm(gdef)
|
|
2930
2934
|
self.pkggraphs[gdef['iden']] = gdef
|
|
2931
2935
|
|
|
2936
|
+
def _runStormPkgOnload(self, pkgdef):
|
|
2937
|
+
name = pkgdef.get('name')
|
|
2932
2938
|
onload = pkgdef.get('onload')
|
|
2939
|
+
|
|
2933
2940
|
if onload is not None and self.isactive:
|
|
2934
2941
|
async def _onload():
|
|
2942
|
+
await self.fire('core:pkg:onload:start', pkg=name)
|
|
2935
2943
|
try:
|
|
2936
2944
|
async for mesg in self.storm(onload):
|
|
2937
2945
|
if mesg[0] == 'print':
|
|
@@ -2943,10 +2951,11 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
2943
2951
|
await asyncio.sleep(0)
|
|
2944
2952
|
except asyncio.CancelledError: # pragma: no cover
|
|
2945
2953
|
raise
|
|
2946
|
-
except Exception: # pragma: no cover
|
|
2947
|
-
logger.warning(f'onload failed for package: {name}')
|
|
2954
|
+
except Exception as exc: # pragma: no cover
|
|
2955
|
+
logger.warning(f'onload failed for package: {name}', exc_info=exc)
|
|
2948
2956
|
await self.fire('core:pkg:onload:complete', pkg=name)
|
|
2949
|
-
|
|
2957
|
+
|
|
2958
|
+
self.runActiveTask(_onload())
|
|
2950
2959
|
|
|
2951
2960
|
# N.B. This function is intentionally not async in order to prevent possible user race conditions for code
|
|
2952
2961
|
# executing outside of the nexus lock.
|
synapse/lib/boss.py
CHANGED
|
@@ -10,6 +10,10 @@ class Boss(s_base.Base):
|
|
|
10
10
|
|
|
11
11
|
'''
|
|
12
12
|
An object to track "promoted" async tasks.
|
|
13
|
+
|
|
14
|
+
Promoted tasks are asyncio tasks, wrapped in a synapse task
|
|
15
|
+
(``s_task.Task``), that are visible to storm users via the task tracking
|
|
16
|
+
libs/commands such as ``ps.list`` and ``$lib.ps.list()``.
|
|
13
17
|
'''
|
|
14
18
|
async def __anit__(self):
|
|
15
19
|
await s_base.Base.__anit__(self)
|
|
@@ -45,7 +49,7 @@ class Boss(s_base.Base):
|
|
|
45
49
|
|
|
46
50
|
async def promotetask(self, task, name, user, info=None, taskiden=None):
|
|
47
51
|
|
|
48
|
-
synt =
|
|
52
|
+
synt = s_task.syntask(task)
|
|
49
53
|
|
|
50
54
|
if synt is not None:
|
|
51
55
|
|
synapse/lib/layer.py
CHANGED
|
@@ -1569,7 +1569,10 @@ class Layer(s_nexus.Pusher):
|
|
|
1569
1569
|
await self.initUpstreamSync(uplayr)
|
|
1570
1570
|
|
|
1571
1571
|
async def initLayerPassive(self):
|
|
1572
|
+
await self._stopMirror()
|
|
1573
|
+
self._stopUpstream()
|
|
1572
1574
|
|
|
1575
|
+
async def _stopMirror(self):
|
|
1573
1576
|
if self.leadtask is not None:
|
|
1574
1577
|
self.leadtask.cancel()
|
|
1575
1578
|
self.leadtask = None
|
|
@@ -1578,6 +1581,7 @@ class Layer(s_nexus.Pusher):
|
|
|
1578
1581
|
await self.leader.fini()
|
|
1579
1582
|
self.leader = None
|
|
1580
1583
|
|
|
1584
|
+
def _stopUpstream(self):
|
|
1581
1585
|
[t.cancel() for t in self.activetasks]
|
|
1582
1586
|
self.activetasks.clear()
|
|
1583
1587
|
|
|
@@ -2786,6 +2790,11 @@ class Layer(s_nexus.Pusher):
|
|
|
2786
2790
|
async def setLayerInfo(self, name, valu):
|
|
2787
2791
|
if name != 'readonly':
|
|
2788
2792
|
self._reqNotReadOnly()
|
|
2793
|
+
|
|
2794
|
+
if name in ('mirror', 'upstream') and valu is not None:
|
|
2795
|
+
mesg = 'Layer only supports setting "mirror" and "upstream" to None.'
|
|
2796
|
+
raise s_exc.BadOptValu(mesg=mesg)
|
|
2797
|
+
|
|
2789
2798
|
return await self._push('layer:set', name, valu)
|
|
2790
2799
|
|
|
2791
2800
|
@s_nexus.Pusher.onPush('layer:set')
|
|
@@ -2793,17 +2802,25 @@ class Layer(s_nexus.Pusher):
|
|
|
2793
2802
|
'''
|
|
2794
2803
|
Set a mutable layer property.
|
|
2795
2804
|
'''
|
|
2796
|
-
if name not in ('name', 'desc', 'logedits', 'readonly'):
|
|
2805
|
+
if name not in ('name', 'desc', 'logedits', 'readonly', 'mirror', 'upstream'):
|
|
2797
2806
|
mesg = f'{name} is not a valid layer info key'
|
|
2798
2807
|
raise s_exc.BadOptValu(mesg=mesg)
|
|
2799
2808
|
|
|
2800
2809
|
if name == 'logedits':
|
|
2801
2810
|
valu = bool(valu)
|
|
2802
2811
|
self.logedits = valu
|
|
2812
|
+
|
|
2803
2813
|
elif name == 'readonly':
|
|
2804
2814
|
valu = bool(valu)
|
|
2805
2815
|
self.readonly = valu
|
|
2806
2816
|
|
|
2817
|
+
elif name == 'mirror' and valu is None:
|
|
2818
|
+
await self._stopMirror()
|
|
2819
|
+
self.ismirror = False
|
|
2820
|
+
|
|
2821
|
+
elif name == 'upstream' and valu is None:
|
|
2822
|
+
self._stopUpstream()
|
|
2823
|
+
|
|
2807
2824
|
# TODO when we can set more props, we may need to parse values.
|
|
2808
2825
|
if valu is None:
|
|
2809
2826
|
self.layrinfo.pop(name, None)
|
|
@@ -4382,6 +4399,11 @@ class Layer(s_nexus.Pusher):
|
|
|
4382
4399
|
async for verb, n2iden in self.iterNodeEdgesN1(buid):
|
|
4383
4400
|
edits.append((EDIT_EDGE_ADD, (verb, n2iden), ()))
|
|
4384
4401
|
|
|
4402
|
+
if len(edits) >= 100:
|
|
4403
|
+
yield nodeedit
|
|
4404
|
+
edits = []
|
|
4405
|
+
nodeedit = (buid, form, edits)
|
|
4406
|
+
|
|
4385
4407
|
yield nodeedit
|
|
4386
4408
|
|
|
4387
4409
|
async def initUpstreamSync(self, url):
|
synapse/lib/modelrev.py
CHANGED
|
@@ -1466,6 +1466,7 @@ class ModelMigration_0_2_31:
|
|
|
1466
1466
|
if (v2_2 := props.get('v2_2')) is not None:
|
|
1467
1467
|
propvalu, stortype = v2_2
|
|
1468
1468
|
if not s_infotech.isValidCpe22(propvalu):
|
|
1469
|
+
logger.debug(f'Queueing invalid v2_2 value for deletion iden={s_common.ehex(buid)} valu={propvalu}')
|
|
1469
1470
|
await self._queueEdit(
|
|
1470
1471
|
layer.iden,
|
|
1471
1472
|
(buid, 'it:sec:cpe', (
|
|
@@ -1622,10 +1623,25 @@ class ModelMigration_0_2_31:
|
|
|
1622
1623
|
if propvalu is not None:
|
|
1623
1624
|
break
|
|
1624
1625
|
|
|
1625
|
-
|
|
1626
|
-
|
|
1626
|
+
if propvalu is None: # pragma: no cover
|
|
1627
|
+
# We didn't find a v2_2 value so remove this node
|
|
1628
|
+
await self.removeNode(buid)
|
|
1629
|
+
removed += 1
|
|
1630
|
+
|
|
1631
|
+
else:
|
|
1632
|
+
# We did find a v2_2 value so try to norm it and use that new value to move the node. If this fails,
|
|
1633
|
+
# remove the node.
|
|
1634
|
+
try:
|
|
1635
|
+
newvalu, _ = form.type.norm(propvalu)
|
|
1627
1636
|
|
|
1628
|
-
|
|
1637
|
+
except s_exc.BadTypeValu: # pragma: no cover
|
|
1638
|
+
logger.debug('Unexpectedly encountered invalid v2_2 prop: iden=%s valu=%s', s_common.ehex(buid), propvalu)
|
|
1639
|
+
await self.removeNode(buid)
|
|
1640
|
+
removed += 1
|
|
1641
|
+
|
|
1642
|
+
else:
|
|
1643
|
+
await self.moveNode(buid, newvalu)
|
|
1644
|
+
migrated += 1
|
|
1629
1645
|
|
|
1630
1646
|
elif action == 'remove':
|
|
1631
1647
|
newvalu = None
|
|
@@ -1636,10 +1652,17 @@ class ModelMigration_0_2_31:
|
|
|
1636
1652
|
if propvalu is None:
|
|
1637
1653
|
continue
|
|
1638
1654
|
|
|
1639
|
-
newvalu, _ = form.type.norm(propvalu)
|
|
1640
1655
|
# This prop is going to be the new primary value so delete the secondary prop
|
|
1641
1656
|
await self.editPropDel(layriden, buid, 'it:sec:cpe', 'v2_2', propvalu, stortype)
|
|
1642
1657
|
|
|
1658
|
+
# We did find a v2_2 value so try to norm it and use that new value to move the node. If this fails,
|
|
1659
|
+
# remove the node.
|
|
1660
|
+
try:
|
|
1661
|
+
newvalu, _ = form.type.norm(propvalu)
|
|
1662
|
+
except s_exc.BadTypeValu: # pragma: no cover
|
|
1663
|
+
logger.debug('Unexpectedly encountered invalid v2_2 prop: iden=%s valu=%s', s_common.ehex(buid), propvalu)
|
|
1664
|
+
continue
|
|
1665
|
+
|
|
1643
1666
|
# Oh yeah! Migrate the node instead of removing it
|
|
1644
1667
|
await self.moveNode(buid, newvalu)
|
|
1645
1668
|
|
synapse/lib/rstorm.py
CHANGED
|
@@ -168,7 +168,9 @@ class StormOutput(s_cmds_cortex.StormCmd):
|
|
|
168
168
|
if self.ctx.pop('storm-fail', None):
|
|
169
169
|
s_cmds_cortex.StormCmd._onErr(self, mesg, opts)
|
|
170
170
|
return
|
|
171
|
-
|
|
171
|
+
(errname, errinfo) = mesg[1]
|
|
172
|
+
errinfo.setdefault('_errname', errname)
|
|
173
|
+
raise s_exc.StormRuntimeError(**errinfo)
|
|
172
174
|
|
|
173
175
|
async def runCmdOpts(self, opts):
|
|
174
176
|
|
synapse/lib/storm.lark
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
%ignore CPPCOMMENT
|
|
6
6
|
%ignore WS
|
|
7
7
|
|
|
8
|
-
WS: /[\s]/+
|
|
8
|
+
WS.-1: /[\s]/+
|
|
9
9
|
|
|
10
10
|
// C comment: /* */
|
|
11
11
|
// From https://stackoverflow.com/a/36328890/6518334
|
|
@@ -466,7 +466,7 @@ TRIPLEQUOTEDSTRING: /'''.*?'''/s
|
|
|
466
466
|
DOUBLEQUOTEDSTRING: ESCAPED_STRING
|
|
467
467
|
SINGLEQUOTEDSTRING: /'[^']*'(?!')/
|
|
468
468
|
|
|
469
|
-
FORMATTEXT: /
|
|
469
|
+
FORMATTEXT.-1: /((?<!\\)(\\\\)*\\[`{]|[^`{])+/s
|
|
470
470
|
_formatexpr: "{" expror "}"
|
|
471
471
|
formatstring: "`" (_formatexpr | FORMATTEXT)* "`"
|
|
472
472
|
|
synapse/lib/storm.py
CHANGED
|
@@ -507,7 +507,7 @@ stormcmds = (
|
|
|
507
507
|
if ( $defv = $lib.null ) {
|
|
508
508
|
$defv = $lib.false
|
|
509
509
|
}
|
|
510
|
-
$text = `{
|
|
510
|
+
$text = `{('.').join($permdef.perm).ljust(32)} : {$permdef.desc} ( default: {$defv} )`
|
|
511
511
|
$lib.print($text)
|
|
512
512
|
}
|
|
513
513
|
} else {
|
|
@@ -594,7 +594,7 @@ stormcmds = (
|
|
|
594
594
|
$ssl = $lib.true
|
|
595
595
|
if $cmdopts.ssl_noverify { $ssl = $lib.false }
|
|
596
596
|
|
|
597
|
-
$headers = ({'X-Synapse-Version':
|
|
597
|
+
$headers = ({'X-Synapse-Version': ('.').join($lib.version.synapse())})
|
|
598
598
|
|
|
599
599
|
$resp = $lib.inet.http.get($cmdopts.url, ssl_verify=$ssl, headers=$headers)
|
|
600
600
|
|
|
@@ -629,7 +629,7 @@ stormcmds = (
|
|
|
629
629
|
$synv = $lib.version.synapse()
|
|
630
630
|
|
|
631
631
|
if $synv {
|
|
632
|
-
$synv =
|
|
632
|
+
$synv = ('.').join($synv)
|
|
633
633
|
}
|
|
634
634
|
|
|
635
635
|
if $comm {
|
|
@@ -1078,8 +1078,8 @@ stormcmds = (
|
|
|
1078
1078
|
$lib.print('entries: incunit incval required')
|
|
1079
1079
|
|
|
1080
1080
|
for $rec in $job.recs {
|
|
1081
|
-
$incunit =
|
|
1082
|
-
$incval =
|
|
1081
|
+
$incunit = (`{$rec.incunit}`).ljust(10)
|
|
1082
|
+
$incval = (`{$rec.incval}`).ljust(6)
|
|
1083
1083
|
|
|
1084
1084
|
$lib.print(' {incunit} {incval} {reqdict}',
|
|
1085
1085
|
incunit=$incunit, incval=$incval, reqdict=$rec.reqdict)
|
synapse/lib/stormlib/auth.py
CHANGED
synapse/lib/stormlib/cortex.py
CHANGED
|
@@ -107,7 +107,7 @@ stormcmds = [
|
|
|
107
107
|
if $perms {
|
|
108
108
|
$lib.print('The following user permissions are required to run this HTTP API endpoint:')
|
|
109
109
|
for $pdef in $perms {
|
|
110
|
-
$perm =
|
|
110
|
+
$perm = ('.').join($pdef.perm)
|
|
111
111
|
$lib.print($perm)
|
|
112
112
|
$lib.print(` default: {$pdef.default}`)
|
|
113
113
|
}
|
synapse/lib/stormlib/vault.py
CHANGED
synapse/lib/stormsvc.py
CHANGED
synapse/lib/stormtypes.py
CHANGED
|
@@ -1308,7 +1308,7 @@ class LibBase(Lib):
|
|
|
1308
1308
|
storm> if $lib.false { $lib.print('Is True') } else { $lib.print('Is False') }
|
|
1309
1309
|
Is False''',
|
|
1310
1310
|
'type': 'boolean', },
|
|
1311
|
-
{'name': 'text', 'desc':
|
|
1311
|
+
{'name': 'text', 'desc': "Get a Storm Text object. This is deprecated; please use a list to append strings to, and then use ``('.').join($listOfStr)`` to join them on demand.",
|
|
1312
1312
|
'deprecated': {'eolvers': '3.0.0'},
|
|
1313
1313
|
'type': {'type': 'function', '_funcname': '_text',
|
|
1314
1314
|
'args': (
|
|
@@ -1691,7 +1691,7 @@ class LibBase(Lib):
|
|
|
1691
1691
|
s_common.deprecated('$lib.text()', curv='2.194.0')
|
|
1692
1692
|
runt = s_scope.get('runt')
|
|
1693
1693
|
if runt:
|
|
1694
|
-
await runt.snap.warnonce(
|
|
1694
|
+
await runt.snap.warnonce("$lib.text() is deprecated. Please use a list to append strings to, and then use ``('').join($listOfStr)`` to join them on demand.")
|
|
1695
1695
|
valu = ''.join(args)
|
|
1696
1696
|
return Text(valu)
|
|
1697
1697
|
|
|
@@ -2023,15 +2023,8 @@ class LibStr(Lib):
|
|
|
2023
2023
|
A Storm Library for interacting with strings.
|
|
2024
2024
|
'''
|
|
2025
2025
|
_storm_locals = (
|
|
2026
|
-
{'name': 'join', 'desc': ''
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
Examples:
|
|
2030
|
-
Join together a list of strings with a dot separator::
|
|
2031
|
-
|
|
2032
|
-
storm> $foo=$lib.str.join('.', ('rep', 'vtx', 'tag')) $lib.print($foo)
|
|
2033
|
-
|
|
2034
|
-
rep.vtx.tag''',
|
|
2026
|
+
{'name': 'join', 'desc': 'Join items into a string using a separator.',
|
|
2027
|
+
# 'deprecated': {'eolvers': 'v3.0.0', 'mesg': 'Use ``('').join($foo, $bar, $baz, ....)`` instead.'},
|
|
2035
2028
|
'type': {'type': 'function', '_funcname': 'join',
|
|
2036
2029
|
'args': (
|
|
2037
2030
|
{'name': 'sepr', 'type': 'str', 'desc': 'The separator used to join strings with.', },
|
|
@@ -2039,22 +2032,14 @@ class LibStr(Lib):
|
|
|
2039
2032
|
),
|
|
2040
2033
|
'returns': {'type': 'str', 'desc': 'The joined string.', }}},
|
|
2041
2034
|
{'name': 'concat', 'desc': 'Concatenate a set of strings together.',
|
|
2035
|
+
# 'deprecated': {'eolvers': 'v3.0.0', 'mesg': "Use ``('').join($foo, $bar, $baz, ....)`` instead."},
|
|
2042
2036
|
'type': {'type': 'function', '_funcname': 'concat',
|
|
2043
2037
|
'args': (
|
|
2044
2038
|
{'name': '*args', 'type': 'any', 'desc': 'Items to join together.', },
|
|
2045
2039
|
),
|
|
2046
2040
|
'returns': {'type': 'str', 'desc': 'The joined string.', }}},
|
|
2047
|
-
{'name': 'format', 'desc': ''
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
Examples:
|
|
2051
|
-
Format a string with a fixed argument and a variable::
|
|
2052
|
-
|
|
2053
|
-
storm> $list=(1,2,3,4)
|
|
2054
|
-
$str=$lib.str.format('Hello {name}, your list is {list}!', name='Reader', list=$list)
|
|
2055
|
-
$lib.print($str)
|
|
2056
|
-
|
|
2057
|
-
Hello Reader, your list is ['1', '2', '3', '4']!''',
|
|
2041
|
+
{'name': 'format', 'desc': 'Format a text string.',
|
|
2042
|
+
# 'deprecated': {'eolvers': 'v3.0.0', 'mesg': 'Use ``$mystr.format(foo=$bar)`` instead.'},
|
|
2058
2043
|
'type': {'type': 'function', '_funcname': 'format',
|
|
2059
2044
|
'args': (
|
|
2060
2045
|
{'name': 'text', 'type': 'str', 'desc': 'The base text string.', },
|
|
@@ -2065,6 +2050,10 @@ class LibStr(Lib):
|
|
|
2065
2050
|
)
|
|
2066
2051
|
_storm_lib_path = ('str',)
|
|
2067
2052
|
|
|
2053
|
+
# _lib_str_join_depr_mesg = '$lib.str.join(), use "$sepr.join($items)" instead.'
|
|
2054
|
+
# _lib_str_concat_depr_mesg = "$lib.str.concat(), use ('').join($foo, $bar, $baz, ....) instead."
|
|
2055
|
+
# _lib_str_format_depr_mesg = '$lib.str.format(), use "$mystr.format(foo=$bar)" instead.'
|
|
2056
|
+
|
|
2068
2057
|
def getObjLocals(self):
|
|
2069
2058
|
return {
|
|
2070
2059
|
'join': self.join,
|
|
@@ -2074,17 +2063,29 @@ class LibStr(Lib):
|
|
|
2074
2063
|
|
|
2075
2064
|
@stormfunc(readonly=True)
|
|
2076
2065
|
async def concat(self, *args):
|
|
2066
|
+
# s_common.deprecated(self._lib_str_concat_depr_mesg)
|
|
2067
|
+
# runt = s_scope.get('runt')
|
|
2068
|
+
# if runt:
|
|
2069
|
+
# await runt.snap.warnonce(self._lib_str_concat_depr_mesg)
|
|
2077
2070
|
strs = [await tostr(a) for a in args]
|
|
2078
2071
|
return ''.join(strs)
|
|
2079
2072
|
|
|
2080
2073
|
@stormfunc(readonly=True)
|
|
2081
2074
|
async def format(self, text, **kwargs):
|
|
2075
|
+
# s_common.deprecated(self._lib_str_format_depr_mesg)
|
|
2076
|
+
# runt = s_scope.get('runt')
|
|
2077
|
+
# if runt:
|
|
2078
|
+
# await runt.snap.warnonce(self._lib_str_format_depr_mesg)
|
|
2082
2079
|
text = await kwarg_format(text, **kwargs)
|
|
2083
2080
|
|
|
2084
2081
|
return text
|
|
2085
2082
|
|
|
2086
2083
|
@stormfunc(readonly=True)
|
|
2087
2084
|
async def join(self, sepr, items):
|
|
2085
|
+
# s_common.deprecated(self._lib_str_join_depr_mesg)
|
|
2086
|
+
# runt = s_scope.get('runt')
|
|
2087
|
+
# if runt:
|
|
2088
|
+
# await runt.snap.warnonce(self._lib_str_join_depr_mesg)
|
|
2088
2089
|
strs = [await tostr(item) async for item in toiter(items)]
|
|
2089
2090
|
return sepr.join(strs)
|
|
2090
2091
|
|
|
@@ -7668,10 +7669,18 @@ class Layer(Prim):
|
|
|
7668
7669
|
valu = None
|
|
7669
7670
|
else:
|
|
7670
7671
|
valu = await tostr(await toprim(valu), noneok=True)
|
|
7672
|
+
|
|
7671
7673
|
elif name == 'logedits':
|
|
7672
7674
|
valu = await tobool(valu)
|
|
7675
|
+
|
|
7673
7676
|
elif name == 'readonly':
|
|
7674
7677
|
valu = await tobool(valu)
|
|
7678
|
+
|
|
7679
|
+
elif name in ('mirror', 'upstream'):
|
|
7680
|
+
if (valu := await toprim(valu)) is not None:
|
|
7681
|
+
mesg = 'Layer only supports setting "mirror" and "upstream" to null.'
|
|
7682
|
+
raise s_exc.BadOptValu(mesg=mesg)
|
|
7683
|
+
|
|
7675
7684
|
else:
|
|
7676
7685
|
mesg = f'Layer does not support setting: {name}'
|
|
7677
7686
|
raise s_exc.BadOptValu(mesg=mesg)
|
synapse/lib/task.py
CHANGED
|
@@ -132,12 +132,18 @@ def loop():
|
|
|
132
132
|
except Exception:
|
|
133
133
|
return None
|
|
134
134
|
|
|
135
|
+
def syntask(task):
|
|
136
|
+
'''
|
|
137
|
+
Return the synapse task associated with the provided asyncio task.
|
|
138
|
+
'''
|
|
139
|
+
return getattr(task, '_syn_task', None)
|
|
140
|
+
|
|
135
141
|
def current():
|
|
136
142
|
'''
|
|
137
143
|
Return the current synapse task.
|
|
138
144
|
'''
|
|
139
145
|
task = asyncio.current_task()
|
|
140
|
-
return
|
|
146
|
+
return syntask(task)
|
|
141
147
|
|
|
142
148
|
def user():
|
|
143
149
|
'''
|
synapse/lib/time.py
CHANGED
|
@@ -312,5 +312,11 @@ def toUTC(tick, fromzone):
|
|
|
312
312
|
mesg = f'Unknown timezone: {fromzone}'
|
|
313
313
|
raise s_exc.BadArg(mesg=mesg) from e
|
|
314
314
|
|
|
315
|
-
base = datetime.datetime(1970, 1, 1
|
|
316
|
-
|
|
315
|
+
base = datetime.datetime(1970, 1, 1) + datetime.timedelta(milliseconds=tick)
|
|
316
|
+
try:
|
|
317
|
+
localized = tz.localize(base, is_dst=None)
|
|
318
|
+
except pytz.exceptions.AmbiguousTimeError as e:
|
|
319
|
+
mesg = f'Ambiguous time: {base} {fromzone}'
|
|
320
|
+
raise s_exc.BadArg(mesg=mesg) from e
|
|
321
|
+
|
|
322
|
+
return int(localized.astimezone(pytz.UTC).timestamp() * 1000)
|
synapse/lib/version.py
CHANGED
|
@@ -223,6 +223,6 @@ def reqVersion(valu, reqver,
|
|
|
223
223
|
##############################################################################
|
|
224
224
|
# The following are touched during the release process by bumpversion.
|
|
225
225
|
# Do not modify these directly.
|
|
226
|
-
version = (2,
|
|
226
|
+
version = (2, 209, 0)
|
|
227
227
|
verstring = '.'.join([str(x) for x in version])
|
|
228
|
-
commit = '
|
|
228
|
+
commit = '0e5089f5b2e5da0d93c93a99943ebbd5fdb6cb4c'
|
synapse/lib/view.py
CHANGED
|
@@ -8,6 +8,7 @@ import synapse.common as s_common
|
|
|
8
8
|
|
|
9
9
|
import synapse.lib.cell as s_cell
|
|
10
10
|
import synapse.lib.snap as s_snap
|
|
11
|
+
import synapse.lib.task as s_task
|
|
11
12
|
import synapse.lib.layer as s_layer
|
|
12
13
|
import synapse.lib.nexus as s_nexus
|
|
13
14
|
import synapse.lib.scope as s_scope
|
|
@@ -411,7 +412,7 @@ class View(s_nexus.Pusher): # type: ignore
|
|
|
411
412
|
|
|
412
413
|
nodeedits.append(nodeedit)
|
|
413
414
|
|
|
414
|
-
if len(nodeedits) ==
|
|
415
|
+
if len(nodeedits) == 5:
|
|
415
416
|
yield nodeedits
|
|
416
417
|
nodeedits.clear()
|
|
417
418
|
|
|
@@ -431,7 +432,7 @@ class View(s_nexus.Pusher): # type: ignore
|
|
|
431
432
|
|
|
432
433
|
meta['time'] = s_common.now()
|
|
433
434
|
|
|
434
|
-
await snap.
|
|
435
|
+
await snap._applyNodeEdits(edits, meta)
|
|
435
436
|
await asyncio.sleep(0)
|
|
436
437
|
|
|
437
438
|
count += len(edits)
|
|
@@ -1000,7 +1001,11 @@ class View(s_nexus.Pusher): # type: ignore
|
|
|
1000
1001
|
keepalive = opts.get('keepalive')
|
|
1001
1002
|
if keepalive is not None and keepalive <= 0:
|
|
1002
1003
|
raise s_exc.BadArg(mesg=f'keepalive must be > 0; got {keepalive}')
|
|
1003
|
-
|
|
1004
|
+
|
|
1005
|
+
if (synt := s_task.current()) is None:
|
|
1006
|
+
# we only want to promote if we aren't already a syntask because we're probably a worker task that shouldn't
|
|
1007
|
+
# show up in the main task list
|
|
1008
|
+
synt = await self.core.boss.promote('storm', user=user, info=taskinfo, taskiden=taskiden)
|
|
1004
1009
|
|
|
1005
1010
|
show = opts.get('show', set())
|
|
1006
1011
|
|
|
@@ -1462,8 +1467,6 @@ class View(s_nexus.Pusher): # type: ignore
|
|
|
1462
1467
|
Merge this view into its parent. All changes made to this view will be applied to the parent. Parent's
|
|
1463
1468
|
triggers will be run.
|
|
1464
1469
|
'''
|
|
1465
|
-
fromlayr = self.layers[0]
|
|
1466
|
-
|
|
1467
1470
|
if useriden is None:
|
|
1468
1471
|
user = await self.core.auth.getUserByName('root')
|
|
1469
1472
|
else:
|
|
@@ -1476,10 +1479,25 @@ class View(s_nexus.Pusher): # type: ignore
|
|
|
1476
1479
|
|
|
1477
1480
|
async with await self.parent.snap(user=user) as snap:
|
|
1478
1481
|
|
|
1482
|
+
async def chunked():
|
|
1483
|
+
nodeedits = []
|
|
1484
|
+
|
|
1485
|
+
async for nodeedit in self.layers[0].iterLayerNodeEdits():
|
|
1486
|
+
|
|
1487
|
+
nodeedits.append(nodeedit)
|
|
1488
|
+
|
|
1489
|
+
if len(nodeedits) == 5:
|
|
1490
|
+
yield nodeedits
|
|
1491
|
+
nodeedits.clear()
|
|
1492
|
+
|
|
1493
|
+
if nodeedits:
|
|
1494
|
+
yield nodeedits
|
|
1495
|
+
|
|
1479
1496
|
meta = await snap.getSnapMeta()
|
|
1480
|
-
async for
|
|
1497
|
+
async for edits in chunked():
|
|
1481
1498
|
meta['time'] = s_common.now()
|
|
1482
|
-
await snap.
|
|
1499
|
+
await snap._applyNodeEdits(edits, meta)
|
|
1500
|
+
await asyncio.sleep(0)
|
|
1483
1501
|
|
|
1484
1502
|
async def swapLayer(self):
|
|
1485
1503
|
oldlayr = self.layers[0]
|
synapse/tests/test_cortex.py
CHANGED
|
@@ -1240,7 +1240,7 @@ class CortexTest(s_t_utils.SynTest):
|
|
|
1240
1240
|
$ddef = $lib.dmon.add(${
|
|
1241
1241
|
$lib.print(hi)
|
|
1242
1242
|
$lib.warn(omg)
|
|
1243
|
-
$s =
|
|
1243
|
+
$s = `Running {$auto.type} {$auto.iden}`
|
|
1244
1244
|
$lib.log.info($s, ({"iden": $auto.iden}))
|
|
1245
1245
|
$que = $lib.queue.get(foo)
|
|
1246
1246
|
$que.put(done)
|
|
@@ -5224,7 +5224,7 @@ class CortexBasicTest(s_t_utils.SynTest):
|
|
|
5224
5224
|
self.len(1, nodes)
|
|
5225
5225
|
self.nn(nodes[0].getTag('bar'))
|
|
5226
5226
|
|
|
5227
|
-
q = '[test:str=yop +#$
|
|
5227
|
+
q = '$t="{first}.{last}" [test:str=yop +#$t.format(first=foo, last=bar)]'
|
|
5228
5228
|
nodes = await core.nodes(q)
|
|
5229
5229
|
self.len(1, nodes)
|
|
5230
5230
|
self.nn(nodes[0].getTag('foo.bar'))
|
|
@@ -5695,7 +5695,7 @@ class CortexBasicTest(s_t_utils.SynTest):
|
|
|
5695
5695
|
self.len(1, nodes)
|
|
5696
5696
|
|
|
5697
5697
|
async def test_storm_order(self):
|
|
5698
|
-
q = '''[test:str=foo :hehe=bar] $tvar=() $tvar.append(1) $tvar.append(:hehe) $lib.print(
|
|
5698
|
+
q = '''[test:str=foo :hehe=bar] $tvar=() $tvar.append(1) $tvar.append(:hehe) $lib.print(('').join($tvar)) '''
|
|
5699
5699
|
async with self.getTestCore() as core:
|
|
5700
5700
|
mesgs = await core.stormlist(q)
|
|
5701
5701
|
self.stormIsInPrint('1bar', mesgs)
|
|
@@ -7731,7 +7731,7 @@ class CortexBasicTest(s_t_utils.SynTest):
|
|
|
7731
7731
|
$ddef = $lib.dmon.add(${
|
|
7732
7732
|
$lib.print(hi)
|
|
7733
7733
|
$lib.warn(omg)
|
|
7734
|
-
$s =
|
|
7734
|
+
$s = `Running {$auto.type} {$auto.iden}`
|
|
7735
7735
|
$lib.log.info($s, ({"iden": $auto.iden}))
|
|
7736
7736
|
})
|
|
7737
7737
|
''')
|
synapse/tests/test_datamodel.py
CHANGED
|
@@ -299,7 +299,7 @@ class DataModelTest(s_t_utils.SynTest):
|
|
|
299
299
|
syn:type:subof=comp $opts=:opts
|
|
300
300
|
-> syn:form:type $valu=$node.value()
|
|
301
301
|
for ($name, $thing) in $opts.fields {
|
|
302
|
-
$v
|
|
302
|
+
$v=`{$valu}:{$name}` syn:prop=$v
|
|
303
303
|
}
|
|
304
304
|
+syn:prop
|
|
305
305
|
-:ro=1
|
synapse/tests/test_lib_ast.py
CHANGED
|
@@ -74,9 +74,9 @@ foo_stormpkg = {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
function outer(arg1, add) {
|
|
77
|
-
$strbase =
|
|
77
|
+
$strbase = `(Run: {$counter}) we got back `
|
|
78
78
|
$reti = $inner($arg1, $add)
|
|
79
|
-
$mesg = $
|
|
79
|
+
$mesg = `{$strbase}{$reti}`
|
|
80
80
|
$counter = $( $counter + $add )
|
|
81
81
|
$lib.print("foobar is {foobar}", foobar=$foobar)
|
|
82
82
|
return ($mesg)
|
|
@@ -296,7 +296,7 @@ class AstTest(s_test.SynTest):
|
|
|
296
296
|
$newvar=:hehe
|
|
297
297
|
-.created
|
|
298
298
|
$s.append("yar {x}", x=$newvar)
|
|
299
|
-
$lib.print(
|
|
299
|
+
$lib.print(('').join($s))
|
|
300
300
|
'''
|
|
301
301
|
mesgs = await core.stormlist(q)
|
|
302
302
|
prints = [m[1]['mesg'] for m in mesgs if m[0] == 'print']
|
|
@@ -2029,7 +2029,7 @@ class AstTest(s_test.SynTest):
|
|
|
2029
2029
|
q = '$val=$lib.base64.decode("dmlzaQ==") function x(parm1=$val) { return($parm1) }'
|
|
2030
2030
|
self.len(0, await core.nodes(q))
|
|
2031
2031
|
|
|
2032
|
-
self.eq('foo', await core.callStorm('
|
|
2032
|
+
self.eq('foo', await core.callStorm('$template="{func}" return($template.format(func=foo))'))
|
|
2033
2033
|
|
|
2034
2034
|
msgs = await core.stormlist('$lib.null()')
|
|
2035
2035
|
erfo = [m for m in msgs if m[0] == 'err'][0]
|
|
@@ -3580,7 +3580,7 @@ class AstTest(s_test.SynTest):
|
|
|
3580
3580
|
|
|
3581
3581
|
q = '''
|
|
3582
3582
|
init { $foo = bar }
|
|
3583
|
-
init { $baz =
|
|
3583
|
+
init { $baz = `foo={$foo}` }
|
|
3584
3584
|
$lib.print($baz)
|
|
3585
3585
|
'''
|
|
3586
3586
|
msgs = await core.stormlist(q)
|
synapse/tests/test_lib_boss.py
CHANGED
|
@@ -56,8 +56,8 @@ class BossTest(s_test.SynTest):
|
|
|
56
56
|
iden = s_common.guid()
|
|
57
57
|
|
|
58
58
|
async def double_promote():
|
|
59
|
-
await boss.promote(
|
|
60
|
-
await boss.promote(
|
|
59
|
+
await boss.promote('double', root, taskiden=iden)
|
|
60
|
+
await boss.promote('double', root, taskiden=iden + iden)
|
|
61
61
|
|
|
62
62
|
coro = boss.schedCoro(double_promote())
|
|
63
63
|
self.true(await stream.wait(timeout=6))
|