Skip to content

Commit 1f9c89a

Browse files
authored
[sonic-py-common] porting sonic_db_dump_load.py from sonic-py-swsssdk to sonic-py-common (sonic-net#12185)
Porting sonic_db_dump_load.py from sonic-py-swsssdk to sonic-py-common. #### Why I did it sonic-py-swsssdk will be deprecate, so porting sonic_db_dump_load.py to sonic-py-common. #### How I did it Copy sonic_db_dump_load.py to sonic-py-common, and fix minor API different. #### How to verify it Pass all E2E test. The platform_tests/test_advanced_reboot.py::test_warm_reboot will cover this script. #### Which release branch to backport (provide reason below if selected) <!-- - Note we only backport fixes to a release branch, *not* features! - Please also provide a reason for the backporting below. - e.g. - [x] 202006 --> - [ ] 201811 - [ ] 201911 - [ ] 202006 - [ ] 202012 - [ ] 202106 - [ ] 202111 - [ ] 202205 #### Description for the changelog Porting sonic_db_dump_load.py from sonic-py-swsssdk to sonic-py-common. #### Ensure to add label/tag for the feature raised. example - [PR#2174](sonic-net/sonic-utilities#2174) where, Generic Config and Update feature has been labelled as GCU. #### Link to config_db schema for YANG module changes <!-- Provide a link to config_db schema for the table for which YANG model is defined Link should point to correct section on https://github.com/Azure/sonic-buildimage/blob/master/src/sonic-yang-models/doc/Configuration.md --> #### A picture of a cute animal (not mandatory but encouraged)
1 parent 8c7e0f8 commit 1f9c89a

File tree

2 files changed

+145
-0
lines changed

2 files changed

+145
-0
lines changed

src/sonic-py-common/setup.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
'pytest',
2828
'mock==3.0.5' # For python 2. Version >=4.0.0 drops support for py2
2929
],
30+
entry_points={
31+
'console_scripts': [
32+
'sonic-db-load = sonic_py_common.sonic_db_dump_load:sonic_db_dump_load',
33+
'sonic-db-dump = sonic_py_common.sonic_db_dump_load:sonic_db_dump_load',
34+
],
35+
},
3036
classifiers=[
3137
'Intended Audience :: Developers',
3238
'Operating System :: Linux',
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
## ref: https://github.com/p/redis-dump-load/blob/7bbdb1eaea0a51ed4758d3ce6ca01d497a4e7429/redisdl.py
2+
3+
def sonic_db_dump_load():
4+
import optparse
5+
import os.path
6+
import re
7+
import sys
8+
from redisdl import dump, load
9+
from swsscommon.swsscommon import SonicDBConfig
10+
11+
DUMP = 1
12+
LOAD = 2
13+
14+
def options_to_kwargs(options):
15+
args = {}
16+
if options.password:
17+
args['password'] = options.password
18+
if options.encoding:
19+
args['encoding'] = options.encoding
20+
# dump only
21+
if hasattr(options, 'pretty') and options.pretty:
22+
args['pretty'] = True
23+
if hasattr(options, 'keys') and options.keys:
24+
args['keys'] = options.keys
25+
# load only
26+
if hasattr(options, 'use_expireat') and options.use_expireat:
27+
args['use_expireat'] = True
28+
if hasattr(options, 'empty') and options.empty:
29+
args['empty'] = True
30+
if hasattr(options, 'backend') and options.backend:
31+
args['streaming_backend'] = options.backend
32+
if hasattr(options, 'dbname') and options.dbname:
33+
if options.conntype == 'tcp':
34+
args['host'] = SonicDBConfig.getDbHostname(options.dbname)
35+
args['port'] = SonicDBConfig.getDbPort(options.dbname)
36+
args['db'] = SonicDBConfig.getDbId(options.dbname)
37+
args['unix_socket_path'] = None
38+
elif options.conntype == "unix_socket":
39+
args['host'] = None
40+
args['port'] = None
41+
args['db'] = SonicDBConfig.getDbId(options.dbname)
42+
args['unix_socket_path'] = SonicDBConfig.getDbSock(options.dbname)
43+
else:
44+
raise TypeError('redis connection type is tcp or unix_socket')
45+
46+
return args
47+
48+
def do_dump(options):
49+
if options.output:
50+
output = open(options.output, 'w')
51+
else:
52+
output = sys.stdout
53+
54+
kwargs = options_to_kwargs(options)
55+
dump(output, **kwargs)
56+
57+
if options.output:
58+
output.close()
59+
60+
def do_load(options, args):
61+
if len(args) > 0:
62+
input = open(args[0], 'rb')
63+
else:
64+
input = sys.stdin
65+
66+
kwargs = options_to_kwargs(options)
67+
load(input, **kwargs)
68+
69+
if len(args) > 0:
70+
input.close()
71+
72+
script_name = os.path.basename(sys.argv[0])
73+
if re.search(r'load(?:$|\.)', script_name):
74+
action = help = LOAD
75+
elif re.search(r'dump(?:$|\.)', script_name):
76+
action = help = DUMP
77+
else:
78+
# default is dump, however if dump is specifically requested
79+
# we don't show help text for toggling between dumping and loading
80+
action = DUMP
81+
help = None
82+
83+
if help == LOAD:
84+
usage = "Usage: %prog [options] [FILE]"
85+
usage += "\n\nLoad data from FILE (which must be a JSON dump previously created"
86+
usage += "\nby redisdl) into specified or default redis."
87+
usage += "\n\nIf FILE is omitted standard input is read."
88+
elif help == DUMP:
89+
usage = "Usage: %prog [options]"
90+
usage += "\n\nDump data from specified or default redis."
91+
usage += "\n\nIf no output file is specified, dump to standard output."
92+
else:
93+
usage = "Usage: %prog [options]"
94+
usage += "\n %prog -l [options] [FILE]"
95+
usage += "\n\nDump data from redis or load data into redis."
96+
usage += "\n\nIf input or output file is specified, dump to standard output and load"
97+
usage += "\nfrom standard input."
98+
parser = optparse.OptionParser(usage=usage)
99+
parser.add_option('-w', '--password', help='connect with PASSWORD')
100+
if help == DUMP:
101+
parser.add_option('-n', '--dbname', help='dump DATABASE (APPL_DB/ASIC_DB...)')
102+
parser.add_option('-t', '--conntype', help='indicate redis connection type (tcp[default] or unix_socket)', default='tcp')
103+
parser.add_option('-k', '--keys', help='dump only keys matching specified glob-style pattern')
104+
parser.add_option('-o', '--output', help='write to OUTPUT instead of stdout')
105+
parser.add_option('-y', '--pretty', help='split output on multiple lines and indent it', action='store_true')
106+
parser.add_option('-E', '--encoding', help='set encoding to use while decoding data from redis', default='utf-8')
107+
elif help == LOAD:
108+
parser.add_option('-n', '--dbname', help='dump DATABASE (APPL_DB/ASIC_DB...)')
109+
parser.add_option('-t', '--conntype', help='indicate redis connection type (tcp[default] or unix_socket)', default='tcp')
110+
parser.add_option('-e', '--empty', help='delete all keys in destination db prior to loading', action='store_true')
111+
parser.add_option('-E', '--encoding', help='set encoding to use while encoding data to redis', default='utf-8')
112+
parser.add_option('-B', '--backend', help='use specified streaming backend')
113+
parser.add_option('-A', '--use-expireat', help='use EXPIREAT rather than TTL/EXPIRE', action='store_true')
114+
else:
115+
parser.add_option('-l', '--load', help='load data into redis (default is to dump data from redis)', action='store_true')
116+
parser.add_option('-n', '--dbname', help='dump DATABASE (APPL_DB/ASIC_DB/COUNTERS_DB/LOGLEVEL_DB/CONFIG_DB...)')
117+
parser.add_option('-t', '--conntype', help='indicate redis connection type (tcp[default] or unix_socket)', default='tcp')
118+
parser.add_option('-k', '--keys', help='dump only keys matching specified glob-style pattern')
119+
parser.add_option('-o', '--output', help='write to OUTPUT instead of stdout (dump mode only)')
120+
parser.add_option('-y', '--pretty', help='split output on multiple lines and indent it (dump mode only)', action='store_true')
121+
parser.add_option('-e', '--empty', help='delete all keys in destination db prior to loading (load mode only)', action='store_true')
122+
parser.add_option('-E', '--encoding', help='set encoding to use while decoding data from redis', default='utf-8')
123+
parser.add_option('-A', '--use-expireat', help='use EXPIREAT rather than TTL/EXPIRE', action='store_true')
124+
parser.add_option('-B', '--backend', help='use specified streaming backend (load mode only)')
125+
options, args = parser.parse_args()
126+
127+
if hasattr(options, 'load') and options.load:
128+
action = LOAD
129+
130+
if action == DUMP:
131+
if len(args) > 0:
132+
parser.print_help()
133+
exit(4)
134+
do_dump(options)
135+
else:
136+
if len(args) > 1:
137+
parser.print_help()
138+
exit(4)
139+
do_load(options, args)

0 commit comments

Comments
 (0)