synapse 2.224.0__py311-none-any.whl → 2.225.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.

Files changed (121) hide show
  1. synapse/axon.py +10 -5
  2. synapse/lib/cell.py +1 -1
  3. synapse/lib/const.py +4 -0
  4. synapse/lib/multislabseqn.py +36 -1
  5. synapse/lib/nexus.py +67 -8
  6. synapse/lib/queue.py +4 -1
  7. synapse/lib/rstorm.py +2 -2
  8. synapse/lib/schemas.py +11 -1
  9. synapse/lib/slabseqn.py +28 -0
  10. synapse/lib/storm.py +5 -1
  11. synapse/lib/stormhttp.py +7 -1
  12. synapse/lib/version.py +2 -2
  13. synapse/models/inet.py +4 -0
  14. synapse/models/media.py +4 -0
  15. synapse/models/risk.py +3 -0
  16. synapse/tests/test_cortex.py +2 -2
  17. synapse/tests/test_lib_agenda.py +1 -1
  18. synapse/tests/test_lib_cell.py +1 -1
  19. synapse/tests/test_lib_certdir.py +1 -1
  20. synapse/tests/test_lib_httpapi.py +1 -1
  21. synapse/tests/test_lib_layer.py +1 -1
  22. synapse/tests/test_lib_multislabseqn.py +22 -0
  23. synapse/tests/test_lib_nexus.py +42 -1
  24. synapse/tests/test_lib_slabseqn.py +30 -1
  25. synapse/tests/test_lib_storm.py +59 -1
  26. synapse/tests/test_lib_stormhttp.py +16 -0
  27. synapse/tests/test_lib_stormlib_oauth.py +1 -1
  28. synapse/tests/test_lib_stormsvc.py +1 -1
  29. synapse/tests/test_lib_trigger.py +1 -1
  30. synapse/tests/test_model_inet.py +6 -0
  31. synapse/tests/test_model_media.py +4 -1
  32. synapse/tests/test_model_risk.py +2 -0
  33. synapse/tests/{test_tools_axon2axon.py → test_tools_axon_copy.py} +4 -4
  34. synapse/tests/{test_tools_pullfile.py → test_tools_axon_get.py} +4 -4
  35. synapse/tests/{test_tools_pushfile.py → test_tools_axon_put.py} +7 -7
  36. synapse/tests/{test_tools_csvtool.py → test_tools_cortex_csv.py} +12 -3
  37. synapse/tests/{test_tools_feed.py → test_tools_cortex_feed.py} +2 -2
  38. synapse/tests/{test_tools_apikey.py → test_tools_service_apikey.py} +1 -4
  39. synapse/tests/{test_tools_backup.py → test_tools_service_backup.py} +5 -5
  40. synapse/tests/{test_tools_demote.py → test_tools_service_demote.py} +1 -1
  41. synapse/tests/{test_tools_healthcheck.py → test_tools_service_healthcheck.py} +1 -1
  42. synapse/tests/{test_tools_livebackup.py → test_tools_service_livebackup.py} +1 -1
  43. synapse/tests/{test_tools_modrole.py → test_tools_service_modrole.py} +1 -1
  44. synapse/tests/{test_tools_moduser.py → test_tools_service_moduser.py} +1 -1
  45. synapse/tests/{test_tools_promote.py → test_tools_service_promote.py} +1 -1
  46. synapse/tests/{test_tools_reload.py → test_tools_service_reload.py} +1 -1
  47. synapse/tests/{test_tools_shutdown.py → test_tools_service_shutdown.py} +1 -1
  48. synapse/tests/{test_tools_snapshot.py → test_tools_service_snapshot.py} +1 -1
  49. synapse/tests/{test_tools_storm.py → test_tools_storm_cli.py} +1 -1
  50. synapse/tests/{test_tools_pkgs_gendocs.py → test_tools_storm_pkg_doc.py} +12 -3
  51. synapse/tests/{test_tools_genpkg.py → test_tools_storm_pkg_gen.py} +1 -1
  52. synapse/tests/{test_tools_autodoc.py → test_tools_utils_autodoc.py} +1 -1
  53. synapse/tests/test_tools_utils_changelog.py +454 -0
  54. synapse/tests/{test_tools_easycert.py → test_tools_utils_easycert.py} +48 -46
  55. synapse/tests/{test_tools_guid.py → test_tools_utils_guid.py} +3 -3
  56. synapse/tests/{test_tools_json2mpk.py → test_tools_utils_json2mpk.py} +3 -3
  57. synapse/tests/{test_tools_rstorm.py → test_tools_utils_rstorm.py} +6 -1
  58. synapse/tests/utils.py +3 -1
  59. synapse/tools/apikey.py +4 -83
  60. synapse/tools/autodoc.py +3 -1031
  61. synapse/tools/axon/copy.py +44 -0
  62. synapse/tools/axon/get.py +64 -0
  63. synapse/tools/axon/put.py +122 -0
  64. synapse/tools/axon2axon.py +3 -36
  65. synapse/tools/backup.py +6 -176
  66. synapse/tools/changelog.py +3 -1098
  67. synapse/tools/cortex/csv.py +236 -0
  68. synapse/tools/cortex/feed.py +151 -0
  69. synapse/tools/csvtool.py +3 -227
  70. synapse/tools/demote.py +4 -40
  71. synapse/tools/docker/validate.py +3 -3
  72. synapse/tools/easycert.py +4 -129
  73. synapse/tools/feed.py +3 -140
  74. synapse/tools/genpkg.py +3 -307
  75. synapse/tools/guid.py +7 -6
  76. synapse/tools/healthcheck.py +3 -101
  77. synapse/tools/json2mpk.py +6 -38
  78. synapse/tools/livebackup.py +4 -27
  79. synapse/tools/modrole.py +3 -108
  80. synapse/tools/moduser.py +3 -179
  81. synapse/tools/pkgs/gendocs.py +3 -164
  82. synapse/tools/promote.py +4 -41
  83. synapse/tools/pullfile.py +3 -56
  84. synapse/tools/pushfile.py +3 -114
  85. synapse/tools/reload.py +4 -61
  86. synapse/tools/rstorm.py +3 -26
  87. synapse/tools/service/__init__.py +0 -0
  88. synapse/tools/service/apikey.py +90 -0
  89. synapse/tools/service/backup.py +181 -0
  90. synapse/tools/service/demote.py +47 -0
  91. synapse/tools/service/healthcheck.py +109 -0
  92. synapse/tools/service/livebackup.py +34 -0
  93. synapse/tools/service/modrole.py +116 -0
  94. synapse/tools/service/moduser.py +184 -0
  95. synapse/tools/service/promote.py +48 -0
  96. synapse/tools/service/reload.py +68 -0
  97. synapse/tools/service/shutdown.py +51 -0
  98. synapse/tools/service/snapshot.py +64 -0
  99. synapse/tools/shutdown.py +5 -45
  100. synapse/tools/snapshot.py +4 -57
  101. synapse/tools/storm/__init__.py +0 -0
  102. synapse/tools/storm/__main__.py +5 -0
  103. synapse/tools/{storm.py → storm/_cli.py} +0 -3
  104. synapse/tools/storm/pkg/__init__.py +0 -0
  105. synapse/tools/{pkgs/pandoc_filter.py → storm/pkg/_pandoc_filter.py} +1 -1
  106. synapse/tools/storm/pkg/doc.py +176 -0
  107. synapse/tools/storm/pkg/gen.py +315 -0
  108. synapse/tools/utils/__init__.py +0 -0
  109. synapse/tools/utils/autodoc.py +1040 -0
  110. synapse/tools/utils/changelog.py +1124 -0
  111. synapse/tools/utils/easycert.py +136 -0
  112. synapse/tools/utils/guid.py +11 -0
  113. synapse/tools/utils/json2mpk.py +46 -0
  114. synapse/tools/utils/rstorm.py +35 -0
  115. {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/METADATA +1 -1
  116. {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/RECORD +120 -91
  117. synapse/tests/test_tools_changelog.py +0 -196
  118. /synapse/tests/{test_tools_axon.py → test_tools_axon_dump_load.py} +0 -0
  119. {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/WHEEL +0 -0
  120. {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/licenses/LICENSE +0 -0
  121. {synapse-2.224.0.dist-info → synapse-2.225.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,44 @@
1
+ import logging
2
+
3
+ import synapse.common as s_common
4
+ import synapse.telepath as s_telepath
5
+
6
+ import synapse.exc as s_exc
7
+ import synapse.lib.cmd as s_cmd
8
+ import synapse.lib.base as s_base
9
+ import synapse.lib.output as s_output
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+ async def main(argv, outp=s_output.stdout):
14
+
15
+ pars = s_cmd.Parser(prog='synapse.tools.axon.copy', outp=outp)
16
+ pars.add_argument('--offset', type=int, default=0, help='An offset within the source axon to start from.')
17
+ pars.add_argument('src_axon', help='The telepath URL of the source axon.')
18
+ pars.add_argument('dst_axon', help='The telepath URL of the destination axon.')
19
+
20
+ try:
21
+ opts = pars.parse_args(argv)
22
+ except s_exc.ParserExit:
23
+ return 1
24
+
25
+ async with s_telepath.withTeleEnv():
26
+ async with await s_base.Base.anit() as base:
27
+
28
+ srcaxon = await base.enter_context(await s_telepath.openurl(opts.src_axon))
29
+ dstaxon = await base.enter_context(await s_telepath.openurl(opts.dst_axon))
30
+
31
+ outp.printf(f'Starting transfer at offset: {opts.offset}')
32
+
33
+ async for (offs, (sha256, size)) in srcaxon.hashes(opts.offset):
34
+ offstext = str(offs).rjust(10)
35
+ sha2text = s_common.ehex(sha256)
36
+ outp.printf(f'[{offstext}] - {sha2text} ({size})')
37
+ async with await dstaxon.upload() as fd:
38
+ async for byts in srcaxon.get(sha256):
39
+ await fd.write(byts)
40
+ await fd.save()
41
+ return 0
42
+
43
+ if __name__ == '__main__': # pragma: no cover
44
+ s_cmd.exitmain(main)
@@ -0,0 +1,64 @@
1
+ import pathlib
2
+
3
+ import synapse.common as s_common
4
+ import synapse.telepath as s_telepath
5
+
6
+ import synapse.lib.cmd as s_cmd
7
+ import synapse.lib.output as s_output
8
+
9
+
10
+ async def main(argv, outp=s_output.stdout):
11
+ pars = getArgParser(outp)
12
+ opts = pars.parse_args(argv)
13
+
14
+ if opts.output is None:
15
+ opts.output = '.'
16
+
17
+ outdir = pathlib.Path(opts.output)
18
+
19
+ s_common.gendir(opts.output)
20
+
21
+ async with s_telepath.withTeleEnv():
22
+
23
+ async with await s_telepath.openurl(opts.axon) as axon:
24
+
25
+ # reminder: these are the hashes *not* available
26
+
27
+ awants = await axon.wants([s_common.uhex(h) for h in opts.hashes])
28
+ for a in awants:
29
+ outp.printf(f'{s_common.ehex(a)} not in axon store')
30
+
31
+ exists = [h for h in opts.hashes if s_common.uhex(h) not in awants]
32
+
33
+ for h in exists:
34
+
35
+ try:
36
+ outp.printf(f'Fetching {h} to file')
37
+
38
+ with open(outdir.joinpath(h), 'wb') as fd:
39
+ async for b in axon.get(s_common.uhex(h)):
40
+ fd.write(b)
41
+
42
+ outp.printf(f'Fetched {h} to file')
43
+
44
+ except Exception as e:
45
+ outp.printf('Error: Hit Exception: %s' % (str(e),))
46
+ continue
47
+
48
+ return 0
49
+
50
+
51
+ def getArgParser(outp):
52
+ desc = 'Fetches file from the given axon'
53
+ pars = s_cmd.Parser(prog='synapse.tools.axon.get', outp=outp, description=desc)
54
+ pars.add_argument('-a', '--axon', type=str, dest='axon', required=True,
55
+ help='URL to the axon blob store')
56
+ pars.add_argument('-o', '--output', type=str, dest='output',
57
+ help='Directory to output files to')
58
+ pars.add_argument('-l', '--list-hashes', dest='hashes', action='append', default=[],
59
+ help='List of hashes to pull from axon')
60
+
61
+ return pars
62
+
63
+ if __name__ == '__main__': # pragma: no cover
64
+ s_cmd.exitmain(main)
@@ -0,0 +1,122 @@
1
+ import os
2
+ import glob
3
+ import logging
4
+
5
+ import synapse.exc as s_exc
6
+ import synapse.common as s_common
7
+ import synapse.telepath as s_telepath
8
+
9
+ import synapse.lib.cmd as s_cmd
10
+ import synapse.lib.output as s_output
11
+ import synapse.lib.hashset as s_hashset
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ async def main(argv, outp=s_output.stdout):
17
+ pars = getArgParser(outp)
18
+ opts = pars.parse_args(argv)
19
+
20
+ async with s_telepath.withTeleEnv():
21
+
22
+ axon = await s_telepath.openurl(opts.axon)
23
+
24
+ core = None
25
+ if opts.cortex:
26
+ core = await s_telepath.openurl(opts.cortex)
27
+
28
+ tags = set()
29
+ if opts.tags:
30
+ for tag in opts.tags.split(','):
31
+ tags.add(tag)
32
+
33
+ tags = tuple(tags)
34
+ if tags:
35
+ outp.printf(f'adding tags: {tags}')
36
+
37
+ filepaths = set()
38
+ for item in opts.filenames:
39
+ paths = glob.glob(item, recursive=opts.recursive)
40
+
41
+ if not paths:
42
+ outp.printf(f'filepath does not contain any files: {item}')
43
+ continue
44
+
45
+ filepaths.update([path for path in paths if os.path.isfile(path)])
46
+
47
+ for path in filepaths:
48
+
49
+ bname = os.path.basename(path)
50
+
51
+ hset = s_hashset.HashSet()
52
+ with s_common.reqfile(path) as fd:
53
+ hset.eatfd(fd)
54
+
55
+ fhashes = {htyp: hasher.hexdigest() for htyp, hasher in hset.hashes}
56
+
57
+ sha256 = fhashes.get('sha256')
58
+ bsha256 = s_common.uhex(sha256)
59
+
60
+ if not await axon.has(bsha256):
61
+
62
+ async with await axon.upload() as upfd:
63
+
64
+ with s_common.genfile(path) as fd:
65
+ for byts in s_common.iterfd(fd):
66
+ await upfd.write(byts)
67
+
68
+ size, hashval = await upfd.save()
69
+
70
+ if hashval != bsha256: # pragma: no cover
71
+ raise s_exc.SynErr(mesg='hashes do not match',
72
+ ehash=s_common.ehex(hashval),
73
+ ahash=hashval)
74
+
75
+ outp.printf(f'Uploaded [{bname}] to axon')
76
+ else:
77
+ outp.printf(f'Axon already had [{bname}]')
78
+
79
+ if core:
80
+ opts = {'vars': {
81
+ 'md5': fhashes.get('md5'),
82
+ 'sha1': fhashes.get('sha1'),
83
+ 'sha256': fhashes.get('sha256'),
84
+ 'size': hset.size,
85
+ 'name': bname,
86
+ 'tags': tags,
87
+ }}
88
+
89
+ q = '[file:bytes=$sha256 :md5=$md5 :sha1=$sha1 :size=$size :name=$name] ' \
90
+ '{ for $tag in $tags { [+#$tag] } }'
91
+
92
+ msgs = await core.storm(q, opts=opts).list()
93
+ node = [m[1] for m in msgs if m[0] == 'node'][0]
94
+
95
+ iden = node[0][1]
96
+ size = node[1]['props']['size']
97
+ name = node[1]['props']['name']
98
+ mesg = f'file: {bname} ({size}) added to core ({iden}) as {name}'
99
+ outp.printf(mesg)
100
+
101
+ await axon.fini()
102
+ if core:
103
+ await core.fini()
104
+
105
+ return 0
106
+
107
+ def getArgParser(outp):
108
+ desc = 'Command line tool for uploading files to an Axon and making ' \
109
+ 'file:bytes in a Cortex.'
110
+ pars = s_cmd.Parser(prog='synapse.tools.axon.put', outp=outp, description=desc)
111
+ pars.add_argument('-a', '--axon', required=True, type=str, dest='axon',
112
+ help='URL for a target Axon to store files at.')
113
+ pars.add_argument('-c', '--cortex', default=None, type=str, dest='cortex',
114
+ help='URL for a target Cortex to make file:bytes nodes.')
115
+ pars.add_argument('filenames', nargs='+', help='File names (or glob patterns) to upload')
116
+ pars.add_argument('-r', '--recursive', action='store_true',
117
+ help='Recursively search paths to upload files.')
118
+ pars.add_argument('-t', '--tags', help='comma separated list of tags to add to the nodes')
119
+ return pars
120
+
121
+ if __name__ == '__main__': # pragma: no cover
122
+ s_cmd.exitmain(main)
@@ -1,44 +1,11 @@
1
- import logging
2
-
3
1
  import synapse.common as s_common
4
- import synapse.telepath as s_telepath
5
2
 
6
- import synapse.exc as s_exc
7
3
  import synapse.lib.cmd as s_cmd
8
- import synapse.lib.base as s_base
9
- import synapse.lib.output as s_output
10
-
11
- logger = logging.getLogger(__name__)
12
-
13
- async def main(argv, outp=s_output.stdout):
14
-
15
- pars = s_cmd.Parser(prog='synapse.tools.axon2axon', outp=outp)
16
- pars.add_argument('--offset', type=int, default=0, help='An offset within the source axon to start from.')
17
- pars.add_argument('src_axon', help='The telepath URL of the source axon.')
18
- pars.add_argument('dst_axon', help='The telepath URL of the destination axon.')
19
-
20
- try:
21
- opts = pars.parse_args(argv)
22
- except s_exc.ParserExit:
23
- return 1
24
-
25
- async with s_telepath.withTeleEnv():
26
- async with await s_base.Base.anit() as base:
27
-
28
- srcaxon = await base.enter_context(await s_telepath.openurl(opts.src_axon))
29
- dstaxon = await base.enter_context(await s_telepath.openurl(opts.dst_axon))
30
4
 
31
- outp.printf(f'Starting transfer at offset: {opts.offset}')
5
+ from synapse.tools.axon.copy import main
32
6
 
33
- async for (offs, (sha256, size)) in srcaxon.hashes(opts.offset):
34
- offstext = str(offs).rjust(10)
35
- sha2text = s_common.ehex(sha256)
36
- outp.printf(f'[{offstext}] - {sha2text} ({size})')
37
- async with await dstaxon.upload() as fd:
38
- async for byts in srcaxon.get(sha256):
39
- await fd.write(byts)
40
- await fd.save()
41
- return 0
7
+ s_common.deprecated('synapse.tools.axon2axon is deprecated. Please use synapse.tools.axon.copy instead.',
8
+ curv='v2.225.0')
42
9
 
43
10
  if __name__ == '__main__': # pragma: no cover
44
11
  s_cmd.exitmain(main)
synapse/tools/backup.py CHANGED
@@ -1,182 +1,12 @@
1
- import os
2
- import sys
3
- import glob
4
- import time
5
- import shutil
6
- import fnmatch
7
- import logging
8
- import argparse
9
- import contextlib
10
-
11
- import lmdb
12
-
13
1
  import synapse.common as s_common
14
2
 
15
- logger = logging.getLogger(__name__)
16
-
17
- def backup(srcdir, dstdir, skipdirs=None):
18
- '''
19
- Create a backup of a Synapse application.
20
-
21
- Args:
22
- srcdir (str): Path to the directory to backup.
23
- dstdir (str): Path to backup target directory.
24
- skipdirs (list or None): Optional list of relative directory name glob patterns to exclude from the backup.
25
-
26
- Note:
27
- Running this method from the same process as a running user of the directory may lead to a segmentation fault
28
- '''
29
- with capturelmdbs(srcdir, skipdirs=skipdirs) as lmdbinfo:
30
- txnbackup(lmdbinfo, srcdir, dstdir, skipdirs=skipdirs)
31
-
32
- @contextlib.contextmanager
33
- def capturelmdbs(srcdir, skipdirs=None, onlydirs=None):
34
- '''
35
- A context manager that opens all the lmdb files under a srcdir and makes a read transaction. All transactions are
36
- aborted and environments closed when the context is exited.
37
-
38
- Yields:
39
- Dict[str, Tuple[lmdb.Environment, lmdb.Transaction]]: Maps path to environment, transaction
40
- '''
41
- if onlydirs:
42
- lmdbpaths = onlydirs
43
-
44
- else:
45
- if skipdirs is None:
46
- skipdirs = []
47
-
48
- srcdir = glob.escape(os.path.abspath(srcdir))
49
- skipdirs.append(os.path.join(srcdir, 'tmp/*'))
50
- skipdirs.append(os.path.join(srcdir, '*/tmp/*'))
51
-
52
- srcdirglob = s_common.genpath(srcdir, '**/data.mdb')
53
- fniter = glob.iglob(srcdirglob, recursive=True)
54
- lmdbpaths = [os.path.dirname(fn) for fn in fniter if not
55
- any([fnmatch.fnmatch(fn, pattern) for pattern in skipdirs])]
56
-
57
- lmdbinfo = {}
58
-
59
- with contextlib.ExitStack() as stack:
60
- for path in lmdbpaths:
61
- logger.debug(f'Capturing txn for {path}')
62
- datafile = os.path.join(path, 'data.mdb')
63
- stat = os.stat(datafile)
64
- map_size = stat.st_size
65
- env = stack.enter_context(
66
- lmdb.open(path, map_size=map_size, max_dbs=16384, create=False, readonly=True))
67
- txn = stack.enter_context(env.begin())
68
- assert path not in lmdbinfo
69
- lmdbinfo[path] = (env, txn)
70
-
71
- yield lmdbinfo
72
-
73
- def txnbackup(lmdbinfo, srcdir, dstdir, skipdirs=None):
74
- '''
75
- Create a backup of a Synapse application under a (hopefully consistent) set of transactions.
76
-
77
- Args:
78
- lmdbinfo(Dict[str, Tuple[lmdb.Environment, lmdb.Transaction]]): Maps of path to environment, transaction
79
- srcdir (str): Path to the directory to backup.
80
- dstdir (str): Path to backup target directory.
81
- skipdirs (list or None): Optional list of relative directory name glob patterns to exclude from the backup.
82
-
83
- Note:
84
- Running this method from the same process as a running user of the directory may lead to a segmentation fault
85
- '''
86
- tick = s_common.now()
87
-
88
- srcdir = s_common.reqdir(srcdir)
89
- dstdir = s_common.gendir(dstdir)
90
-
91
- if skipdirs is None:
92
- skipdirs = []
93
-
94
- # Always avoid backing up temporary and backup directories
95
- skipdirs.append('**/tmp')
96
- skipdirs.append('**/backups')
97
-
98
- logger.debug(f'Starting backup of [{srcdir}]')
99
- logger.debug(f'Destination dir: [{dstdir}]')
100
-
101
- for root, dnames, fnames in os.walk(srcdir, topdown=True):
102
-
103
- relpath = os.path.relpath(root, start=srcdir)
3
+ import synapse.lib.cmd as s_cmd
104
4
 
105
- for name in list(dnames):
5
+ from synapse.tools.service.backup import logger, main, backup
106
6
 
107
- srcpath = s_common.genpath(root, name)
108
-
109
- relname = os.path.join(relpath, name)
110
-
111
- if any([fnmatch.fnmatch(relname, pattern) for pattern in skipdirs]):
112
- logger.debug(f'skipping dir:{srcpath}')
113
- dnames.remove(name)
114
- continue
115
-
116
- dstpath = s_common.genpath(dstdir, relname)
117
-
118
- info = lmdbinfo.get(os.path.abspath(srcpath))
119
-
120
- if info is not None:
121
- logger.debug('backing up lmdb file: %s', srcpath)
122
- dnames.remove(name)
123
- env, txn = info
124
- backup_lmdb(env, dstpath, txn=txn)
125
- continue
126
-
127
- if name.endswith('.lmdb'):
128
- logger.warning('lmdb file %s not copied', srcpath)
129
- dnames.remove(name)
130
- continue
131
-
132
- logger.debug(f'making dir:{dstpath}')
133
- s_common.gendir(dstpath)
134
-
135
- for name in fnames:
136
-
137
- srcpath = s_common.genpath(root, name)
138
- # skip unix sockets etc...
139
- if not os.path.isfile(srcpath):
140
- continue
141
-
142
- dstpath = s_common.genpath(dstdir, relpath, name)
143
- logger.debug(f'copying: {srcpath} -> {dstpath}')
144
- shutil.copy(srcpath, dstpath)
145
-
146
- tock = s_common.now()
147
-
148
- logger.debug(f'Backup complete. Took [{tock-tick:.2f}] for [{srcdir}]')
149
- return
150
-
151
- def backup_lmdb(env: lmdb.Environment, dstdir: str, txn=None):
152
-
153
- tick = time.time()
154
-
155
- s_common.gendir(dstdir)
156
-
157
- env.copy(dstdir, compact=True, txn=txn)
158
-
159
- tock = time.time()
160
- logger.info(f'backup of: {env.path()} took: {tock-tick:.2f} seconds')
161
-
162
- def main(argv):
163
- args = parse_args(argv)
164
- backup(args.srcdir, args.dstdir, args.skipdirs)
165
- return 0
166
-
167
- def parse_args(argv):
168
- desc = 'Create an optimized backup of a Synapse directory.'
169
- parser = argparse.ArgumentParser('synapse.tools.backup', description=desc)
170
- parser.add_argument('srcdir', help='Path to the Synapse directory to backup.')
171
- parser.add_argument('dstdir', help='Path to the backup target directory.')
172
- parser.add_argument('--skipdirs', nargs='+',
173
- help='Glob patterns of relative directory names to exclude from the backup.')
174
- args = parser.parse_args(argv)
175
- return args
176
-
177
- def _main(argv): # pragma: no cover
178
- s_common.setlogging(logger, defval='DEBUG')
179
- return main(argv)
7
+ s_common.deprecated('synapse.tools.backup is deprecated. Please use synapse.tools.service.backup instead.',
8
+ curv='v2.225.0')
180
9
 
181
10
  if __name__ == '__main__': # pragma: no cover
182
- sys.exit(_main(sys.argv[1:]))
11
+ s_common.setlogging(logger, defval='DEBUG')
12
+ s_cmd.exitmain(main)