Skip to content

Commit 884b847

Browse files
[KubeSonic] Add bmp container watchdog (#22352)
Why I did it Add bmp container watchdog, so that bmp could be managed/upgraded via k8s path. How I did it Add watchdog docker container with health check returned directly, will fill health check logic in following PR. How to verify it image verfication.
1 parent 0b55cb4 commit 884b847

File tree

13 files changed

+286
-0
lines changed

13 files changed

+286
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
FROM docker-config-engine-bookworm-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} AS builder
2+
3+
# Update apt's cache of available packages
4+
RUN apt-get update && apt-get install -y \
5+
build-essential
6+
7+
# Install Rust/Cargo via rustup
8+
ARG RUST_ROOT=/usr/.cargo
9+
RUN RUSTUP_HOME=$RUST_ROOT CARGO_HOME=$RUST_ROOT bash -c \
10+
'curl --proto "=https" -sSf https://sh.rustup.rs | sh -s -- --default-toolchain 1.79.0 -y'
11+
ENV RUSTUP_HOME=$RUST_ROOT
12+
ENV PATH $PATH:$RUST_ROOT/bin
13+
14+
# Copy watchdog source into /watchdog
15+
WORKDIR /watchdog
16+
COPY watchdog/ ./
17+
18+
# Build from within /watchdog
19+
RUN cargo build --release
20+
21+
FROM docker-config-engine-bookworm-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}}
22+
23+
ARG docker_container_name
24+
ARG image_version
25+
RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf
26+
27+
ENV DEBIAN_FRONTEND=noninteractive
28+
ENV IMAGE_VERSION=$image_version
29+
30+
RUN apt-get update
31+
32+
# Copy supervisord.conf into final stage
33+
COPY ["supervisord.conf", "/etc/supervisor/conf.d/"]
34+
35+
# Copy the compiled Rust binary from the builder stage
36+
COPY --from=builder /watchdog/target/release/bmp_watchdog /usr/bin/bmp_watchdog
37+
RUN chmod +x /usr/bin/bmp_watchdog
38+
39+
ENTRYPOINT ["/usr/local/bin/supervisord"]
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
[program:rsyslogd]
16+
command=/usr/sbin/rsyslogd -n -iNONE
17+
priority=1
18+
autostart=false
19+
autorestart=unexpected
20+
stdout_logfile=NONE
21+
stdout_syslog=true
22+
stderr_logfile=NONE
23+
stderr_syslog=true
24+
dependent_startup=true
25+
26+
[program:bmp_watchdog]
27+
command=/usr/bin/bmp_watchdog
28+
priority=3
29+
autostart=false
30+
autorestart=false
31+
startsecs=0
32+
stdout_logfile=NONE
33+
stdout_syslog=true
34+
stderr_logfile=NONE
35+
stderr_syslog=true
36+
dependent_startup=true
37+
dependent_startup_wait_for=rsyslogd:running

dockers/docker-bmp-watchdog/watchdog/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "bmp_watchdog"
3+
version = "0.1.0"
4+
edition = "2021"
5+
description = "watchdog for bmp container"
6+
license = "MIT"
7+
authors = ["Feng Pan"]
8+
9+
[dependencies]
10+
daemonize = "0.5"
11+
chrono = "0.4"
12+
serde = { version = "1.0", features = ["derive"] }
13+
serde_json = "1.0"
14+
15+
[[bin]]
16+
name = "bmp_watchdog"
17+
path = "src/main.rs"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
.ONESHELL:
2+
SHELL = /bin/bash
3+
.SHELLFLAGS += -e
4+
5+
#
6+
# Debug build targets
7+
#
8+
build:
9+
cargo build --all
10+
11+
test:
12+
cargo test --all
13+
14+
clean:
15+
cargo clean
16+
17+
#
18+
# Release build targets
19+
#
20+
build-release:
21+
cargo build --release --all
22+
23+
test-release:
24+
cargo test --release --all
25+
26+
clean-release:
27+
cargo clean --release
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
sonic (1.0.0) stable; urgency=medium
2+
3+
* Initial release
4+
5+
-- Feng Pan <[email protected]> Tue, 15 Apr 2025 03:13:12 +0000
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
11
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Source: sonic
2+
Maintainer: Feng Pan <[email protected]>
3+
Section: net
4+
Priority: optional
5+
Standards-Version: 1.0.0
6+
7+
Package: sonic-bmp-watchdog
8+
Architecture: any
9+
Description: bmp watchdog for KubeSONiC project
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
target/release/bmp_watchdog /usr/bin
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/make -f
2+
# See debhelper(7) (uncomment to enable)
3+
# output every command that modifies files on the build system.
4+
#export DH_VERBOSE = 1
5+
6+
%:
7+
dh $@
8+
9+
override_dh_auto_build:
10+
cargo build --release --all
11+
12+
override_dh_auto_clean:
13+
cargo clean --release
14+
15+
override_dh_auto_test:
16+
# do nothing
17+
:
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use std::io::{BufRead, BufReader, Write};
2+
use std::net::TcpListener;
3+
use std::process::Command;
4+
5+
use serde::Serialize;
6+
7+
#[derive(Serialize)]
8+
struct HealthStatus {
9+
check_bmp_supervisorctl: String,
10+
check_bmp_db: String,
11+
check_bmp_port: String,
12+
}
13+
14+
fn check_bmp_supervisorctl() -> String {
15+
// TODO: Replace with real health check
16+
"OK".to_string()
17+
}
18+
19+
fn check_bmp_db() -> String {
20+
// TODO: Replace with real health check
21+
"OK".to_string()
22+
}
23+
24+
fn check_bmp_port() -> String {
25+
// TODO: Replace with real health check
26+
"OK".to_string()
27+
}
28+
29+
fn main() {
30+
// Start a HTTP server listening on port 50058
31+
let listener = TcpListener::bind("127.0.0.1:50058")
32+
.expect("Failed to bind to 127.0.0.1:50058");
33+
34+
println!("Watchdog HTTP server running on http://127.0.0.1:50058");
35+
36+
for stream_result in listener.incoming() {
37+
match stream_result {
38+
Ok(mut stream) => {
39+
let mut reader = BufReader::new(&stream);
40+
let mut request_line = String::new();
41+
42+
if let Ok(_) = reader.read_line(&mut request_line) {
43+
println!("Received request: {}", request_line.trim_end());
44+
45+
if !request_line.starts_with("GET /") {
46+
let response = "HTTP/1.1 405 Method Not Allowed\r\n\r\n";
47+
stream.write_all(response.as_bytes()).ok();
48+
continue;
49+
}
50+
51+
let supervisorctl_result = check_bmp_supervisorctl();
52+
let db_result = check_bmp_db();
53+
let port_result = check_bmp_port();
54+
55+
let status = HealthStatus {
56+
check_bmp_supervisorctl: supervisorctl_result.clone(),
57+
check_bmp_db: db_result.clone(),
58+
check_bmp_port: port_result.clone(),
59+
};
60+
61+
let json_body = serde_json::to_string(&status).unwrap();
62+
let all_passed = [supervisorctl_result, db_result, port_result]
63+
.iter()
64+
.all(|s| s.starts_with("OK"));
65+
66+
let status_line = if all_passed {
67+
"HTTP/1.1 200 OK"
68+
} else {
69+
"HTTP/1.1 500 Internal Server Error"
70+
};
71+
72+
let response = format!(
73+
"{status_line}\r\nContent-Type: application/json\r\nContent-Length: {}\r\n\r\n{}",
74+
json_body.len(),
75+
json_body
76+
);
77+
78+
if let Err(e) = stream.write_all(response.as_bytes()) {
79+
eprintln!("Failed to write response: {}", e);
80+
}
81+
}
82+
}
83+
Err(e) => {
84+
eprintln!("Error accepting connection: {}", e);
85+
}
86+
}
87+
}
88+
}

rules/docker-bmp-watchdog.dep

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

rules/docker-bmp-watchdog.mk

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# docker image for bmp watchdog
2+
3+
DOCKER_BMP_WATCHDOG_STEM = docker-bmp-watchdog
4+
DOCKER_BMP_WATCHDOG = $(DOCKER_BMP_WATCHDOG_STEM).gz
5+
DOCKER_BMP_WATCHDOG_DBG = $(DOCKER_BMP_WATCHDOG_STEM)-$(DBG_IMAGE_MARK).gz
6+
7+
$(DOCKER_BMP_WATCHDOG)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BOOKWORM)
8+
9+
$(DOCKER_BMP_WATCHDOG)_PATH = $(DOCKERS_PATH)/$(DOCKER_BMP_WATCHDOG_STEM)
10+
11+
$(DOCKER_BMP_WATCHDOG)_VERSION = 1.0.0
12+
$(DOCKER_BMP_WATCHDOG)_PACKAGE_NAME = bmp_watchdog
13+
14+
SONIC_DOCKER_IMAGES += $(DOCKER_BMP_WATCHDOG)
15+
SONIC_BOOKWORM_DOCKERS += $(DOCKER_BMP_WATCHDOG)
16+
SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_BMP_WATCHDOG)
17+
18+
SONIC_DOCKER_DBG_IMAGES += $(DOCKER_BMP_WATCHDOG_DBG)
19+
SONIC_BOOKWORM_DBG_DOCKERS += $(DOCKER_BMP_WATCHDOG_DBG)
20+
SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_BMP_WATCHDOG_DBG)
21+
22+
$(DOCKER_BMP_WATCHDOG)_CONTAINER_NAME = bmp_watchdog
23+
$(DOCKER_BMP_WATCHDOG)_RUN_OPT += -t --privileged --pid=host
24+
$(DOCKER_BMP_WATCHDOG)_RUN_OPT += -v /lib/systemd/system:/lib/systemd/system:rw
25+
$(DOCKER_BMP_WATCHDOG)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
26+
$(DOCKER_BMP_WATCHDOG)_RUN_OPT += -v /etc/localtime:/etc/localtime:ro
27+
28+
$(DOCKER_BMP_WATCHDOG)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)

0 commit comments

Comments
 (0)