Skip to content

Commit 7e7d05c

Browse files
authored
Update the DBmigrator to support persistent loglevel during warm-upgrade (sonic-net#2370)
- What I did Add the ability to the user to save the loglevel and make it persistent to reboot with the support in warm-upgrade. (Not need to add special support for cold/fast reboot since the LOGLEVEL DB flushes during fast/cold reboot). - How I did it Add a new version to the db_migrator that will move the logger tables from the LOGLEVEL DB to the CONFIG DB - How to verify it 1. start with a switch that has an old master image (old master means that the VERSION in the config db is 3_0_5 or lower) 2. install this image to the switch 3. run warm-reboot 4. verify that the LOGLEVEL DB does not contain logger tables -> run redis-cli -n 3 keys "*" (expect to see only the JINJA2CACHE) 5. verify that the logger tables are in the config db -> run redis-cli -n 4 keys "LOGGER|*"
1 parent c2841b8 commit 7e7d05c

File tree

6 files changed

+103
-3
lines changed

6 files changed

+103
-3
lines changed

scripts/db_migrator.py

+33-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def __init__(self, namespace, socket=None):
4444
none-zero values.
4545
build: sequentially increase within a minor version domain.
4646
"""
47-
self.CURRENT_VERSION = 'version_3_0_5'
47+
self.CURRENT_VERSION = 'version_3_0_6'
4848

4949
self.TABLE_NAME = 'VERSIONS'
5050
self.TABLE_KEY = 'DATABASE'
@@ -70,6 +70,10 @@ def __init__(self, namespace, socket=None):
7070
if self.stateDB is not None:
7171
self.stateDB.connect(self.stateDB.STATE_DB)
7272

73+
self.loglevelDB = SonicV2Connector(host='127.0.0.1')
74+
if self.loglevelDB is not None:
75+
self.loglevelDB.connect(self.loglevelDB.LOGLEVEL_DB)
76+
7377
version_info = device_info.get_sonic_version_info()
7478
asic_type = version_info.get('asic_type')
7579
self.asic_type = asic_type
@@ -717,9 +721,36 @@ def version_3_0_4(self):
717721

718722
def version_3_0_5(self):
719723
"""
720-
Current latest version. Nothing to do here.
724+
Version 3_0_5
721725
"""
722726
log.log_info('Handling version_3_0_5')
727+
# Removing LOGLEVEL DB and moving it's content to CONFIG DB
728+
# Removing Jinja2_cache
729+
warmreboot_state = self.stateDB.get(self.stateDB.STATE_DB, 'WARM_RESTART_ENABLE_TABLE|system', 'enable')
730+
if warmreboot_state == 'true':
731+
table_name = "LOGGER"
732+
loglevel_field = "LOGLEVEL"
733+
logoutput_field = "LOGOUTPUT"
734+
keys = self.loglevelDB.keys(self.loglevelDB.LOGLEVEL_DB, "*")
735+
if keys is not None:
736+
for key in keys:
737+
if key != "JINJA2_CACHE":
738+
fvs = self.loglevelDB.get_all(self.loglevelDB.LOGLEVEL_DB, key)
739+
component = key.split(":")[1]
740+
loglevel = fvs[loglevel_field]
741+
logoutput = fvs[logoutput_field]
742+
self.configDB.set(self.configDB.CONFIG_DB, '{}|{}'.format(table_name, component), loglevel_field, loglevel)
743+
self.configDB.set(self.configDB.CONFIG_DB, '{}|{}'.format(table_name, component), logoutput_field, logoutput)
744+
self.loglevelDB.delete(self.loglevelDB.LOGLEVEL_DB, key)
745+
self.set_version('version_3_0_6')
746+
return 'version_3_0_6'
747+
748+
def version_3_0_6(self):
749+
"""
750+
Current latest version. Nothing to do here.
751+
"""
752+
753+
log.log_info('Handling version_3_0_6')
723754
return None
724755

725756
def get_version(self):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"VERSIONS|DATABASE": {
3+
"VERSION": "version_3_0_6"
4+
},
5+
"LOGGER|orchagent": {
6+
"LOGLEVEL": "INFO",
7+
"LOGOUTPUT": "SYSLOG"
8+
},
9+
"LOGGER|SAI_API_BUFFER": {
10+
"LOGLEVEL": "SAI_LOG_LEVEL_NOTICE",
11+
"LOGOUTPUT": "SYSLOG"
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"VERSIONS|DATABASE": {
3+
"VERSION": "version_3_0_5"
4+
}
5+
}

tests/db_migrator_input/config_db/reclaiming-buffer-warmreboot-expected.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2043,6 +2043,6 @@
20432043
"admin_status": "up"
20442044
},
20452045
"VERSIONS|DATABASE": {
2046-
"VERSION": "version_3_0_5"
2046+
"VERSION": "version_3_0_3"
20472047
}
20482048
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"orchagent:orchagent": {
3+
"LOGLEVEL": "INFO",
4+
"LOGOUTPUT": "SYSLOG"
5+
},
6+
"SAI_API_BUFFER:SAI_API_BUFFER": {
7+
"LOGLEVEL": "SAI_LOG_LEVEL_NOTICE",
8+
"LOGOUTPUT": "SYSLOG"
9+
},
10+
"JINJA2_CACHE": {}
11+
}

tests/db_migrator_test.py

+40
Original file line numberDiff line numberDiff line change
@@ -409,4 +409,44 @@ def test_global_dscp_to_tc_map_migrator(self):
409409
dbmgtr_mlnx.migrate()
410410
resulting_table = dbmgtr_mlnx.configDB.get_table('PORT_QOS_MAP')
411411
assert resulting_table == {}
412+
413+
class TestMoveLoggerTablesInWarmUpgrade(object):
414+
@classmethod
415+
def setup_class(cls):
416+
os.environ['UTILITIES_UNIT_TESTING'] = "2"
417+
418+
@classmethod
419+
def teardown_class(cls):
420+
os.environ['UTILITIES_UNIT_TESTING'] = "0"
421+
dbconnector.dedicated_dbs['CONFIG_DB'] = None
422+
dbconnector.dedicated_dbs['LOGLEVEL_DB'] = None
423+
dbconnector.dedicated_dbs['STATE_DB'] = None
424+
425+
def mock_dedicated_loglevel_db(self, filename):
426+
jsonfile = os.path.join(mock_db_path, 'loglevel_db', filename)
427+
dbconnector.dedicated_dbs['LOGLEVEL_DB'] = jsonfile
428+
loglevel_db = SonicV2Connector(host='127.0.0.1')
429+
loglevel_db.connect(loglevel_db.LOGLEVEL_DB)
430+
return loglevel_db
431+
432+
def test_move_logger_tables_in_warm_upgrade(self):
433+
device_info.get_sonic_version_info = get_sonic_version_info_mlnx
412434

435+
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'config_db', 'logger_tables_input')
436+
dbconnector.dedicated_dbs['LOGLEVEL_DB'] = os.path.join(mock_db_path, 'loglevel_db', 'logger_tables_input')
437+
dbconnector.dedicated_dbs['STATE_DB'] = os.path.join(mock_db_path, 'state_db')
438+
439+
import db_migrator
440+
dbmgtr = db_migrator.DBMigrator(None)
441+
dbmgtr.migrate()
442+
443+
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'config_db', 'logger_tables_expected')
444+
dbconnector.dedicated_dbs['LOGLEVEL_DB'] = os.path.join(mock_db_path, 'loglevel_db', 'logger_tables_expected')
445+
446+
expected_db = Db()
447+
448+
resulting_table = dbmgtr.configDB.get_table('LOGGER')
449+
expected_table = expected_db.cfgdb.get_table('LOGGER')
450+
451+
diff = DeepDiff(resulting_table, expected_table, ignore_order=True)
452+
assert not diff

0 commit comments

Comments
 (0)