Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the DBmigrator to support persistent loglevel during warm-upgrade #2370

Merged
merged 12 commits into from
Oct 25, 2022
35 changes: 33 additions & 2 deletions scripts/db_migrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def __init__(self, namespace, socket=None):
none-zero values.
build: sequentially increase within a minor version domain.
"""
self.CURRENT_VERSION = 'version_3_0_5'
self.CURRENT_VERSION = 'version_3_0_6'

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

self.loglevelDB = SonicV2Connector(host='127.0.0.1')
if self.loglevelDB is not None:
self.loglevelDB.connect(self.loglevelDB.LOGLEVEL_DB)

version_info = device_info.get_sonic_version_info()
asic_type = version_info.get('asic_type')
self.asic_type = asic_type
Expand Down Expand Up @@ -717,9 +721,36 @@ def version_3_0_4(self):

def version_3_0_5(self):
"""
Current latest version. Nothing to do here.
Version 3_0_5
"""
log.log_info('Handling version_3_0_5')
# Removing LOGLEVEL DB and moving it's content to CONFIG DB
# Removing Jinja2_cache
warmreboot_state = self.stateDB.get(self.stateDB.STATE_DB, 'WARM_RESTART_ENABLE_TABLE|system', 'enable')
if warmreboot_state == 'true':
table_name = "LOGGER"
loglevel_field = "LOGLEVEL"
logoutput_field = "LOGOUTPUT"
keys = self.loglevelDB.keys(self.loglevelDB.LOGLEVEL_DB, "*")
if keys is not None:
for key in keys:
if key != "JINJA2_CACHE":
fvs = self.loglevelDB.get_all(self.loglevelDB.LOGLEVEL_DB, key)
component = key.split(":")[1]
loglevel = fvs[loglevel_field]
logoutput = fvs[logoutput_field]
self.configDB.set(self.configDB.CONFIG_DB, '{}|{}'.format(table_name, component), loglevel_field, loglevel)
self.configDB.set(self.configDB.CONFIG_DB, '{}|{}'.format(table_name, component), logoutput_field, logoutput)
self.loglevelDB.delete(self.loglevelDB.LOGLEVEL_DB, key)
self.set_version('version_3_0_6')
return 'version_3_0_6'

def version_3_0_6(self):
"""
Current latest version. Nothing to do here.
"""

log.log_info('Handling version_3_0_6')
return None

def get_version(self):
Expand Down
13 changes: 13 additions & 0 deletions tests/db_migrator_input/config_db/logger_tables_expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"VERSIONS|DATABASE": {
"VERSION": "version_3_0_6"
},
"LOGGER|orchagent": {
"LOGLEVEL": "INFO",
"LOGOUTPUT": "SYSLOG"
},
"LOGGER|SAI_API_BUFFER": {
"LOGLEVEL": "SAI_LOG_LEVEL_NOTICE",
"LOGOUTPUT": "SYSLOG"
}
}
5 changes: 5 additions & 0 deletions tests/db_migrator_input/config_db/logger_tables_input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"VERSIONS|DATABASE": {
"VERSION": "version_3_0_5"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2043,6 +2043,6 @@
"admin_status": "up"
},
"VERSIONS|DATABASE": {
"VERSION": "version_3_0_5"
"VERSION": "version_3_0_3"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this change needed? Is this relevant to persistance loglevel design?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, relevant to persistance loglevel design.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I am unable to understand, can you explain why tests for reclaiming-buffer need to be changed for persistence log-level design?

Copy link
Collaborator

@stephenxs stephenxs Oct 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @vaibhavhd
This is to change it back, correcting an error caused by an old PR. Refer this comment for details

}
}
11 changes: 11 additions & 0 deletions tests/db_migrator_input/loglevel_db/logger_tables_input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"orchagent:orchagent": {
"LOGLEVEL": "INFO",
"LOGOUTPUT": "SYSLOG"
},
"SAI_API_BUFFER:SAI_API_BUFFER": {
"LOGLEVEL": "SAI_LOG_LEVEL_NOTICE",
"LOGOUTPUT": "SYSLOG"
},
"JINJA2_CACHE": {}
}
40 changes: 40 additions & 0 deletions tests/db_migrator_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,4 +409,44 @@ def test_global_dscp_to_tc_map_migrator(self):
dbmgtr_mlnx.migrate()
resulting_table = dbmgtr_mlnx.configDB.get_table('PORT_QOS_MAP')
assert resulting_table == {}

class TestMoveLoggerTablesInWarmUpgrade(object):
@classmethod
def setup_class(cls):
os.environ['UTILITIES_UNIT_TESTING'] = "2"

@classmethod
def teardown_class(cls):
os.environ['UTILITIES_UNIT_TESTING'] = "0"
dbconnector.dedicated_dbs['CONFIG_DB'] = None
dbconnector.dedicated_dbs['LOGLEVEL_DB'] = None
dbconnector.dedicated_dbs['STATE_DB'] = None

def mock_dedicated_loglevel_db(self, filename):
jsonfile = os.path.join(mock_db_path, 'loglevel_db', filename)
dbconnector.dedicated_dbs['LOGLEVEL_DB'] = jsonfile
loglevel_db = SonicV2Connector(host='127.0.0.1')
loglevel_db.connect(loglevel_db.LOGLEVEL_DB)
return loglevel_db

def test_move_logger_tables_in_warm_upgrade(self):
device_info.get_sonic_version_info = get_sonic_version_info_mlnx

dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'config_db', 'logger_tables_input')
dbconnector.dedicated_dbs['LOGLEVEL_DB'] = os.path.join(mock_db_path, 'loglevel_db', 'logger_tables_input')
dbconnector.dedicated_dbs['STATE_DB'] = os.path.join(mock_db_path, 'state_db')

import db_migrator
dbmgtr = db_migrator.DBMigrator(None)
dbmgtr.migrate()

dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'config_db', 'logger_tables_expected')
dbconnector.dedicated_dbs['LOGLEVEL_DB'] = os.path.join(mock_db_path, 'loglevel_db', 'logger_tables_expected')

expected_db = Db()

resulting_table = dbmgtr.configDB.get_table('LOGGER')
expected_table = expected_db.cfgdb.get_table('LOGGER')

diff = DeepDiff(resulting_table, expected_table, ignore_order=True)
assert not diff