Skip to content

Commit

Permalink
[db_migrator] fix old 1911 feature config migration to a new one. (#1635
Browse files Browse the repository at this point in the history
)

* [db_migrator] fix old 1911 feature config migration to a new one.

This change is in addition to sonic-net/sonic-utilities#1522.
The init_cfg.json may have important fields added to configuration, while in
previous fix these entries will not be added when table already exists.
This change fixes this behaviour. Also, in order to preserve users auto_restart
configuration a special logic for migrating CONTAINER_FEATURE table has been implemented.
A test to cover this scenario is added.

Signed-off-by: Stepan Blyschak <[email protected]>
  • Loading branch information
stepanblyschak authored Jun 3, 2021
1 parent 56db162 commit f5f2a00
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 9 deletions.
35 changes: 26 additions & 9 deletions scripts/db_migrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,21 @@ def migrate_copp_table(self):
for copp_key in keys:
self.appDB.delete(self.appDB.APPL_DB, copp_key)

def migrate_feature_table(self):
'''
Combine CONTAINER_FEATURE and FEATURE tables into FEATURE table.
'''
feature_table = self.configDB.get_table('FEATURE')
for feature, config in feature_table.items():
state = config.pop('status', 'disabled')
config['state'] = state
self.configDB.set_entry('FEATURE', feature, config)

container_feature_table = self.configDB.get_table('CONTAINER_FEATURE')
for feature, config in container_feature_table.items():
self.configDB.mod_entry('FEATURE', feature, config)
self.configDB.set_entry('CONTAINER_FEATURE', feature, None)

def migrate_config_db_buffer_tables_for_dynamic_calculation(self, speed_list, cable_len_list, default_dynamic_th, abandon_method, append_item_method):
'''
Migrate buffer tables to dynamic calculation mode
Expand Down Expand Up @@ -419,6 +434,8 @@ def version_1_0_3(self):
"""
log.log_info('Handling version_1_0_3')

self.migrate_feature_table()

# Check ASIC type, if Mellanox platform then need DB migration
if self.asic_type == "mellanox":
if self.mellanox_buffer_migrator.mlnx_migrate_buffer_pool_size('version_1_0_3', 'version_1_0_4') \
Expand Down Expand Up @@ -520,15 +537,13 @@ def get_version(self):

return 'version_unknown'


def set_version(self, version=None):
if not version:
version = self.CURRENT_VERSION
log.log_info('Setting version to ' + version)
entry = { self.TABLE_FIELD : version }
self.configDB.set_entry(self.TABLE_NAME, self.TABLE_KEY, entry)


def common_migration_ops(self):
try:
with open(INIT_CFG_FILE) as f:
Expand All @@ -537,14 +552,16 @@ def common_migration_ops(self):
raise Exception(str(e))

for init_cfg_table, table_val in init_db.items():
data = self.configDB.get_table(init_cfg_table)
if data:
# Ignore overriding the values that pre-exist in configDB
continue
log.log_info("Migrating table {} from INIT_CFG to config_db".format(init_cfg_table))
# Update all tables that do not exist in configDB but are present in INIT_CFG
for init_table_key, init_table_val in table_val.items():
self.configDB.set_entry(init_cfg_table, init_table_key, init_table_val)
for key in table_val:
curr_cfg = self.configDB.get_entry(init_cfg_table, key)
init_cfg = table_val[key]

# Override init config with current config.
# This will leave new fields from init_config
# in new_config, but not override existing configuration.
new_cfg = {**init_cfg, **curr_cfg}
self.configDB.set_entry(init_cfg_table, key, new_cfg)

self.migrate_copp_table()

Expand Down
18 changes: 18 additions & 0 deletions tests/db_migrator_input/config_db/feature-expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"FEATURE|swss": {
"auto_restart": "disabled",
"has_global_scope": "False",
"has_per_asic_scope": "True",
"has_timer": "False",
"high_mem_alert": "disabled",
"state": "enabled"
},
"FEATURE|telemetry": {
"auto_restart": "enabled",
"has_global_scope": "False",
"has_per_asic_scope": "True",
"has_timer": "False",
"high_mem_alert": "disabled",
"state": "enabled"
}
}
13 changes: 13 additions & 0 deletions tests/db_migrator_input/config_db/feature-input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"CONTAINER_FEATURE|swss": {
"auto_restart": "disabled",
"high_mem_alert": "disabled"
},
"CONTAINER_FEATURE|telemetry": {
"auto_restart": "enabled",
"high_mem_alert": "disabled"
},
"FEATURE|telemetry": {
"status": "enabled"
}
}
18 changes: 18 additions & 0 deletions tests/db_migrator_input/init_cfg.json
Original file line number Diff line number Diff line change
@@ -1,2 +1,20 @@
{
"FEATURE": {
"swss": {
"auto_restart": "enabled",
"has_global_scope": "False",
"has_per_asic_scope": "True",
"has_timer": "False",
"high_mem_alert": "disabled",
"state": "enabled"
},
"telemetry": {
"auto_restart": "disabled",
"has_global_scope": "False",
"has_per_asic_scope": "True",
"has_timer": "False",
"high_mem_alert": "disabled",
"state": "disabled"
}
}
}
29 changes: 29 additions & 0 deletions tests/db_migrator_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import pytest
import sys

from deepdiff import DeepDiff

from swsssdk import SonicV2Connector
from sonic_py_common import device_info

Expand Down Expand Up @@ -218,3 +220,30 @@ def test_port_autoneg_migrator(self):

assert dbmgtr.configDB.get_table('PORT') == expected_db.cfgdb.get_table('PORT')
assert dbmgtr.configDB.get_table('VERSIONS') == expected_db.cfgdb.get_table('VERSIONS')


class TestInitConfigMigrator(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

def test_init_config_feature_migration(self):
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'config_db', 'feature-input')
import db_migrator
dbmgtr = db_migrator.DBMigrator(None)
dbmgtr.migrate()
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'config_db', 'feature-expected')
expected_db = Db()

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

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

assert not expected_db.cfgdb.get_table('CONTAINER_FEATURE')

0 comments on commit f5f2a00

Please sign in to comment.