Skip to content

Commit f5f2a00

Browse files
[db_migrator] fix old 1911 feature config migration to a new one. (#1635)
* [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]>
1 parent 56db162 commit f5f2a00

File tree

5 files changed

+104
-9
lines changed

5 files changed

+104
-9
lines changed

scripts/db_migrator.py

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,21 @@ def migrate_copp_table(self):
174174
for copp_key in keys:
175175
self.appDB.delete(self.appDB.APPL_DB, copp_key)
176176

177+
def migrate_feature_table(self):
178+
'''
179+
Combine CONTAINER_FEATURE and FEATURE tables into FEATURE table.
180+
'''
181+
feature_table = self.configDB.get_table('FEATURE')
182+
for feature, config in feature_table.items():
183+
state = config.pop('status', 'disabled')
184+
config['state'] = state
185+
self.configDB.set_entry('FEATURE', feature, config)
186+
187+
container_feature_table = self.configDB.get_table('CONTAINER_FEATURE')
188+
for feature, config in container_feature_table.items():
189+
self.configDB.mod_entry('FEATURE', feature, config)
190+
self.configDB.set_entry('CONTAINER_FEATURE', feature, None)
191+
177192
def migrate_config_db_buffer_tables_for_dynamic_calculation(self, speed_list, cable_len_list, default_dynamic_th, abandon_method, append_item_method):
178193
'''
179194
Migrate buffer tables to dynamic calculation mode
@@ -419,6 +434,8 @@ def version_1_0_3(self):
419434
"""
420435
log.log_info('Handling version_1_0_3')
421436

437+
self.migrate_feature_table()
438+
422439
# Check ASIC type, if Mellanox platform then need DB migration
423440
if self.asic_type == "mellanox":
424441
if self.mellanox_buffer_migrator.mlnx_migrate_buffer_pool_size('version_1_0_3', 'version_1_0_4') \
@@ -520,15 +537,13 @@ def get_version(self):
520537

521538
return 'version_unknown'
522539

523-
524540
def set_version(self, version=None):
525541
if not version:
526542
version = self.CURRENT_VERSION
527543
log.log_info('Setting version to ' + version)
528544
entry = { self.TABLE_FIELD : version }
529545
self.configDB.set_entry(self.TABLE_NAME, self.TABLE_KEY, entry)
530546

531-
532547
def common_migration_ops(self):
533548
try:
534549
with open(INIT_CFG_FILE) as f:
@@ -537,14 +552,16 @@ def common_migration_ops(self):
537552
raise Exception(str(e))
538553

539554
for init_cfg_table, table_val in init_db.items():
540-
data = self.configDB.get_table(init_cfg_table)
541-
if data:
542-
# Ignore overriding the values that pre-exist in configDB
543-
continue
544555
log.log_info("Migrating table {} from INIT_CFG to config_db".format(init_cfg_table))
545-
# Update all tables that do not exist in configDB but are present in INIT_CFG
546-
for init_table_key, init_table_val in table_val.items():
547-
self.configDB.set_entry(init_cfg_table, init_table_key, init_table_val)
556+
for key in table_val:
557+
curr_cfg = self.configDB.get_entry(init_cfg_table, key)
558+
init_cfg = table_val[key]
559+
560+
# Override init config with current config.
561+
# This will leave new fields from init_config
562+
# in new_config, but not override existing configuration.
563+
new_cfg = {**init_cfg, **curr_cfg}
564+
self.configDB.set_entry(init_cfg_table, key, new_cfg)
548565

549566
self.migrate_copp_table()
550567

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"FEATURE|swss": {
3+
"auto_restart": "disabled",
4+
"has_global_scope": "False",
5+
"has_per_asic_scope": "True",
6+
"has_timer": "False",
7+
"high_mem_alert": "disabled",
8+
"state": "enabled"
9+
},
10+
"FEATURE|telemetry": {
11+
"auto_restart": "enabled",
12+
"has_global_scope": "False",
13+
"has_per_asic_scope": "True",
14+
"has_timer": "False",
15+
"high_mem_alert": "disabled",
16+
"state": "enabled"
17+
}
18+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"CONTAINER_FEATURE|swss": {
3+
"auto_restart": "disabled",
4+
"high_mem_alert": "disabled"
5+
},
6+
"CONTAINER_FEATURE|telemetry": {
7+
"auto_restart": "enabled",
8+
"high_mem_alert": "disabled"
9+
},
10+
"FEATURE|telemetry": {
11+
"status": "enabled"
12+
}
13+
}

tests/db_migrator_input/init_cfg.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,20 @@
11
{
2+
"FEATURE": {
3+
"swss": {
4+
"auto_restart": "enabled",
5+
"has_global_scope": "False",
6+
"has_per_asic_scope": "True",
7+
"has_timer": "False",
8+
"high_mem_alert": "disabled",
9+
"state": "enabled"
10+
},
11+
"telemetry": {
12+
"auto_restart": "disabled",
13+
"has_global_scope": "False",
14+
"has_per_asic_scope": "True",
15+
"has_timer": "False",
16+
"high_mem_alert": "disabled",
17+
"state": "disabled"
18+
}
19+
}
220
}

tests/db_migrator_test.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import pytest
33
import sys
44

5+
from deepdiff import DeepDiff
6+
57
from swsssdk import SonicV2Connector
68
from sonic_py_common import device_info
79

@@ -218,3 +220,30 @@ def test_port_autoneg_migrator(self):
218220

219221
assert dbmgtr.configDB.get_table('PORT') == expected_db.cfgdb.get_table('PORT')
220222
assert dbmgtr.configDB.get_table('VERSIONS') == expected_db.cfgdb.get_table('VERSIONS')
223+
224+
225+
class TestInitConfigMigrator(object):
226+
@classmethod
227+
def setup_class(cls):
228+
os.environ['UTILITIES_UNIT_TESTING'] = "2"
229+
230+
@classmethod
231+
def teardown_class(cls):
232+
os.environ['UTILITIES_UNIT_TESTING'] = "0"
233+
dbconnector.dedicated_dbs['CONFIG_DB'] = None
234+
235+
def test_init_config_feature_migration(self):
236+
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'config_db', 'feature-input')
237+
import db_migrator
238+
dbmgtr = db_migrator.DBMigrator(None)
239+
dbmgtr.migrate()
240+
dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'config_db', 'feature-expected')
241+
expected_db = Db()
242+
243+
resulting_table = dbmgtr.configDB.get_table('FEATURE')
244+
expected_table = expected_db.cfgdb.get_table('FEATURE')
245+
246+
diff = DeepDiff(resulting_table, expected_table, ignore_order=True)
247+
assert not diff
248+
249+
assert not expected_db.cfgdb.get_table('CONTAINER_FEATURE')

0 commit comments

Comments
 (0)