synapse 2.166.0__py311-none-any.whl → 2.168.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/axon.py +4 -10
- synapse/cortex.py +55 -12
- synapse/exc.py +1 -0
- synapse/lib/aha.py +4 -1
- synapse/lib/base.py +11 -4
- synapse/lib/cell.py +11 -2
- synapse/lib/hive.py +11 -0
- synapse/lib/layer.py +2 -0
- synapse/lib/modelrev.py +6 -0
- synapse/lib/modules.py +1 -0
- synapse/lib/node.py +4 -2
- synapse/lib/schemas.py +1 -1
- synapse/lib/stormlib/aha.py +385 -20
- synapse/lib/stormlib/easyperm.py +8 -0
- synapse/lib/stormlib/macro.py +11 -18
- synapse/lib/stormlib/stix.py +1 -1
- synapse/lib/stormtypes.py +25 -2
- synapse/lib/types.py +2 -0
- synapse/lib/version.py +2 -2
- synapse/lib/view.py +5 -3
- synapse/models/base.py +8 -0
- synapse/models/files.py +3 -0
- synapse/models/planning.py +161 -0
- synapse/telepath.py +1 -0
- synapse/tests/files/stormpkg/dotstorm/dotstorm.yaml +3 -0
- synapse/tests/test_cortex.py +40 -3
- synapse/tests/test_lib_aha.py +8 -4
- synapse/tests/test_lib_cell.py +6 -2
- synapse/tests/test_lib_grammar.py +62 -64
- synapse/tests/test_lib_httpapi.py +1 -1
- synapse/tests/test_lib_rstorm.py +4 -4
- synapse/tests/test_lib_storm.py +3 -3
- synapse/tests/test_lib_stormlib_aha.py +196 -0
- synapse/tests/test_lib_stormlib_compression.py +12 -12
- synapse/tests/test_lib_stormlib_macro.py +94 -0
- synapse/tests/test_lib_stormlib_spooled.py +1 -1
- synapse/tests/test_lib_stormtypes.py +44 -33
- synapse/tests/test_lib_trigger.py +3 -3
- synapse/tests/test_lib_view.py +50 -3
- synapse/tests/test_model_files.py +3 -0
- synapse/tests/test_model_planning.py +126 -0
- synapse/tests/test_tools_genpkg.py +26 -0
- synapse/tests/test_tools_hiveload.py +1 -0
- synapse/tests/test_tools_hivesave.py +1 -0
- synapse/tests/utils.py +22 -3
- synapse/tools/autodoc.py +1 -1
- synapse/tools/hive/load.py +3 -0
- synapse/tools/hive/save.py +3 -0
- {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/METADATA +3 -3
- {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/RECORD +53 -50
- {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/LICENSE +0 -0
- {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/WHEEL +0 -0
- {synapse-2.166.0.dist-info → synapse-2.168.0.dist-info}/top_level.txt +0 -0
synapse/axon.py
CHANGED
|
@@ -1509,7 +1509,6 @@ class Axon(s_cell.Cell):
|
|
|
1509
1509
|
atimeout = aiohttp.ClientTimeout(total=timeout)
|
|
1510
1510
|
|
|
1511
1511
|
async with aiohttp.ClientSession(connector=connector, timeout=atimeout) as sess:
|
|
1512
|
-
|
|
1513
1512
|
try:
|
|
1514
1513
|
data = aiohttp.FormData()
|
|
1515
1514
|
data._is_multipart = True
|
|
@@ -1523,7 +1522,9 @@ class Axon(s_cell.Cell):
|
|
|
1523
1522
|
|
|
1524
1523
|
sha256 = field.get('sha256')
|
|
1525
1524
|
if sha256:
|
|
1526
|
-
|
|
1525
|
+
sha256b = s_common.uhex(sha256)
|
|
1526
|
+
await self._reqHas(sha256b)
|
|
1527
|
+
valu = self.get(sha256b)
|
|
1527
1528
|
else:
|
|
1528
1529
|
valu = field.get('value')
|
|
1529
1530
|
if not isinstance(valu, (bytes, str)):
|
|
@@ -1547,9 +1548,6 @@ class Axon(s_cell.Cell):
|
|
|
1547
1548
|
}
|
|
1548
1549
|
return info
|
|
1549
1550
|
|
|
1550
|
-
except asyncio.CancelledError: # pramga: no cover
|
|
1551
|
-
raise
|
|
1552
|
-
|
|
1553
1551
|
except Exception as e:
|
|
1554
1552
|
logger.exception(f'Error POSTing files to [{s_urlhelp.sanitizeUrl(url)}]')
|
|
1555
1553
|
err = s_common.err(e)
|
|
@@ -1586,9 +1584,8 @@ class Axon(s_cell.Cell):
|
|
|
1586
1584
|
atimeout = aiohttp.ClientTimeout(total=timeout)
|
|
1587
1585
|
|
|
1588
1586
|
async with aiohttp.ClientSession(connector=connector, timeout=atimeout) as sess:
|
|
1589
|
-
|
|
1590
1587
|
try:
|
|
1591
|
-
|
|
1588
|
+
await self._reqHas(sha256)
|
|
1592
1589
|
async with sess.request(method, url, headers=headers, params=params,
|
|
1593
1590
|
data=self.get(sha256), ssl=ssl) as resp:
|
|
1594
1591
|
|
|
@@ -1601,9 +1598,6 @@ class Axon(s_cell.Cell):
|
|
|
1601
1598
|
}
|
|
1602
1599
|
return info
|
|
1603
1600
|
|
|
1604
|
-
except asyncio.CancelledError: # pramga: no cover
|
|
1605
|
-
raise
|
|
1606
|
-
|
|
1607
1601
|
except Exception as e:
|
|
1608
1602
|
logger.exception(f'Error streaming [{sha256}] to [{s_urlhelp.sanitizeUrl(url)}]')
|
|
1609
1603
|
err = s_common.err(e)
|
synapse/cortex.py
CHANGED
|
@@ -881,7 +881,9 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
881
881
|
|
|
882
882
|
self.maxnodes = self.conf.get('max:nodes')
|
|
883
883
|
self.nodecount = 0
|
|
884
|
+
|
|
884
885
|
self.migration = False
|
|
886
|
+
self._migration_lock = asyncio.Lock()
|
|
885
887
|
|
|
886
888
|
self.stormmods = {} # name: mdef
|
|
887
889
|
self.stormpkgs = {} # name: pkgdef
|
|
@@ -1016,6 +1018,12 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
1016
1018
|
(2, self._storLayrFeedDefaults),
|
|
1017
1019
|
), nexs=False)
|
|
1018
1020
|
|
|
1021
|
+
async def _viewNomergeToProtected(self):
|
|
1022
|
+
for view in self.views.values():
|
|
1023
|
+
nomerge = view.info.get('nomerge', False)
|
|
1024
|
+
await view.setViewInfo('protected', nomerge)
|
|
1025
|
+
await view.setViewInfo('nomerge', None)
|
|
1026
|
+
|
|
1019
1027
|
async def _storUpdateMacros(self):
|
|
1020
1028
|
for name, node in await self.hive.open(('cortex', 'storm', 'macros')):
|
|
1021
1029
|
|
|
@@ -1050,6 +1058,9 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
1050
1058
|
|
|
1051
1059
|
def getStormMacro(self, name, user=None):
|
|
1052
1060
|
|
|
1061
|
+
if not name:
|
|
1062
|
+
raise s_exc.BadArg(mesg=f'Macro names must be at least 1 character long')
|
|
1063
|
+
|
|
1053
1064
|
if len(name) > 491:
|
|
1054
1065
|
raise s_exc.BadArg(mesg='Macro names may only be up to 491 chars.')
|
|
1055
1066
|
|
|
@@ -1140,6 +1151,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
1140
1151
|
raise s_exc.BadArg(mesg=f'Duplicate macro name: {name}')
|
|
1141
1152
|
|
|
1142
1153
|
self.slab.put(name.encode(), s_msgpack.en(mdef), db=self.macrodb)
|
|
1154
|
+
await self.feedBeholder('storm:macro:add', {'macro': mdef})
|
|
1143
1155
|
return mdef
|
|
1144
1156
|
|
|
1145
1157
|
async def delStormMacro(self, name, user=None):
|
|
@@ -1151,9 +1163,15 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
1151
1163
|
|
|
1152
1164
|
@s_nexus.Pusher.onPush('storm:macro:del')
|
|
1153
1165
|
async def _delStormMacro(self, name):
|
|
1166
|
+
if not name:
|
|
1167
|
+
raise s_exc.BadArg(mesg=f'Macro names must be at least 1 character long')
|
|
1168
|
+
|
|
1154
1169
|
byts = self.slab.pop(name.encode(), db=self.macrodb)
|
|
1170
|
+
|
|
1155
1171
|
if byts is not None:
|
|
1156
|
-
|
|
1172
|
+
macro = s_msgpack.un(byts)
|
|
1173
|
+
await self.feedBeholder('storm:macro:del', {'name': name, 'iden': macro.get('iden')})
|
|
1174
|
+
return macro
|
|
1157
1175
|
|
|
1158
1176
|
async def modStormMacro(self, name, info, user=None):
|
|
1159
1177
|
if user is not None:
|
|
@@ -1183,6 +1201,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
1183
1201
|
else:
|
|
1184
1202
|
self.slab.put(name.encode(), s_msgpack.en(mdef), db=self.macrodb)
|
|
1185
1203
|
|
|
1204
|
+
await self.feedBeholder('storm:macro:mod', {'macro': mdef, 'info': info})
|
|
1186
1205
|
return mdef
|
|
1187
1206
|
|
|
1188
1207
|
async def setStormMacroPerm(self, name, scope, iden, level, user=None):
|
|
@@ -1201,6 +1220,14 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
1201
1220
|
reqValidStormMacro(mdef)
|
|
1202
1221
|
|
|
1203
1222
|
self.slab.put(name.encode(), s_msgpack.en(mdef), db=self.macrodb)
|
|
1223
|
+
|
|
1224
|
+
info = {
|
|
1225
|
+
'scope': scope,
|
|
1226
|
+
'iden': iden,
|
|
1227
|
+
'level': level
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
await self.feedBeholder('storm:macro:set:perm', {'macro': mdef, 'info': info})
|
|
1204
1231
|
return mdef
|
|
1205
1232
|
|
|
1206
1233
|
async def getStormMacros(self, user=None):
|
|
@@ -1400,6 +1427,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
1400
1427
|
|
|
1401
1428
|
await self._bumpCellVers('cortex:defaults', (
|
|
1402
1429
|
(1, self._addAllLayrRead),
|
|
1430
|
+
(2, self._viewNomergeToProtected),
|
|
1403
1431
|
))
|
|
1404
1432
|
|
|
1405
1433
|
async def _addAllLayrRead(self):
|
|
@@ -1454,12 +1482,21 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
1454
1482
|
await self.stormdmons.start()
|
|
1455
1483
|
await self.agenda.clearRunningStatus()
|
|
1456
1484
|
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1485
|
+
async def _runMigrations():
|
|
1486
|
+
# Run migrations when this cortex becomes active. This is to prevent
|
|
1487
|
+
# migrations getting skipped in a zero-downtime upgrade path
|
|
1488
|
+
# (upgrade mirror, promote mirror).
|
|
1489
|
+
await self._checkLayerModels()
|
|
1460
1490
|
|
|
1461
|
-
|
|
1462
|
-
|
|
1491
|
+
# Once migrations are complete, start the view and layer tasks.
|
|
1492
|
+
for view in self.views.values():
|
|
1493
|
+
await view.initTrigTask()
|
|
1494
|
+
await view.initMergeTask()
|
|
1495
|
+
|
|
1496
|
+
for layer in self.layers.values():
|
|
1497
|
+
await layer.initLayerActive()
|
|
1498
|
+
|
|
1499
|
+
self.runActiveTask(_runMigrations())
|
|
1463
1500
|
|
|
1464
1501
|
await self.initStormPool()
|
|
1465
1502
|
|
|
@@ -3571,6 +3608,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
3571
3608
|
break
|
|
3572
3609
|
|
|
3573
3610
|
yield ioff, layr.iden, SYNC_NODEEDITS, item, meta
|
|
3611
|
+
await asyncio.sleep(0)
|
|
3574
3612
|
|
|
3575
3613
|
if layr.isdeleted:
|
|
3576
3614
|
yield layr.deloffs, layr.iden, SYNC_LAYR_DEL, (), {}
|
|
@@ -4337,7 +4375,7 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
4337
4375
|
return ret
|
|
4338
4376
|
|
|
4339
4377
|
async def _checkLayerModels(self):
|
|
4340
|
-
with self.enterMigrationMode():
|
|
4378
|
+
async with self.enterMigrationMode():
|
|
4341
4379
|
mrev = s_modelrev.ModelRev(self)
|
|
4342
4380
|
await mrev.revCoreLayers()
|
|
4343
4381
|
|
|
@@ -4458,6 +4496,10 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
4458
4496
|
if view is None:
|
|
4459
4497
|
raise s_exc.NoSuchView(mesg=f'No such view {iden=}', iden=iden)
|
|
4460
4498
|
|
|
4499
|
+
if view.info.get('protected'):
|
|
4500
|
+
mesg = f'Cannot delete view ({iden}) that has protected set.'
|
|
4501
|
+
raise s_exc.CantDelView(mesg=mesg)
|
|
4502
|
+
|
|
4461
4503
|
return await self._push('view:del', iden)
|
|
4462
4504
|
|
|
4463
4505
|
@s_nexus.Pusher.onPush('view:del')
|
|
@@ -6068,11 +6110,12 @@ class Cortex(s_oauth.OAuthMixin, s_cell.Cell): # type: ignore
|
|
|
6068
6110
|
appt = await self.agenda.get(iden)
|
|
6069
6111
|
await appt.edits(edits)
|
|
6070
6112
|
|
|
6071
|
-
@contextlib.
|
|
6072
|
-
def enterMigrationMode(self):
|
|
6073
|
-
self.
|
|
6074
|
-
|
|
6075
|
-
|
|
6113
|
+
@contextlib.asynccontextmanager
|
|
6114
|
+
async def enterMigrationMode(self):
|
|
6115
|
+
async with self._migration_lock:
|
|
6116
|
+
self.migration = True
|
|
6117
|
+
yield
|
|
6118
|
+
self.migration = False
|
|
6076
6119
|
|
|
6077
6120
|
async def iterFormRows(self, layriden, form, stortype=None, startvalu=None):
|
|
6078
6121
|
'''
|
synapse/exc.py
CHANGED
|
@@ -145,6 +145,7 @@ class CantDelForm(SynErr): pass
|
|
|
145
145
|
class CantDelProp(SynErr): pass
|
|
146
146
|
class CantDelType(SynErr): pass
|
|
147
147
|
class CantDelUniv(SynErr): pass
|
|
148
|
+
class CantDelView(SynErr): pass
|
|
148
149
|
class CantMergeView(SynErr): pass
|
|
149
150
|
class CantRevLayer(SynErr): pass
|
|
150
151
|
class CliFini(SynErr):
|
synapse/lib/aha.py
CHANGED
|
@@ -782,6 +782,8 @@ class AhaCell(s_cell.Cell):
|
|
|
782
782
|
|
|
783
783
|
svcname, svcnetw, svcfull = self._nameAndNetwork(name, network)
|
|
784
784
|
|
|
785
|
+
logger.info(f'Deleting service [{svcfull}].', extra=await self.getLogExtra(name=svcname, netw=svcnetw))
|
|
786
|
+
|
|
785
787
|
full = ('aha', 'svcfull', svcfull)
|
|
786
788
|
path = ('aha', 'services', svcnetw, svcname)
|
|
787
789
|
|
|
@@ -805,7 +807,8 @@ class AhaCell(s_cell.Cell):
|
|
|
805
807
|
async def _setAhaSvcDown(self, name, linkiden, network=None):
|
|
806
808
|
svcname, svcnetw, svcfull = self._nameAndNetwork(name, network)
|
|
807
809
|
path = ('aha', 'services', svcnetw, svcname)
|
|
808
|
-
await self.jsonstor.cmpDelPathObjProp(path, 'svcinfo/online', linkiden)
|
|
810
|
+
if await self.jsonstor.cmpDelPathObjProp(path, 'svcinfo/online', linkiden):
|
|
811
|
+
await self.jsonstor.setPathObjProp(path, 'svcinfo/ready', False)
|
|
809
812
|
|
|
810
813
|
# Check if we have any links which may need to be removed
|
|
811
814
|
current_sessions = {s_common.guid(iden): sess for iden, sess in self.dmon.sessions.items()}
|
synapse/lib/base.py
CHANGED
|
@@ -143,6 +143,7 @@ class Base:
|
|
|
143
143
|
self._fini_atexit = False
|
|
144
144
|
self._active_tasks = None # the set of free running tasks associated with me
|
|
145
145
|
self._context_managers = None # the set of context managers i must fini
|
|
146
|
+
self._syn_signal_tasks = None # initialized as a Set when addSignalHandlers is called.
|
|
146
147
|
|
|
147
148
|
async def postAnit(self):
|
|
148
149
|
'''
|
|
@@ -559,14 +560,20 @@ class Base:
|
|
|
559
560
|
'''
|
|
560
561
|
Register SIGTERM/SIGINT signal handlers with the ioloop to fini this object.
|
|
561
562
|
'''
|
|
563
|
+
if self._syn_signal_tasks is None:
|
|
564
|
+
self._syn_signal_tasks = set()
|
|
562
565
|
|
|
563
566
|
def sigterm():
|
|
564
|
-
|
|
565
|
-
asyncio.create_task(self.fini())
|
|
567
|
+
logger.warning('Caught SIGTERM, shutting down.')
|
|
568
|
+
task = asyncio.create_task(self.fini())
|
|
569
|
+
self._syn_signal_tasks.add(task)
|
|
570
|
+
task.add_done_callback(self._syn_signal_tasks.discard)
|
|
566
571
|
|
|
567
572
|
def sigint():
|
|
568
|
-
|
|
569
|
-
asyncio.create_task(self.fini())
|
|
573
|
+
logger.warning('Caught SIGINT, shutting down.')
|
|
574
|
+
task = asyncio.create_task(self.fini())
|
|
575
|
+
self._syn_signal_tasks.add(task)
|
|
576
|
+
task.add_done_callback(self._syn_signal_tasks.discard)
|
|
570
577
|
|
|
571
578
|
loop = asyncio.get_running_loop()
|
|
572
579
|
loop.add_signal_handler(signal.SIGINT, sigint)
|
synapse/lib/cell.py
CHANGED
|
@@ -668,26 +668,32 @@ class CellApi(s_base.Base):
|
|
|
668
668
|
|
|
669
669
|
@adminapi()
|
|
670
670
|
async def listHiveKey(self, path=None):
|
|
671
|
+
s_common.deprecated('CellApi.listHiveKey', curv='2.167.0')
|
|
671
672
|
return await self.cell.listHiveKey(path=path)
|
|
672
673
|
|
|
673
674
|
@adminapi(log=True)
|
|
674
675
|
async def getHiveKeys(self, path):
|
|
676
|
+
s_common.deprecated('CellApi.getHiveKeys', curv='2.167.0')
|
|
675
677
|
return await self.cell.getHiveKeys(path)
|
|
676
678
|
|
|
677
679
|
@adminapi(log=True)
|
|
678
680
|
async def getHiveKey(self, path):
|
|
681
|
+
s_common.deprecated('CellApi.getHiveKey', curv='2.167.0')
|
|
679
682
|
return await self.cell.getHiveKey(path)
|
|
680
683
|
|
|
681
684
|
@adminapi(log=True)
|
|
682
685
|
async def setHiveKey(self, path, valu):
|
|
686
|
+
s_common.deprecated('CellApi.setHiveKey', curv='2.167.0')
|
|
683
687
|
return await self.cell.setHiveKey(path, valu)
|
|
684
688
|
|
|
685
689
|
@adminapi(log=True)
|
|
686
690
|
async def popHiveKey(self, path):
|
|
691
|
+
s_common.deprecated('CellApi.popHiveKey', curv='2.167.0')
|
|
687
692
|
return await self.cell.popHiveKey(path)
|
|
688
693
|
|
|
689
694
|
@adminapi(log=True)
|
|
690
695
|
async def saveHiveTree(self, path=()):
|
|
696
|
+
s_common.deprecated('CellApi.saveHiveTree', curv='2.167.0')
|
|
691
697
|
return await self.cell.saveHiveTree(path=path)
|
|
692
698
|
|
|
693
699
|
@adminapi()
|
|
@@ -1419,7 +1425,6 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
|
|
|
1419
1425
|
if ahaurl is not None:
|
|
1420
1426
|
|
|
1421
1427
|
info = await s_telepath.addAhaUrl(ahaurl)
|
|
1422
|
-
self.ahaclient = info.get('client')
|
|
1423
1428
|
if self.ahaclient is None:
|
|
1424
1429
|
self.ahaclient = await s_telepath.Client.anit(info.get('url'))
|
|
1425
1430
|
self.ahaclient._fini_atexit = True
|
|
@@ -2895,6 +2900,7 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
|
|
|
2895
2900
|
if isnew:
|
|
2896
2901
|
path = os.path.join(self.dirn, 'hiveboot.yaml')
|
|
2897
2902
|
if os.path.isfile(path):
|
|
2903
|
+
s_common.deprdate('Initial hive config from hiveboot.yaml', '2024-05-05')
|
|
2898
2904
|
logger.debug(f'Loading cell hive from {path}')
|
|
2899
2905
|
tree = s_common.yamlload(path)
|
|
2900
2906
|
if tree is not None:
|
|
@@ -4079,7 +4085,10 @@ class Cell(s_nexus.Pusher, s_telepath.Aware):
|
|
|
4079
4085
|
await s_base.Base.addSignalHandlers(self)
|
|
4080
4086
|
|
|
4081
4087
|
def sighup():
|
|
4082
|
-
|
|
4088
|
+
logger.info('Caught SIGHUP, running reloadable subsystems.')
|
|
4089
|
+
task = asyncio.create_task(self.reload())
|
|
4090
|
+
self._syn_signal_tasks.add(task)
|
|
4091
|
+
task.add_done_callback(self._syn_signal_tasks.discard)
|
|
4083
4092
|
|
|
4084
4093
|
loop = asyncio.get_running_loop()
|
|
4085
4094
|
loop.add_signal_handler(signal.SIGHUP, sighup)
|
synapse/lib/hive.py
CHANGED
|
@@ -473,12 +473,15 @@ class HiveApi(s_base.Base):
|
|
|
473
473
|
self.onfini(self._onHapiFini)
|
|
474
474
|
|
|
475
475
|
async def loadHiveTree(self, tree, path=(), trim=False):
|
|
476
|
+
s_common.deprecated('HiveApi.loadHiveTree', curv='2.167.0')
|
|
476
477
|
return await self.hive.loadHiveTree(tree, path=path, trim=trim)
|
|
477
478
|
|
|
478
479
|
async def saveHiveTree(self, path=()):
|
|
480
|
+
s_common.deprecated('HiveApi.saveHiveTree', curv='2.167.0')
|
|
479
481
|
return await self.hive.saveHiveTree(path=path)
|
|
480
482
|
|
|
481
483
|
async def treeAndSync(self, path, iden):
|
|
484
|
+
s_common.deprecated('HiveApi.treeAndSync', curv='2.167.0')
|
|
482
485
|
|
|
483
486
|
node = await self.hive.open(path)
|
|
484
487
|
|
|
@@ -510,16 +513,22 @@ class HiveApi(s_base.Base):
|
|
|
510
513
|
return
|
|
511
514
|
|
|
512
515
|
async def setAndSync(self, path, valu, iden, nexs=False):
|
|
516
|
+
s_common.deprecated('HiveApi.setAndSync', curv='2.167.0')
|
|
517
|
+
|
|
513
518
|
valu = await self.hive.set(path, valu, nexs=nexs)
|
|
514
519
|
await self.msgq.put(('hive:sync', {'iden': iden}))
|
|
515
520
|
return valu
|
|
516
521
|
|
|
517
522
|
async def addAndSync(self, path, valu, iden):
|
|
523
|
+
s_common.deprecated('HiveApi.addAndSync', curv='2.167.0')
|
|
524
|
+
|
|
518
525
|
valu = await self.hive.add(path, valu)
|
|
519
526
|
await self.msgq.put(('hive:sync', {'iden': iden}))
|
|
520
527
|
return valu
|
|
521
528
|
|
|
522
529
|
async def popAndSync(self, path, iden, nexs=False):
|
|
530
|
+
s_common.deprecated('HiveApi.popAndSync', curv='2.167.0')
|
|
531
|
+
|
|
523
532
|
valu = await self.hive.pop(path, nexs=nexs)
|
|
524
533
|
await self.msgq.put(('hive:sync', {'iden': iden}))
|
|
525
534
|
return valu
|
|
@@ -531,9 +540,11 @@ class HiveApi(s_base.Base):
|
|
|
531
540
|
self.msgq.put_nowait(mesg)
|
|
532
541
|
|
|
533
542
|
async def get(self, full):
|
|
543
|
+
s_common.deprecated('HiveApi.get', curv='2.167.0')
|
|
534
544
|
return await self.hive.get(full)
|
|
535
545
|
|
|
536
546
|
async def edits(self):
|
|
547
|
+
s_common.deprecated('HiveApi.edits', curv='2.167.0')
|
|
537
548
|
|
|
538
549
|
while not self.isfini:
|
|
539
550
|
|
synapse/lib/layer.py
CHANGED
|
@@ -165,11 +165,13 @@ class LayerApi(s_cell.CellApi):
|
|
|
165
165
|
await self._reqUserAllowed(self.liftperm)
|
|
166
166
|
async for item in self.layr.syncNodeEdits(offs, wait=wait):
|
|
167
167
|
yield item
|
|
168
|
+
await asyncio.sleep(0)
|
|
168
169
|
|
|
169
170
|
async def syncNodeEdits2(self, offs, wait=True):
|
|
170
171
|
await self._reqUserAllowed(self.liftperm)
|
|
171
172
|
async for item in self.layr.syncNodeEdits2(offs, wait=wait):
|
|
172
173
|
yield item
|
|
174
|
+
await asyncio.sleep(0)
|
|
173
175
|
|
|
174
176
|
async def getEditIndx(self):
|
|
175
177
|
'''
|
synapse/lib/modelrev.py
CHANGED
|
@@ -768,6 +768,12 @@ class ModelRev:
|
|
|
768
768
|
Returns:
|
|
769
769
|
None
|
|
770
770
|
'''
|
|
771
|
+
if opts is None:
|
|
772
|
+
opts = {}
|
|
773
|
+
|
|
774
|
+
# Migrations only run on leaders
|
|
775
|
+
opts['mirror'] = False
|
|
776
|
+
|
|
771
777
|
async def _runStorm():
|
|
772
778
|
async for mesgtype, mesginfo in self.core.storm(text, opts=opts):
|
|
773
779
|
if mesgtype == 'print':
|
synapse/lib/modules.py
CHANGED
synapse/lib/node.py
CHANGED
|
@@ -472,10 +472,12 @@ class Node:
|
|
|
472
472
|
form=self.form.full, tag=tag)
|
|
473
473
|
|
|
474
474
|
pref = name + '.'
|
|
475
|
+
exists = self.tags.get(name, s_common.novalu) is not s_common.novalu
|
|
475
476
|
|
|
476
477
|
todel = [(len(t), t) for t in self.tags.keys() if t.startswith(pref)]
|
|
477
478
|
|
|
478
|
-
|
|
479
|
+
# only prune when we're actually deleting a tag
|
|
480
|
+
if len(path) > 1 and exists:
|
|
479
481
|
|
|
480
482
|
parent = '.'.join(path[:-1])
|
|
481
483
|
|
|
@@ -511,7 +513,7 @@ class Node:
|
|
|
511
513
|
edits.append((s_layer.EDIT_TAG_DEL, (subtag, None), ()))
|
|
512
514
|
|
|
513
515
|
edits.extend(self._getTagPropDel(name))
|
|
514
|
-
if
|
|
516
|
+
if exists:
|
|
515
517
|
edits.append((s_layer.EDIT_TAG_DEL, (name, None), ()))
|
|
516
518
|
|
|
517
519
|
return edits
|
synapse/lib/schemas.py
CHANGED
|
@@ -172,7 +172,7 @@ reqValidView = s_config.getJsValidator({
|
|
|
172
172
|
'parent': {'type': ['string', 'null'], 'pattern': s_config.re_iden},
|
|
173
173
|
'creator': {'type': 'string', 'pattern': s_config.re_iden},
|
|
174
174
|
'created': {'type': 'integer', 'minimum': 0},
|
|
175
|
-
'
|
|
175
|
+
'protected': {'type': 'boolean', 'default': False},
|
|
176
176
|
'merging': {'type': 'boolean'},
|
|
177
177
|
'layers': {
|
|
178
178
|
'type': 'array',
|