From c7c4831baf2f60c7f63166244eb07c6ab7fe8b8a Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Fri, 1 Sep 2023 00:50:55 +0800 Subject: [PATCH] [db_migrator.py] Fix issue while upgrading from 202205 to 202211 via fast reboot (#2948) - What I did Fix issue while upgrading from 202205 to 202211 via fast reboot. This issue is caused by a mismatch version handling for fast reboot in db_migrator. This mismatch causes an incorrect sequence like this: 1. User issue fast-reboot under 202205 2. fast-reboot script set fast reboot flag by command "sonic-db-cli STATE_DB HSET "FAST_RESTART_ENABLE_TABLE|system" "enable" "true" &>/dev/null" 3. system boot to 202211 4. db_migrator found the database version is 3_0_6, it will run 4_0_0, however, it found FAST_REBOOT|system does not exist, and it set FAST_RESTART_ENABLE_TABLE|system enable to false 5. system incorrectly performs cold reboot - How I did it in db migrator if we see there is FAST_RESTART_ENABLE_TABLE already, we should skip fast reboot flag migration - How to verify it unit test manual test --- scripts/db_migrator.py | 17 ++++++++------- .../fast_reboot_upgrade_from_202205.json | 5 +++++ tests/db_migrator_test.py | 21 ++++++++++++++++++- 3 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 tests/db_migrator_input/state_db/fast_reboot_upgrade_from_202205.json diff --git a/scripts/db_migrator.py b/scripts/db_migrator.py index c2d0fd837a..d8d1ec24c5 100755 --- a/scripts/db_migrator.py +++ b/scripts/db_migrator.py @@ -691,7 +691,7 @@ def migrate_routing_config_mode(self): # overwrite the routing-config-mode as per minigraph parser # Criteria for update: # if config mode is missing in base OS or if base and target modes are not same - # Eg. in 201811 mode is "unified", and in newer branches mode is "separated" + # Eg. in 201811 mode is "unified", and in newer branches mode is "separated" if ('docker_routing_config_mode' not in device_metadata_old and 'docker_routing_config_mode' in device_metadata_new) or \ (device_metadata_old.get('docker_routing_config_mode') != device_metadata_new.get('docker_routing_config_mode')): device_metadata_old['docker_routing_config_mode'] = device_metadata_new.get('docker_routing_config_mode') @@ -1033,12 +1033,14 @@ def version_4_0_0(self): # reading FAST_REBOOT table can't be done with stateDB.get as it uses hget behind the scenes and the table structure is # not using hash and won't work. # FAST_REBOOT table exists only if fast-reboot was triggered. - keys = self.stateDB.keys(self.stateDB.STATE_DB, "FAST_REBOOT|system") - if keys: - enable_state = 'true' - else: - enable_state = 'false' - self.stateDB.set(self.stateDB.STATE_DB, 'FAST_RESTART_ENABLE_TABLE|system', 'enable', enable_state) + keys = self.stateDB.keys(self.stateDB.STATE_DB, "FAST_RESTART_ENABLE_TABLE|system") + if not keys: + keys = self.stateDB.keys(self.stateDB.STATE_DB, "FAST_REBOOT|system") + if keys: + enable_state = 'true' + else: + enable_state = 'false' + self.stateDB.set(self.stateDB.STATE_DB, 'FAST_RESTART_ENABLE_TABLE|system', 'enable', enable_state) self.set_version('version_4_0_1') return 'version_4_0_1' @@ -1057,7 +1059,6 @@ def version_4_0_2(self): Version 4_0_2. """ log.log_info('Handling version_4_0_2') - if self.stateDB.keys(self.stateDB.STATE_DB, "FAST_REBOOT|system"): self.migrate_config_db_flex_counter_delay_status() diff --git a/tests/db_migrator_input/state_db/fast_reboot_upgrade_from_202205.json b/tests/db_migrator_input/state_db/fast_reboot_upgrade_from_202205.json new file mode 100644 index 0000000000..b2e3169d4b --- /dev/null +++ b/tests/db_migrator_input/state_db/fast_reboot_upgrade_from_202205.json @@ -0,0 +1,5 @@ +{ + "FAST_RESTART_ENABLE_TABLE|system": { + "enable": "true" + } +} \ No newline at end of file diff --git a/tests/db_migrator_test.py b/tests/db_migrator_test.py index 7b4f842463..3f15f2c2e0 100644 --- a/tests/db_migrator_test.py +++ b/tests/db_migrator_test.py @@ -538,6 +538,25 @@ def test_rename_fast_reboot_table_check_enable(self): diff = DeepDiff(resulting_table, expected_table, ignore_order=True) assert not diff + def test_ignore_rename_fast_reboot_table(self): + device_info.get_sonic_version_info = get_sonic_version_info_mlnx + dbconnector.dedicated_dbs['STATE_DB'] = os.path.join(mock_db_path, 'state_db', 'fast_reboot_upgrade_from_202205') + dbconnector.dedicated_dbs['CONFIG_DB'] = os.path.join(mock_db_path, 'config_db', 'empty-config-input') + + import db_migrator + dbmgtr = db_migrator.DBMigrator(None) + dbmgtr.migrate() + + dbconnector.dedicated_dbs['STATE_DB'] = os.path.join(mock_db_path, 'state_db', 'fast_reboot_upgrade_from_202205') + expected_db = SonicV2Connector(host='127.0.0.1') + expected_db.connect(expected_db.STATE_DB) + + resulting_table = dbmgtr.stateDB.get_all(dbmgtr.stateDB.STATE_DB, 'FAST_RESTART_ENABLE_TABLE|system') + expected_table = expected_db.get_all(expected_db.STATE_DB, 'FAST_RESTART_ENABLE_TABLE|system') + + diff = DeepDiff(resulting_table, expected_table, ignore_order=True) + assert not diff + class TestWarmUpgrade_to_2_0_2(object): @classmethod def setup_class(cls): @@ -744,4 +763,4 @@ def test_fast_reboot_upgrade_to_4_0_3(self): expected_db = self.mock_dedicated_config_db(db_after_migrate) advance_version_for_expected_database(dbmgtr.configDB, expected_db.cfgdb, 'version_4_0_3') assert not self.check_config_db(dbmgtr.configDB, expected_db.cfgdb) - assert dbmgtr.CURRENT_VERSION == expected_db.cfgdb.get_entry('VERSIONS', 'DATABASE')['VERSION'] \ No newline at end of file + assert dbmgtr.CURRENT_VERSION == expected_db.cfgdb.get_entry('VERSIONS', 'DATABASE')['VERSION']