diff --git a/config/main.py b/config/main.py index e9bab3172d..58a2186866 100644 --- a/config/main.py +++ b/config/main.py @@ -242,6 +242,22 @@ def _get_device_type(): return device_type +def _get_hwsku(config_db): + """ + Get hwsku from CONFIG_DB + + TODO: move to sonic-py-common + """ + + metadata = config_db.get_table('DEVICE_METADATA') + if metadata and 'localhost' in metadata and 'hwsku' in metadata['localhost']: + return metadata['localhost']['hwsku'] + + click.echo("Could not get the hwsku from CONFIG_DB, setting hwsku to Unknown") + hwsku = 'Unknown' + + return hwsku + def interface_alias_to_name(config_db, interface_alias): """Return default interface name if alias name is given as argument """ @@ -1284,11 +1300,13 @@ def load_minigraph(db, no_service_restart): log.log_info("'load_minigraph' stopping services...") _stop_services() + platform = device_info.get_platform() + # For Single Asic platform the namespace list has the empty string # for mulit Asic platform the empty string to generate the config # for host namespace_list = [DEFAULT_NAMESPACE] - num_npus = multi_asic.get_num_asics() + num_npus = device_info.get_num_npus() if num_npus > 1: namespace_list += multi_asic.get_namespaces_from_linux() @@ -1309,6 +1327,25 @@ def load_minigraph(db, no_service_restart): else: command = "{} -H -m --write-to-db {}".format(SONIC_CFGGEN_PATH, cfggen_namespace_option) clicommon.run_command(command, display_cmd=True) + + if namespace is DEFAULT_NAMESPACE: + npu_id = '' + else: + npu_id = device_info.get_npu_id_from_name(namespace) + + # load default_config.json file from platform directory + default_config_file = os.path.join('/usr/share/sonic/device/', platform, npu_id, 'default_config.json') + if os.path.isfile(default_config_file): + command = "{} -j {} {} --write-to-db".format(SONIC_CFGGEN_PATH, default_config_file, cfggen_namespace_option) + clicommon.run_command(command, display_cmd=True) + + hwsku = _get_hwsku(config_db) + # load default_config.json file from hwsku directory + default_config_file = os.path.join('/usr/share/sonic/device/', platform, hwsku, npu_id, 'default_config.json') + if os.path.isfile(default_config_file): + command = "{} -j {} {} --write-to-db".format(SONIC_CFGGEN_PATH, default_config_file, cfggen_namespace_option) + clicommon.run_command(command, display_cmd=True) + client.set(config_db.INIT_INDICATOR, 1) # get the device type diff --git a/tests/config_test.py b/tests/config_test.py index 32ecc5bdef..87fa51b888 100644 --- a/tests/config_test.py +++ b/tests/config_test.py @@ -18,9 +18,23 @@ import config.main as config -load_minigraph_command_output="""\ -Stopping SONiC target ... -Running command: /usr/local/bin/sonic-cfggen -H -m --write-to-db +def get_load_minigraph_command_output(init_cfg=False, default_config=False): + load_minigraph_command_output="""\ +Stopping SONiC target ...""" + + if init_cfg: + load_minigraph_command_output += """ +Running command: /usr/local/bin/sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db""" + else: + load_minigraph_command_output += """ +Running command: /usr/local/bin/sonic-cfggen -H -m --write-to-db""" + + if default_config: + load_minigraph_command_output += """ +Running command: /usr/local/bin/sonic-cfggen -j /usr/share/sonic/device/x86_64-mlnx_msn3800-r0/default_config.json --write-to-db +Running command: /usr/local/bin/sonic-cfggen -j /usr/share/sonic/device/x86_64-mlnx_msn3800-r0/Arista-VM/default_config.json --write-to-db""" + + load_minigraph_command_output += """ Running command: pfcwd start_default Running command: config qos reload --no-dynamic-buffer Restarting SONiC target ... @@ -28,6 +42,8 @@ Please note setting loaded from minigraph will be lost after system reboot. To preserve setting, run `config save`. """ + return load_minigraph_command_output + def mock_run_command_side_effect(*args, **kwargs): command = args[0] @@ -55,9 +71,38 @@ def test_load_minigraph(self, get_cmd_module, setup_single_broadcom_asic): print(result.output) traceback.print_tb(result.exc_info[2]) assert result.exit_code == 0 - assert "\n".join([l.rstrip() for l in result.output.split('\n')]) == load_minigraph_command_output + assert "\n".join([l.rstrip() for l in result.output.split('\n')]) == get_load_minigraph_command_output() + assert mock_run_command.call_count == 7 + + def test_load_minigraph_with_init_cfg(self, get_cmd_module, setup_single_broadcom_asic): + with mock.patch("utilities_common.cli.run_command", mock.MagicMock(side_effect=mock_run_command_side_effect)) as mock_run_command, \ + mock.patch("os.path.isfile") as mock_isfile: + mock_isfile.side_effect = lambda filename: filename.endswith( "init_cfg.json" ) + (config, show) = get_cmd_module + runner = CliRunner() + result = runner.invoke(config.config.commands["load_minigraph"], ["-y"]) + print(result.exit_code) + print(result.output) + traceback.print_tb(result.exc_info[2]) + assert result.exit_code == 0 + assert "\n".join([l.rstrip() for l in result.output.split('\n')]) == get_load_minigraph_command_output( init_cfg=True ) assert mock_run_command.call_count == 7 + def test_load_minigraph_with_default_config(self, get_cmd_module, setup_single_broadcom_asic): + with mock.patch("utilities_common.cli.run_command", mock.MagicMock(side_effect=mock_run_command_side_effect)) as mock_run_command, \ + mock.patch("os.path.isfile") as mock_isfile: + mock_isfile.side_effect = lambda filename: filename.endswith( "default_config.json" ) + (config, show) = get_cmd_module + runner = CliRunner() + result = runner.invoke(config.config.commands["load_minigraph"], ["-y"]) + print(result.exit_code) + print(result.output) + traceback.print_tb(result.exc_info[2]) + assert result.exit_code == 0 + assert "\n".join([l.rstrip() for l in result.output.split('\n')]) == get_load_minigraph_command_output( default_config=True ) + assert mock_run_command.call_count == 9 + + @classmethod def teardown_class(cls): os.environ['UTILITIES_UNIT_TESTING'] = "0" diff --git a/tests/conftest.py b/tests/conftest.py index 4ff1a002bd..f7a8c76c72 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -62,6 +62,7 @@ def set_mock_apis(): cwd = os.path.dirname(os.path.realpath(__file__)) config.asic_type = mock.MagicMock(return_value="broadcom") config._get_device_type = mock.MagicMock(return_value="ToRRouter") + config._get_hwsku = mock.MagicMock(return_value="Arista-VM") @pytest.fixture def setup_qos_mock_apis():