From dd2ec2cdc68886b94dbd38fb7ed2f1f984fa6b0d Mon Sep 17 00:00:00 2001 From: Feng-msft Date: Fri, 29 Nov 2024 12:48:29 +0800 Subject: [PATCH] Fix bmpcfgd daemon integration bug (#20922) Why I did it Fix bmpcfgd daemon integration bug Work item tracking Microsoft ADO (number only):27511095 How I did it updated corresponding script code. How to verify it Verified on DUT, bmpcfgd observes config db and behave as expected, with syslog output. --- rules/docker-bmp.mk | 3 +- .../{scripts => bmpcfgd}/__init__.py | 0 .../{scripts/bmpcfgd => bmpcfgd/bmpcfgd.py} | 20 +++++---- src/sonic-bmpcfgd/setup.py | 42 +++++-------------- src/sonic-bmpcfgd/tests/bmpcfgd_test.py | 22 +++++----- 5 files changed, 34 insertions(+), 53 deletions(-) rename src/sonic-bmpcfgd/{scripts => bmpcfgd}/__init__.py (100%) rename src/sonic-bmpcfgd/{scripts/bmpcfgd => bmpcfgd/bmpcfgd.py} (77%) diff --git a/rules/docker-bmp.mk b/rules/docker-bmp.mk index 419f1ed2eccd..b38718a161c6 100644 --- a/rules/docker-bmp.mk +++ b/rules/docker-bmp.mk @@ -9,8 +9,7 @@ $(DOCKER_BMP)_PATH = $(DOCKERS_PATH)/$(DOCKER_BMP_STEM) $(DOCKER_BMP)_DEPENDS += $(LIBSWSSCOMMON) \ $(SONIC_BMPD) -$(DOCKER_BMP)_INSTALL_PYTHON_WHEELS = $(SONIC_BMPCFGD) \ - $(SONIC_UTILITIES_PY3) +$(DOCKER_BMP)_PYTHON_WHEELS = $(SONIC_BMPCFGD) $(DOCKER_BMP)_INSTALL_DEBS = $(LIBSWSSCOMMON) \ $(SONIC_BMPD) \ $(PYTHON3_SWSSCOMMON) \ diff --git a/src/sonic-bmpcfgd/scripts/__init__.py b/src/sonic-bmpcfgd/bmpcfgd/__init__.py similarity index 100% rename from src/sonic-bmpcfgd/scripts/__init__.py rename to src/sonic-bmpcfgd/bmpcfgd/__init__.py diff --git a/src/sonic-bmpcfgd/scripts/bmpcfgd b/src/sonic-bmpcfgd/bmpcfgd/bmpcfgd.py similarity index 77% rename from src/sonic-bmpcfgd/scripts/bmpcfgd rename to src/sonic-bmpcfgd/bmpcfgd/bmpcfgd.py index d6dd296b81bf..f8fa35fe253f 100644 --- a/src/sonic-bmpcfgd/scripts/bmpcfgd +++ b/src/sonic-bmpcfgd/bmpcfgd/bmpcfgd.py @@ -11,7 +11,7 @@ import signal from shutil import copy2 from datetime import datetime -from sonic_py_common import device_info +from sonic_py_common import logger from sonic_py_common.general import check_output_pipe from swsscommon.swsscommon import ConfigDBConnector, DBConnector, Table from swsscommon import swsscommon @@ -22,6 +22,7 @@ REDIS_HOSTIP = "127.0.0.1" BMP_TABLE = "BMP" SYSLOG_IDENTIFIER = "bmpcfgd" +logger = logger.Logger(SYSLOG_IDENTIFIER) def is_true(val): return str(val).lower() == 'true' @@ -40,7 +41,7 @@ def load(self, data={}): self.bgp_neighbor_table = is_true(common_config.get('bgp_neighbor_table', 'false')) self.bgp_rib_in_table = is_true(common_config.get('bgp_rib_in_table', 'false')) self.bgp_rib_out_table = is_true(common_config.get('bgp_rib_out_table', 'false')) - self.log_info(f'BMPCfg: update : {self.bgp_neighbor_table}, {self.bgp_rib_in_table}, {self.bgp_rib_out_table}') + logger.log_notice(f'bmpcfgd: config update : {self.bgp_neighbor_table}, {self.bgp_rib_in_table}, {self.bgp_rib_out_table}') # reset bmp table state once config is changed. self.stop_bmp() @@ -53,20 +54,20 @@ def cfg_handler(self, data): def stop_bmp(self): - self.log_info('BMPCfg: stop bmp daemon') - subprocess.call(["supervisorctl", "stop", "openbmpd"]) + logger.log_notice('bmpcfgd: stop bmp daemon') + subprocess.call(["supervisorctl", "stop", "sonic-bmp:openbmpd"]) def reset_bmp_table(self): - self.log_info('BMPCfg: Reset bmp table from state_db') + logger.log_notice('bmpcfgd: Reset bmp table from state_db') self.state_db_conn.delete_all_by_pattern(BMP_STATE_DB, 'BGP_NEIGHBOR*') self.state_db_conn.delete_all_by_pattern(BMP_STATE_DB, 'BGP_RIB_IN_TABLE*') self.state_db_conn.delete_all_by_pattern(BMP_STATE_DB, 'BGP_RIB_OUT_TABLE*') def start_bmp(self): - self.log_info('BMPCfg: start bmp daemon') - subprocess.call(["supervisorctl", "start", "openbmpd"]) + logger.log_notice('bmpcfgd: start bmp daemon') + subprocess.call(["supervisorctl", "start", "sonic-bmp:openbmpd"]) class BMPCfgDaemon: @@ -77,14 +78,15 @@ def __init__(self): self.config_db.connect(wait_for_init=True, retry_on=True) self.bmpcfg = BMPCfg(self.state_db_conn) - def bmp_handler(self, key, op, data): + def bmp_handler(self, key, data): data = self.config_db.get_table(BMP_TABLE) self.bmpcfg.cfg_handler(data) def register_callbacks(self): self.config_db.subscribe(BMP_TABLE, lambda table, key, data: - self.bmp_handler(key, op, data)) + self.bmp_handler(key, data)) + self.config_db.listen(init_data_handler=self.bmpcfg.load) def main(): daemon = BMPCfgDaemon() diff --git a/src/sonic-bmpcfgd/setup.py b/src/sonic-bmpcfgd/setup.py index 7c76da07e2dd..193b2094722e 100644 --- a/src/sonic-bmpcfgd/setup.py +++ b/src/sonic-bmpcfgd/setup.py @@ -1,10 +1,11 @@ -from __future__ import print_function -import sys -from setuptools import setup -import pkg_resources -from packaging import version +import setuptools -setup( + +dependencies = [ + 'sonic_py_common', +] + +setuptools.setup( name = 'sonic-bmpcfgd-services', version = '1.0', description = 'Python services which run in the bmp container', @@ -14,8 +15,9 @@ url = 'https://github.com/Azure/sonic-buildimage', maintainer = 'Feng Pan', maintainer_email = 'fenpan@microsoft.com', - scripts = [ - 'scripts/bmpcfgd' + packages=[ + 'bmpcfgd', + 'tests' ], install_requires = [ 'jinja2>=2.10', @@ -25,7 +27,7 @@ ], entry_points={ 'console_scripts': [ - 'bmpcfgd = scripts.bmpcfgd:main', + 'bmpcfgd = bmpcfgd.bmpcfgd:main', ] }, setup_requires = [ @@ -39,26 +41,4 @@ 'sonic-py-common', 'pytest-cov' ], - extras_require = { - "testing": [ - 'parameterized', - 'pytest', - 'pyfakefs', - 'sonic-py-common' - ] - }, - classifiers = [ - 'Development Status :: 3 - Alpha', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'Intended Audience :: Information Technology', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: Apache Software License', - 'Natural Language :: English', - 'Operating System :: POSIX :: Linux', - 'Programming Language :: Python :: 3.7', - 'Topic :: System', - ], - keywords = 'SONiC bmp config daemon', - test_suite = 'setup.get_test_suite' ) diff --git a/src/sonic-bmpcfgd/tests/bmpcfgd_test.py b/src/sonic-bmpcfgd/tests/bmpcfgd_test.py index ce6fbcf2a02f..f43ba77cf780 100644 --- a/src/sonic-bmpcfgd/tests/bmpcfgd_test.py +++ b/src/sonic-bmpcfgd/tests/bmpcfgd_test.py @@ -19,11 +19,11 @@ test_path = os.path.dirname(os.path.abspath(__file__)) modules_path = os.path.dirname(test_path) -scripts_path = os.path.join(modules_path, "scripts") +scripts_path = os.path.join(modules_path, "bmpcfgd") sys.path.insert(0, modules_path) # Load the file under test -bmpcfgd_path = os.path.join(scripts_path, 'bmpcfgd') +bmpcfgd_path = os.path.join(scripts_path, 'bmpcfgd.py') bmpcfgd = load_module_from_source('bmpcfgd', bmpcfgd_path) @@ -51,10 +51,10 @@ def test_bmpcfgd_neighbor_enable(self, mock_call, mock_log_info): MockConfigDb.set_config_db(self.test_data) bmp_config_daemon = bmpcfgd.BMPCfgDaemon() bmp_config_daemon.register_callbacks() - bmp_config_daemon.bmp_handler("BMP", '', self.test_data) + bmp_config_daemon.bmp_handler("BMP", self.test_data) expected_calls = [ - mock.call(["supervisorctl", "stop", "openbmpd"]), - mock.call(["supervisorctl", "start", "openbmpd"]) + mock.call(["supervisorctl", "stop", "sonic-bmp:openbmpd"]), + mock.call(["supervisorctl", "start", "sonic-bmp:openbmpd"]) ] mock_log_info.assert_has_calls(expected_calls) @@ -64,10 +64,10 @@ def test_bmpcfgd_bgp_rib_in_enable(self, mock_call, mock_log_info): self.test_data['BMP']['table']['bgp_rib_in_table'] = 'true' MockConfigDb.set_config_db(self.test_data) bmp_config_daemon = bmpcfgd.BMPCfgDaemon() - bmp_config_daemon.bmp_handler("BMP", '', self.test_data) + bmp_config_daemon.bmp_handler("BMP", self.test_data) expected_calls = [ - mock.call(["supervisorctl", "stop", "openbmpd"]), - mock.call(["supervisorctl", "start", "openbmpd"]) + mock.call(["supervisorctl", "stop", "sonic-bmp:openbmpd"]), + mock.call(["supervisorctl", "start", "sonic-bmp:openbmpd"]) ] mock_log_info.assert_has_calls(expected_calls) @@ -77,9 +77,9 @@ def test_bmpcfgd_bgp_rib_out_enable(self, mock_call, mock_log_info): self.test_data['BMP']['table']['bgp_rib_out_table'] = 'true' MockConfigDb.set_config_db(self.test_data) bmp_config_daemon = bmpcfgd.BMPCfgDaemon() - bmp_config_daemon.bmp_handler("BMP", '', self.test_data) + bmp_config_daemon.bmp_handler("BMP", self.test_data) expected_calls = [ - mock.call(["supervisorctl", "stop", "openbmpd"]), - mock.call(["supervisorctl", "start", "openbmpd"]) + mock.call(["supervisorctl", "stop", "sonic-bmp:openbmpd"]), + mock.call(["supervisorctl", "start", "sonic-bmp:openbmpd"]) ] mock_log_info.assert_has_calls(expected_calls) \ No newline at end of file