Skip to content

Commit f8a78c1

Browse files
authoredNov 22, 2024
Build bmp container into sonic-buildimage (sonic-net#18946)
Why I did it Build bmp container into sonic-buildimage, and added relevant daemon/file handling. Work item tracking Microsoft ADO (number only):27588893 How I did it Build bmp container into sonic-buildimage, and added relevant daemon/file handling. How to verify it Local build successfully and verified in lab DUT.
1 parent 9e888d4 commit f8a78c1

27 files changed

+413
-101
lines changed
 

‎Makefile.work

+1
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ SONIC_BUILD_INSTRUCTION := $(MAKE) \
535535
SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD=$(SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD) \
536536
SONIC_INCLUDE_SYSTEM_TELEMETRY=$(INCLUDE_SYSTEM_TELEMETRY) \
537537
SONIC_INCLUDE_SYSTEM_GNMI=$(INCLUDE_SYSTEM_GNMI) \
538+
SONIC_INCLUDE_SYSTEM_BMP=$(INCLUDE_SYSTEM_BMP) \
538539
SONIC_INCLUDE_SYSTEM_EVENTD=$(INCLUDE_SYSTEM_EVENTD) \
539540
INCLUDE_DHCP_RELAY=$(INCLUDE_DHCP_RELAY) \
540541
INCLUDE_DHCP_SERVER=$(INCLUDE_DHCP_SERVER) \
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %}
2+
FROM docker-config-engine-bookworm-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}}
3+
4+
ARG docker_container_name
5+
ARG image_version
6+
7+
## Make apt-get non-interactive
8+
ENV DEBIAN_FRONTEND=noninteractive
9+
10+
# Pass the image_version to container
11+
ENV IMAGE_VERSION=$image_version
12+
13+
RUN apt-get update
14+
15+
{% if docker_sonic_bmp_debs.strip() -%}
16+
# Copy locally-built Debian package dependencies
17+
{{ copy_files("debs/", docker_sonic_bmp_debs.split(' '), "/debs/") }}
18+
19+
# Install locally-built Debian packages and implicitly install their dependencies
20+
{{ install_debian_packages(docker_sonic_bmp_debs.split(' ')) }}
21+
{%- endif %}
22+
23+
{% if docker_sonic_bmp_whls.strip() %}
24+
# Copy locally-built Python wheel dependencies
25+
{{ copy_files("python-wheels/", docker_sonic_bmp_whls.split(' '), "/python-wheels/") }}
26+
27+
# Install locally-built Python wheel dependencies
28+
{{ install_python_wheels(docker_sonic_bmp_whls.split(' ')) }}
29+
{% endif %}
30+
31+
RUN apt-get clean -y && \
32+
apt-get autoclean - && \
33+
apt-get autoremove -y && \
34+
rm -rf /debs && \
35+
mkdir -p /etc/bmp
36+
37+
COPY ["bmp.sh", "/usr/bin/"]
38+
COPY ["supervisord.conf", "/etc/supervisor/conf.d/"]
39+
COPY ["files/supervisor-proc-exit-listener", "/usr/bin"]
40+
COPY ["critical_processes", "/etc/supervisor/"]
41+
42+
RUN chmod +x /usr/bin/bmp.sh
43+
RUN touch /var/log/openbmpd.log
44+
45+
RUN apt-get clean -y && \
46+
apt-get autoclean -y && \
47+
apt-get autoremove -y && \
48+
rm -rf /debs
49+
50+
ENTRYPOINT ["/usr/local/bin/supervisord"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
###############################################################################
2+
## Monit configuration for bmp container
3+
###############################################################################
4+
check program container_memory_bmp with path "/usr/bin/memory_checker bmp 419430400"
5+
if status == 3 for 10 times within 20 cycles then exec "/usr/bin/docker exec bmp supervisorctl restart openbmpd"

‎dockers/docker-sonic-bmp/bmp.sh

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env bash
2+
3+
4+
if [ "${RUNTIME_OWNER}" == "" ]; then
5+
RUNTIME_OWNER="kube"
6+
fi
7+
8+
CTR_SCRIPT="/usr/share/sonic/scripts/container_startup.py"
9+
if test -f ${CTR_SCRIPT}
10+
then
11+
${CTR_SCRIPT} -f bmp -o ${RUNTIME_OWNER} -v ${IMAGE_VERSION}
12+
fi
13+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
group:sonic-bmp
2+
program:openbmpd
3+
program:bmpcfgd
+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
[supervisord]
2+
logfile_maxbytes=1MB
3+
logfile_backups=2
4+
nodaemon=true
5+
6+
[eventlistener:dependent-startup]
7+
command=python3 -m supervisord_dependent_startup
8+
autostart=true
9+
autorestart=unexpected
10+
startretries=0
11+
exitcodes=0,3
12+
events=PROCESS_STATE
13+
buffer_size=1024
14+
15+
[eventlistener:supervisor-proc-exit-listener]
16+
command=/usr/bin/supervisor-proc-exit-listener --container-name bmp
17+
events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING
18+
autostart=true
19+
autorestart=false
20+
buffer_size=1024
21+
22+
[program:rsyslogd]
23+
command=/usr/sbin/rsyslogd -n -iNONE
24+
priority=1
25+
autostart=false
26+
autorestart=true
27+
stdout_logfile=syslog
28+
stderr_logfile=syslog
29+
dependent_startup=true
30+
31+
[program:bmp]
32+
command=/usr/bin/bmp.sh
33+
priority=2
34+
autostart=false
35+
autorestart=false
36+
startsecs=0
37+
stdout_logfile=syslog
38+
stderr_logfile=syslog
39+
dependent_startup=true
40+
dependent_startup_wait_for=rsyslogd:running
41+
42+
[group:sonic-bmp]
43+
programs=openbmpd,bmpcfgd
44+
45+
[program:bmpcfgd]
46+
command=python3 /usr/local/bin/bmpcfgd
47+
priority=3
48+
autostart=false
49+
autorestart=false
50+
stdout_logfile=syslog
51+
stderr_logfile=syslog
52+
dependent_startup=true
53+
54+
[program:openbmpd]
55+
command=/usr/bin/openbmpd -f -l /var/log/openbmpd.log -c /etc/bmp/openbmpd.conf
56+
priority=3
57+
autostart=false
58+
autorestart=false
59+
stdout_logfile=syslog
60+
stderr_logfile=syslog
61+
dependent_startup=true

‎files/build_templates/bmp.service.j2

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[Unit]
2+
Description=BMP container
3+
Requires=database.service
4+
After=database.service
5+
Before=ntp-config.service
6+
BindsTo=sonic.target
7+
After=sonic.target
8+
StartLimitIntervalSec=1200
9+
StartLimitBurst=3
10+
11+
[Service]
12+
User={{ sonicadmin_user }}
13+
ExecStartPre=/usr/local/bin/{{docker_container_name}}.sh start
14+
ExecStart=/usr/local/bin/{{docker_container_name}}.sh wait
15+
ExecStop=/usr/local/bin/{{docker_container_name}}.sh stop
16+
RestartSec=30

‎files/build_templates/docker_image_ctl.j2

+2-2
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ function postStartAction()
292292
fi
293293

294294
# Add redis UDS to the redis group and give read/write access to the group
295+
REDIS_BMP_SOCK="/var/run/redis/redis_bmp.sock"
296+
chgrp -f redis $REDIS_BMP_SOCK && chmod -f 0760 $REDIS_BMP_SOCK
295297
REDIS_SOCK="/var/run/redis${DEV}/redis.sock"
296298
else
297299
until [[ ($(docker exec -i ${DOCKERNAME} pgrep -x -c supervisord) -gt 0) &&
@@ -303,9 +305,7 @@ function postStartAction()
303305
fi
304306
REDIS_SOCK="/var/run/redis-chassis/redis_chassis.sock"
305307
fi
306-
REDIS_BMP_SOCK="/var/run/redis/redis_bmp.sock"
307308
chgrp -f redis $REDIS_SOCK && chmod -f 0760 $REDIS_SOCK
308-
chgrp -f redis $REDIS_BMP_SOCK && chmod -f 0760 $REDIS_BMP_SOCK
309309
{%- elif docker_container_name == "swss" %}
310310
# Wait until swss container state is Running
311311
until [[ ($(docker inspect -f {{"'{{.State.Running}}'"}} swss$DEV) == "true") ]]; do

‎files/build_templates/sonic_debian_extension.j2

+1
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,7 @@ sudo LANG=C cp $SCRIPTS_DIR/database.sh $FILESYSTEM_ROOT/usr/local/bin/database.
10191019
sudo LANG=C cp $SCRIPTS_DIR/snmp.sh $FILESYSTEM_ROOT/usr/local/bin/snmp.sh
10201020
sudo LANG=C cp $SCRIPTS_DIR/telemetry.sh $FILESYSTEM_ROOT/usr/local/bin/telemetry.sh
10211021
sudo LANG=C cp $SCRIPTS_DIR/gnmi.sh $FILESYSTEM_ROOT/usr/local/bin/gnmi.sh
1022+
sudo LANG=C cp $SCRIPTS_DIR/bmp.sh $FILESYSTEM_ROOT/usr/local/bin/bmp.sh
10221023
sudo LANG=C cp $SCRIPTS_DIR/mgmt-framework.sh $FILESYSTEM_ROOT/usr/local/bin/mgmt-framework.sh
10231024
sudo LANG=C cp $SCRIPTS_DIR/asic_status.sh $FILESYSTEM_ROOT/usr/local/bin/asic_status.sh
10241025
sudo LANG=C cp $SCRIPTS_DIR/asic_status.py $FILESYSTEM_ROOT/usr/local/bin/asic_status.py

‎files/image_config/logrotate/rsyslog.j2

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
/var/log/teamd.log
3232
/var/log/telemetry.log
3333
/var/log/gnmi.log
34+
/var/log/bmp.log
3435
/var/log/frr/bgpd.log
3536
/var/log/frr/zebra.log
3637
/var/log/swss/sairedis*.rec

‎files/image_config/rsyslog/rsyslog.d/00-sonic.conf.j2

+6
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ if $msg startswith " gnmi-native" then {
4747
stop
4848
}
4949

50+
## bmp rules
51+
if $msg startswith " bmp" then {
52+
/var/log/bmp.log
53+
stop
54+
}
55+
5056
## telemetry rules
5157
if $msg startswith " telemetry" or ($msg startswith " dialout" )then {
5258
/var/log/telemetry.log

‎files/scripts/bmp.sh

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#!/bin/bash
2+
3+
function debug()
4+
{
5+
/usr/bin/logger $1
6+
}
7+
8+
function check_warm_boot()
9+
{
10+
SYSTEM_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable`
11+
SERVICE_WARM_START=`$SONIC_DB_CLI STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable`
12+
if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then
13+
WARM_BOOT="true"
14+
else
15+
WARM_BOOT="false"
16+
fi
17+
}
18+
19+
function check_fast_boot ()
20+
{
21+
SYSTEM_FAST_REBOOT=`sonic-db-cli STATE_DB hget "FAST_RESTART_ENABLE_TABLE|system" enable`
22+
if [[ x"${SYSTEM_FAST_REBOOT}" == x"true" ]]; then
23+
FAST_BOOT="true"
24+
else
25+
FAST_BOOT="false"
26+
fi
27+
}
28+
29+
function check_redundant_type()
30+
{
31+
DEVICE_SUBTYPE=`$SONIC_DB_CLI CONFIG_DB hget "DEVICE_METADATA|localhost" subtype`
32+
if [[ x"$DEVICE_SUBTYPE" == x"DualToR" ]]; then
33+
MUX_CONFIG=`show muxcable config`
34+
if [[ $MUX_CONFIG =~ .*active-active.* ]]; then
35+
ACTIVE_ACTIVE="true"
36+
else
37+
ACTIVE_ACTIVE="false"
38+
fi
39+
else
40+
ACTIVE_ACTIVE="false"
41+
fi
42+
CONFIG_KNOB=`$SONIC_DB_CLI CONFIG_DB hget "MUX_LINKMGR|SERVICE_MGMT" kill_radv`
43+
if [[ x"$CONFIG_KNOB" == x"False" ]]; then
44+
ACTIVE_ACTIVE='false'
45+
fi
46+
debug "DEVICE_SUBTYPE: ${DEVICE_SUBTYPE}, CONFIG_KNOB: ${CONFIG_KNOB}"
47+
}
48+
49+
start() {
50+
debug "Starting ${SERVICE}$DEV service..."
51+
52+
# start service docker
53+
/usr/bin/${SERVICE}.sh start $DEV
54+
debug "Started ${SERVICE}$DEV service..."
55+
}
56+
57+
wait() {
58+
/usr/bin/${SERVICE}.sh wait $DEV
59+
}
60+
61+
stop() {
62+
debug "Stopping ${SERVICE}$DEV service..."
63+
64+
check_warm_boot
65+
check_fast_boot
66+
check_redundant_type
67+
debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}."
68+
debug "Fast boot flag: ${SERVICE}$DEV ${FAST_BOOT}."
69+
70+
# For WARM/FAST boot do not perform service stop
71+
if [[ x"$WARM_BOOT" != x"true" ]] && [[ x"$FAST_BOOT" != x"true" ]]; then
72+
if [[ x"$SERVICE" == x"radv" ]] && [[ x"$ACTIVE_ACTIVE" == x"true" ]]; then
73+
debug "Killing Docker ${SERVICE}${DEV} for active-active dualtor device..."
74+
/usr/bin/${SERVICE}.sh kill $DEV
75+
else
76+
/usr/bin/${SERVICE}.sh stop $DEV
77+
debug "Stopped ${SERVICE}$DEV service..."
78+
fi
79+
else
80+
debug "Killing Docker ${SERVICE}${DEV}..."
81+
/usr/bin/${SERVICE}.sh kill $DEV
82+
fi
83+
}
84+
85+
DEV=$2
86+
87+
SCRIPT_NAME=$(basename -- "$0")
88+
SERVICE="${SCRIPT_NAME%.*}"
89+
NAMESPACE_PREFIX="asic"
90+
if [[ "$DEV" && "$DEV" != *"dpu"* ]]; then
91+
NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace
92+
SONIC_DB_CLI="sonic-db-cli -n $NET_NS"
93+
else
94+
SONIC_DB_CLI="sonic-db-cli"
95+
fi
96+
97+
case "$1" in
98+
start|wait|stop)
99+
$1
100+
;;
101+
*)
102+
echo "Usage: $0 {start|wait|stop}"
103+
exit 1
104+
;;
105+
esac

‎rules/config

+3
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ DEFAULT_VS_PREPARE_MEM = yes
124124
# INCLUDE_SYSTEM_GNMI - build docker-sonic-gnmi for system gnmi support
125125
INCLUDE_SYSTEM_GNMI = y
126126

127+
# INCLUDE_SYSTEM_BMP - build docker-sonic-bmp for system bmp support
128+
INCLUDE_SYSTEM_BMP = y
129+
127130
# INCLUDE_SYSTEM_EVENTD - build docker-eventd for system eventd support
128131
INCLUDE_SYSTEM_EVENTD = y
129132

‎rules/docker-bmp.dep

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
DPATH := $($(DOCKER_BMP)_PATH)
2+
DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-bmp.mk rules/docker-bmp.dep
3+
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
4+
DEP_FILES += $(shell git ls-files $(DPATH))
5+
6+
$(DOCKER_BMP)_CACHE_MODE := GIT_CONTENT_SHA
7+
$(DOCKER_BMP)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
8+
$(DOCKER_BMP)_DEP_FILES := $(DEP_FILES)
9+
10+
$(eval $(call add_dbg_docker,$(DOCKER_BMP),$(DOCKER_BMP_DBG)))

‎rules/docker-bmp.mk

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# docker image for BMP agent
2+
3+
DOCKER_BMP_STEM = docker-sonic-bmp
4+
DOCKER_BMP = $(DOCKER_BMP_STEM).gz
5+
DOCKER_BMP_DBG = $(DOCKER_BMP_STEM)-$(DBG_IMAGE_MARK).gz
6+
7+
$(DOCKER_BMP)_PATH = $(DOCKERS_PATH)/$(DOCKER_BMP_STEM)
8+
9+
$(DOCKER_BMP)_DEPENDS += $(LIBSWSSCOMMON) \
10+
$(SONIC_BMPD)
11+
12+
$(DOCKER_BMP)_INSTALL_PYTHON_WHEELS = $(SONIC_BMPCFGD) \
13+
$(SONIC_UTILITIES_PY3)
14+
$(DOCKER_BMP)_INSTALL_DEBS = $(LIBSWSSCOMMON) \
15+
$(SONIC_BMPD) \
16+
$(PYTHON3_SWSSCOMMON) \
17+
$(LIBYANG_PY3)
18+
19+
$(DOCKER_BMP)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BOOKWORM)_DBG_DEPENDS)
20+
21+
$(DOCKER_BMP)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BOOKWORM)
22+
23+
$(DOCKER_BMP)_VERSION = 1.0.0
24+
$(DOCKER_BMP)_PACKAGE_NAME = bmp
25+
26+
$(DOCKER_BMP)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BOOKWORM)_DBG_IMAGE_PACKAGES)
27+
28+
SONIC_DOCKER_IMAGES += $(DOCKER_BMP)
29+
SONIC_BOOKWORM_DOCKERS += $(DOCKER_BMP)
30+
ifeq ($(INCLUDE_SYSTEM_BMP), y)
31+
SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_BMP)
32+
endif
33+
34+
SONIC_DOCKER_DBG_IMAGES += $(DOCKER_BMP_DBG)
35+
SONIC_BOOKWORM_DBG_DOCKERS += $(DOCKER_BMP_DBG)
36+
ifeq ($(INCLUDE_SYSTEM_BMP), y)
37+
SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_BMP_DBG)
38+
endif
39+
40+
$(DOCKER_BMP)_CONTAINER_NAME = bmp
41+
$(DOCKER_BMP)_RUN_OPT += -t
42+
$(DOCKER_BMP)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
43+
$(DOCKER_BMP)_RUN_OPT += -v /etc/timezone:/etc/timezone:ro
44+
$(DOCKER_BMP)_RUN_OPT += -v /var/run/dbus:/var/run/dbus:rw
45+
46+
$(DOCKER_BMP)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)
47+
$(DOCKER_BMP)_BASE_IMAGE_FILES += monit_bmp:/etc/monit/conf.d

‎rules/sonic-bmp.dep

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
SPATH := $($(SONIC_BMPD)_SRC_PATH)
2+
DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-bmp.mk rules/sonic-bmp.dep
3+
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
4+
SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files))
5+
6+
$(SONIC_BMPD)_CACHE_MODE := GIT_CONTENT_SHA
7+
$(SONIC_BMPD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
8+
$(SONIC_BMPD)_DEP_FILES := $(DEP_FILES)
9+
$(SONIC_BMPD)_SMDEP_FILES := $(SMDEP_FILES)
10+
$(SONIC_BMPD)_SMDEP_PATHS := $(SPATH)

‎rules/sonic-bmp.mk

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# sonic-bmp package
2+
SONIC_BMPD = sonic-bmp_0.1_$(CONFIGURED_ARCH).deb
3+
$(SONIC_BMPD)_SRC_PATH = $(SRC_PATH)/sonic-bmp
4+
$(SONIC_BMPD)_DEPENDS = $(LIBSWSSCOMMON_DEV) $(LIBSWSSCOMMON)
5+
$(SONIC_BMPD)_RDEPENDS = $(LIBSWSSCOMMON)
6+
SONIC_DPKG_DEBS += $(SONIC_BMPD)

‎rules/sonic_bmpcfgd.dep

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
SPATH := $($(SONIC_BMPCFGD)_SRC_PATH)
3+
DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic_bmpcfgd.mk rules/sonic_bmpcfgd.dep
4+
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
5+
DEP_FILES += $(shell git ls-files $(SPATH))
6+
SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files))
7+
8+
$(SONIC_BMPCFGD)_CACHE_MODE := GIT_CONTENT_SHA
9+
$(SONIC_BMPCFGD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
10+
$(SONIC_BMPCFGD)_DEP_FILES := $(DEP_FILES)
11+
$(SONIC_BMPCFGD)_SMDEP_FILES := $(SMDEP_FILES)
12+
$(SONIC_BMPCFGD)_SMDEP_PATHS := $(SPATH)
13+

‎rules/sonic_bmpcfgd.mk

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# sonic-bmpcfgd package
2+
3+
SONIC_BMPCFGD = sonic_bmpcfgd_services-1.0-py3-none-any.whl
4+
$(SONIC_BMPCFGD)_SRC_PATH = $(SRC_PATH)/sonic-bmpcfgd
5+
$(SONIC_BMPCFGD)_PYTHON_VERSION = 3
6+
$(SONIC_BMPCFGD)_DEPENDS += $(SONIC_PY_COMMON_PY3) \
7+
$(SONIC_UTILITIES_PY3)
8+
$(SONIC_BMPCFGD)_DEBS_DEPENDS = $(LIBSWSSCOMMON) \
9+
$(PYTHON3_SWSSCOMMON)
10+
SONIC_PYTHON_WHEELS += $(SONIC_BMPCFGD)

‎slave.mk

+6
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ ifeq ($(SONIC_INCLUDE_SYSTEM_GNMI),y)
170170
INCLUDE_SYSTEM_GNMI = y
171171
endif
172172

173+
ifeq ($(SONIC_INCLUDE_SYSTEM_BMP),y)
174+
INCLUDE_SYSTEM_BMP = y
175+
endif
176+
173177
ifeq ($(SONIC_INCLUDE_SYSTEM_EVENTD),y)
174178
INCLUDE_SYSTEM_EVENTD = y
175179
endif
@@ -439,6 +443,7 @@ $(info "INCLUDE_MGMT_FRAMEWORK" : "$(INCLUDE_MGMT_FRAMEWORK)")
439443
$(info "INCLUDE_ICCPD" : "$(INCLUDE_ICCPD)")
440444
$(info "INCLUDE_SYSTEM_TELEMETRY" : "$(INCLUDE_SYSTEM_TELEMETRY)")
441445
$(info "INCLUDE_SYSTEM_GNMI" : "$(INCLUDE_SYSTEM_GNMI)")
446+
$(info "INCLUDE_SYSTEM_BMP" : "$(INCLUDE_SYSTEM_BMP)")
442447
$(info "INCLUDE_SYSTEM_EVENTD" : "$(INCLUDE_SYSTEM_EVENTD)")
443448
$(info "ENABLE_HOST_SERVICE_ON_START" : "$(ENABLE_HOST_SERVICE_ON_START)")
444449
$(info "INCLUDE_RESTAPI" : "$(INCLUDE_RESTAPI)")
@@ -1433,6 +1438,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
14331438
export sonic_su_prod_signing_tool="/sonic/scripts/$(shell basename -- $(SECURE_UPGRADE_PROD_SIGNING_TOOL))"
14341439
export include_system_telemetry="$(INCLUDE_SYSTEM_TELEMETRY)"
14351440
export include_system_gnmi="$(INCLUDE_SYSTEM_GNMI)"
1441+
export include_system_bmp="$(INCLUDE_SYSTEM_BMP)"
14361442
export include_system_eventd="$(INCLUDE_SYSTEM_EVENTD)"
14371443
export build_reduce_image_size="$(BUILD_REDUCE_IMAGE_SIZE)"
14381444
export include_restapi="$(INCLUDE_RESTAPI)"

‎sonic-slave-bookworm/Dockerfile.j2

+4
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@ RUN apt-get update && apt-get install -y eatmydata && eatmydata apt-get install
281281
libbsd-dev \
282282
pkg-config \
283283
check \
284+
# For bmp
285+
librdkafka-dev \
286+
libyaml-cpp-dev \
287+
libsasl2-dev \
284288
# For mpdecimal
285289
docutils-common \
286290
libjs-sphinxdoc \

‎src/sonic-bmpcfgd/data/debian/sonic-services-data.bmpcfgd.service

-14
This file was deleted.
File renamed without changes.

‎src/sonic-bmpcfgd/scripts/bmpcfgd

+3-19
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ CFG_DB = "CONFIG_DB"
2121
BMP_STATE_DB = "BMP_STATE_DB"
2222
REDIS_HOSTIP = "127.0.0.1"
2323
BMP_TABLE = "BMP"
24+
SYSLOG_IDENTIFIER = "bmpcfgd"
2425

2526
def is_true(val):
2627
return str(val).lower() == 'true'
@@ -36,7 +37,6 @@ class BMPCfg(DaemonBase):
3637

3738
def load(self, data={}):
3839
common_config = data.get('table', {})
39-
4040
self.bgp_neighbor_table = is_true(common_config.get('bgp_neighbor_table', 'false'))
4141
self.bgp_rib_in_table = is_true(common_config.get('bgp_rib_in_table', 'false'))
4242
self.bgp_rib_out_table = is_true(common_config.get('bgp_rib_out_table', 'false'))
@@ -54,7 +54,7 @@ class BMPCfg(DaemonBase):
5454

5555
def stop_bmp(self):
5656
self.log_info('BMPCfg: stop bmp daemon')
57-
subprocess.call(["service", "openbmpd", "stop"])
57+
subprocess.call(["supervisorctl", "stop", "openbmpd"])
5858

5959

6060
def reset_bmp_table(self):
@@ -66,7 +66,7 @@ class BMPCfg(DaemonBase):
6666

6767
def start_bmp(self):
6868
self.log_info('BMPCfg: start bmp daemon')
69-
subprocess.call(["service", "openbmpd", "start"])
69+
subprocess.call(["supervisorctl", "start", "openbmpd"])
7070

7171

7272
class BMPCfgDaemon:
@@ -86,23 +86,7 @@ class BMPCfgDaemon:
8686
lambda table, key, data:
8787
self.bmp_handler(key, op, data))
8888

89-
def signal_handler(sig, frame):
90-
if sig == signal.SIGHUP:
91-
self.log_info("bmpcfgd: signal 'SIGHUP' is caught and ignoring..")
92-
elif sig == signal.SIGINT:
93-
self.log_info("bmpcfgd: signal 'SIGINT' is caught and exiting...")
94-
sys.exit(128 + sig)
95-
elif sig == signal.SIGTERM:
96-
self.log_info("bmpcfgd: signal 'SIGTERM' is caught and exiting...")
97-
sys.exit(128 + sig)
98-
else:
99-
self.log_info("bmpcfgd: invalid signal - ignoring..")
100-
101-
10289
def main():
103-
signal.signal(signal.SIGTERM, signal_handler)
104-
signal.signal(signal.SIGINT, signal_handler)
105-
signal.signal(signal.SIGHUP, signal_handler)
10690
daemon = BMPCfgDaemon()
10791
daemon.register_callbacks()
10892

‎src/sonic-bmpcfgd/setup.py

+7-18
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,6 @@
44
import pkg_resources
55
from packaging import version
66

7-
# sonic_dependencies, version requirement only supports '>='
8-
sonic_dependencies = ['sonic-py-common', 'sonic-utilities']
9-
for package in sonic_dependencies:
10-
try:
11-
package_dist = pkg_resources.get_distribution(package.split(">=")[0])
12-
except pkg_resources.DistributionNotFound:
13-
print(package + " is not found!", file=sys.stderr)
14-
print("Please build and install SONiC python wheels dependencies from sonic-buildimage", file=sys.stderr)
15-
exit(1)
16-
if ">=" in package:
17-
if version.parse(package_dist.version) >= version.parse(package.split(">=")[1]):
18-
continue
19-
print(package + " version not match!", file=sys.stderr)
20-
exit(1)
21-
227
setup(
238
name = 'sonic-bmpcfgd-services',
249
version = '1.0',
@@ -29,7 +14,6 @@
2914
url = 'https://github.com/Azure/sonic-buildimage',
3015
maintainer = 'Feng Pan',
3116
maintainer_email = 'fenpan@microsoft.com',
32-
packages = setuptools.find_packages(),
3317
scripts = [
3418
'scripts/bmpcfgd'
3519
],
@@ -38,7 +22,12 @@
3822
'netaddr==0.8.0',
3923
'pyyaml==6.0.1',
4024
'ipaddress==1.0.23'
41-
] + sonic_dependencies,
25+
],
26+
entry_points={
27+
'console_scripts': [
28+
'bmpcfgd = scripts.bmpcfgd:main',
29+
]
30+
},
4231
setup_requires = [
4332
'pytest-runner',
4433
'wheel'
@@ -70,6 +59,6 @@
7059
'Programming Language :: Python :: 3.7',
7160
'Topic :: System',
7261
],
73-
keywords = 'sonic SONiC bmp services',
62+
keywords = 'SONiC bmp config daemon',
7463
test_suite = 'setup.get_test_suite'
7564
)

‎src/sonic-bmpcfgd/tests/bmpcfgd_test.py

+17-48
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
bmpcfgd = load_module_from_source('bmpcfgd', bmpcfgd_path)
2828

2929

30-
from bmpcfgd import signal_handler
31-
3230
original_syslog = bmpcfgd.syslog
3331

3432
# Mock swsscommon classes
@@ -46,71 +44,42 @@ def setUp(self):
4644
self.test_data['BMP'] = {}
4745
self.test_data['BMP']['table'] = {'bgp_neighbor_table': 'false', 'bgp_rib_in_table': 'false', 'bgp_rib_out_table': 'false'}
4846

49-
@mock.patch('sonic_installer.bootloader.get_bootloader', side_effect=[MockBootloader()])
50-
@mock.patch('syslog.syslog')
5147
@mock.patch('subprocess.call')
52-
def test_bmpcfgd_neighbor_enable(self, mock_check_call, mock_syslog, mock_get_bootloader):
48+
@mock.patch('bmpcfgd.BMPCfg.log_info')
49+
def test_bmpcfgd_neighbor_enable(self, mock_call, mock_log_info):
5350
self.test_data['BMP']['table']['bgp_neighbor_table'] = 'true'
5451
MockConfigDb.set_config_db(self.test_data)
5552
bmp_config_daemon = bmpcfgd.BMPCfgDaemon()
5653
bmp_config_daemon.register_callbacks()
5754
bmp_config_daemon.bmp_handler("BMP", '', self.test_data)
5855
expected_calls = [
59-
mock.call(original_syslog.LOG_INFO, 'BMPCfg: update : True, False, False'),
60-
mock.call(original_syslog.LOG_INFO, 'BMPCfg: stop bmp daemon'),
61-
mock.call(original_syslog.LOG_INFO, 'BMPCfg: Reset bmp table from state_db'),
62-
mock.call(original_syslog.LOG_INFO, 'BMPCfg: start bmp daemon'),
56+
mock.call(["supervisorctl", "stop", "openbmpd"]),
57+
mock.call(["supervisorctl", "start", "openbmpd"])
6358
]
64-
mock_syslog.assert_has_calls(expected_calls)
59+
mock_log_info.assert_has_calls(expected_calls)
6560

66-
@mock.patch('sonic_installer.bootloader.get_bootloader', side_effect=[MockBootloader()])
67-
@mock.patch('syslog.syslog')
68-
@mock.patch('subprocess.check_call')
69-
def test_bmpcfgd_bgp_rib_in_enable(self, mock_check_call, mock_syslog, mock_get_bootloader):
61+
@mock.patch('subprocess.call')
62+
@mock.patch('bmpcfgd.BMPCfg.log_info')
63+
def test_bmpcfgd_bgp_rib_in_enable(self, mock_call, mock_log_info):
7064
self.test_data['BMP']['table']['bgp_rib_in_table'] = 'true'
7165
MockConfigDb.set_config_db(self.test_data)
7266
bmp_config_daemon = bmpcfgd.BMPCfgDaemon()
7367
bmp_config_daemon.bmp_handler("BMP", '', self.test_data)
7468
expected_calls = [
75-
mock.call(original_syslog.LOG_INFO, 'BMPCfg: update : False, True, False'),
76-
mock.call(original_syslog.LOG_INFO, 'BMPCfg: stop bmp daemon'),
77-
mock.call(original_syslog.LOG_INFO, 'BMPCfg: Reset bmp table from state_db'),
78-
mock.call(original_syslog.LOG_INFO, 'BMPCfg: start bmp daemon'),
69+
mock.call(["supervisorctl", "stop", "openbmpd"]),
70+
mock.call(["supervisorctl", "start", "openbmpd"])
7971
]
80-
mock_syslog.assert_has_calls(expected_calls)
72+
mock_log_info.assert_has_calls(expected_calls)
8173

82-
@mock.patch('sonic_installer.bootloader.get_bootloader', side_effect=[MockBootloader()])
83-
@mock.patch('syslog.syslog')
84-
@mock.patch('subprocess.check_call')
85-
def test_bmpcfgd_bgp_rib_out_enable(self, mock_check_call, mock_syslog, mock_get_bootloader):
74+
@mock.patch('subprocess.call')
75+
@mock.patch('bmpcfgd.BMPCfg.log_info')
76+
def test_bmpcfgd_bgp_rib_out_enable(self, mock_call, mock_log_info):
8677
self.test_data['BMP']['table']['bgp_rib_out_table'] = 'true'
8778
MockConfigDb.set_config_db(self.test_data)
8879
bmp_config_daemon = bmpcfgd.BMPCfgDaemon()
8980
bmp_config_daemon.bmp_handler("BMP", '', self.test_data)
9081
expected_calls = [
91-
mock.call(original_syslog.LOG_INFO, 'BMPCfg: update : False, False, True'),
92-
mock.call(original_syslog.LOG_INFO, 'BMPCfg: stop bmp daemon'),
93-
mock.call(original_syslog.LOG_INFO, 'BMPCfg: Reset bmp table from state_db'),
94-
mock.call(original_syslog.LOG_INFO, 'BMPCfg: start bmp daemon'),
82+
mock.call(["supervisorctl", "stop", "openbmpd"]),
83+
mock.call(["supervisorctl", "start", "openbmpd"])
9584
]
96-
mock_syslog.assert_has_calls(expected_calls)
97-
98-
99-
@mock.patch('syslog.syslog')
100-
@mock.patch.object(sys, 'exit')
101-
def test_signal_handler(self, mock_exit, mock_syslog):
102-
# Test SIGHUP signal
103-
signal_handler(signal.SIGHUP, None)
104-
mock_syslog.assert_called_with(original_syslog.LOG_INFO, "bmpcfgd: signal 'SIGHUP' is caught and ignoring..")
105-
mock_exit.assert_not_called()
106-
# Test SIGINT signal
107-
signal_handler(signal.SIGINT, None)
108-
mock_syslog.assert_called_with(original_syslog.LOG_INFO, "bmpcfgd: signal 'SIGINT' is caught and exiting...")
109-
mock_exit.assert_called_once_with(128 + signal.SIGINT)
110-
# Test SIGTERM signal
111-
signal_handler(signal.SIGTERM, None)
112-
mock_syslog.assert_called_with(original_syslog.LOG_INFO, "bmpcfgd: signal 'SIGTERM' is caught and exiting...")
113-
mock_exit.assert_called_with(128 + signal.SIGTERM)
114-
# Test invalid signal
115-
signal_handler(999, None)
116-
mock_syslog.assert_called_with(original_syslog.LOG_INFO, "bmpcfgd: invalid signal - ignoring..")
85+
mock_log_info.assert_has_calls(expected_calls)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class MockBootloader(object):
2+
3+
def __init__(self, enforce=False):
4+
self.enforce = enforce
5+
6+
def get_next_image(self):
7+
return ""
8+
9+
def set_fips(self, image, enable):
10+
self.enforce = enable
11+
12+
def get_fips(self, image):
13+
return self.enforce

0 commit comments

Comments
 (0)
Please sign in to comment.