From a4bff506bcb98a776159bb189174d3d27baa437c Mon Sep 17 00:00:00 2001 From: anamehra Date: Wed, 11 Jan 2023 21:35:48 -0800 Subject: [PATCH 1/5] database-chassis python http-server implementation Python HTTP Server service. This service runs in database-chassis docker based on the configuration provided in device//chassisdb.conf Configuration parameters provided by chassisdb.conf are as follows: start_http_server: if "yes" or "1", http-server will be started on this node chassis_db_address : IP address for http-server. This is the same IP used for the chassis db server http_server_port : Port to bind to, default: 8000 http_server_dir : HTTP server home directory path, default: /var/www/ Signed-off-by: anamehra --- dockers/docker-database/Dockerfile.j2 | 1 + dockers/docker-database/http-server | 120 ++++++++++++++++++++ dockers/docker-database/supervisord.conf.j2 | 16 +++ 3 files changed, 137 insertions(+) create mode 100755 dockers/docker-database/http-server diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index b9d3669c0f49..dadf6276471a 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -44,5 +44,6 @@ COPY ["files/sysctl-net.conf", "/etc/sysctl.d/"] COPY ["critical_processes", "/etc/supervisor"] COPY ["files/update_chassisdb_config", "/usr/local/bin/"] COPY ["flush_unused_database", "/usr/local/bin/"] +COPY ["http-server", "/usr/local/bin/"] ENTRYPOINT ["/usr/local/bin/docker-database-init.sh"] diff --git a/dockers/docker-database/http-server b/dockers/docker-database/http-server new file mode 100755 index 000000000000..b0888bc489ae --- /dev/null +++ b/dockers/docker-database/http-server @@ -0,0 +1,120 @@ +#!/usr/bin/python3 +# +########################################################################### +# http-server +# +# Python HTTP Server service. +# This service runs based on the configuration provided in +# device//chassisdb.conf +# +# Configuration parameters provided by chassisdb.conf are as follows: +# +# start_http_server: if "yes" or "1", http-server will be started on this +# node +# chassis_db_address : IP address for http-server. This is the same IP used +# for the chassis db server +# http_server_port : Port to bind to, default: 8000 +# http_server_dir : HTTP server home directory path, default: /var/www/ +# +########################################################################### +# Copyright (c) 2021-2022 Cisco Systems, Inc. and its affiliates. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +########################################################################### + +# Example of config: +''' +start_http_server=yes +chassis_db_address=127.0.0.10 +http_server_port=8000 +http_server_dir=/var/www/tftp/ +''' + +import argparse +import http.server +import os +import socketserver +import subprocess +import syslog + +from pathlib import Path + +HTTP_DEFAULT_BIND_PORT = "8000" +HTTP_DEFAULT_DIR_PATH = '/var/www' +http_dir = None + +class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler): + def __init__(self, *args, **kwargs): + super().__init__(*args, directory=http_dir, **kwargs) + +class HttpServer(): + ''' HTTP server class implementation ''' + + def __init__(self, args, **kw): + self.http_config = {} + self.start_http_server = None + + if args.config_file: + # Use config file provided from command line + platform_conf = args.config_file + else: + platform_conf=os.path.join('/usr/share/sonic/platform', 'chassisdb.conf') + + syslog.syslog(syslog.LOG_INFO,'HTTP Server config file:{}'.format(platform_conf)) + if os.path.isfile(platform_conf): + with open(platform_conf) as f: + for line in f.readlines(): + (key, _, value) = line.strip().replace('"','').partition("=") + self.http_config[key] = value + else: + syslog.syslog(syslog.LOG_INFO, 'HTTP server config file {} not present - exiting...'.format(platform_conf)) + exit(0) + + self.http_server_ip = self.http_config.get('chassis_db_address') + if self.http_server_ip: + global http_dir + self.start_http_server = self.http_config.get('start_http_server') + http_dir = self.http_config.get('http_server_dir', HTTP_DEFAULT_DIR_PATH) + + # Get Server port from config + self.http_server_port = int(self.http_config.get('http_server_port', HTTP_DEFAULT_BIND_PORT)) + + # Create HTTP home dir path if not present + path = Path(http_dir) + path.mkdir(parents=True, exist_ok=True) + + def run(self): + ''' start the http-server if start_http_server is set in config file ''' + + if self.start_http_server == 'yes' or self.start_http_server == '1': + # Start the http-server, generally on the Supervisor card. + syslog.syslog(syslog.LOG_INFO, 'start_http_server is set, starting http-server') + if self.http_config: + with socketserver.TCPServer((self.http_server_ip, self.http_server_port), HTTPRequestHandler) as httpd: + syslog.syslog(syslog.LOG_INFO, 'HTTP Server Port:{} home:{}'.format(self.http_server_port, http_dir)) + httpd.serve_forever() + else: + syslog.syslog(syslog.LOG_INFO, 'start_http_server is not set, exiting...') + +def main(): + #import pdb; pdb.set_trace() + parser = argparse.ArgumentParser(description='Python3 HTTP Server') + parser.add_argument('--config-file', help='HTTP Server config yaml file', default=None) + args = parser.parse_args() + + HttpServer(args).run() + +if __name__ == '__main__': + main() diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 index c73c6e783e81..b9aee0c6c571 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/supervisord.conf.j2 @@ -56,3 +56,19 @@ stdout_logfile=syslog stderr_logfile=syslog dependent_startup=true dependent_startup_wait_for=rsyslogd:running + +{% if INSTANCES %} +{% for redis_inst, redis_items in INSTANCES.items() %} +{% if redis_inst == 'redis_chassis' %} +[program: http-server] +command=python3 /usr/local/bin/http-server +priority=3 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running +{%- endif -%} +{% endfor %} +{% endif %} From a99715b9277eea42b5b1c35d767e662900ccf7c3 Mon Sep 17 00:00:00 2001 From: anamehra <54692434+anamehra@users.noreply.github.com> Date: Wed, 1 Feb 2023 08:04:40 -0800 Subject: [PATCH 2/5] Removed commented code --- dockers/docker-database/http-server | 1 - 1 file changed, 1 deletion(-) diff --git a/dockers/docker-database/http-server b/dockers/docker-database/http-server index b0888bc489ae..5464b95caac4 100755 --- a/dockers/docker-database/http-server +++ b/dockers/docker-database/http-server @@ -109,7 +109,6 @@ class HttpServer(): syslog.syslog(syslog.LOG_INFO, 'start_http_server is not set, exiting...') def main(): - #import pdb; pdb.set_trace() parser = argparse.ArgumentParser(description='Python3 HTTP Server') parser.add_argument('--config-file', help='HTTP Server config yaml file', default=None) args = parser.parse_args() From 221bb96989355644443ec96dbee893d10443dac8 Mon Sep 17 00:00:00 2001 From: anamehra <54692434+anamehra@users.noreply.github.com> Date: Thu, 23 Feb 2023 08:53:31 -0800 Subject: [PATCH 3/5] Update supervisord.conf.j2 If the start_http_server is not set, the process exit with status 0 but it exits before reaching RUNNING state which happens after running for more than a sec. In such a scenario, supervisord restarts the process and mark state as FATAL. For exit with status 0, we do not want to restart the process. Fixed indentation --- dockers/docker-database/supervisord.conf.j2 | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 index b9aee0c6c571..852d20ac1344 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/supervisord.conf.j2 @@ -59,16 +59,20 @@ dependent_startup_wait_for=rsyslogd:running {% if INSTANCES %} {% for redis_inst, redis_items in INSTANCES.items() %} -{% if redis_inst == 'redis_chassis' %} +{%- if redis_inst == 'redis_chassis' %} [program: http-server] -command=python3 /usr/local/bin/http-server +; http-server should run only on database-chassis which hosts redis_chassis server. +; Using 2 sec sleep in command to give the process enough run time to reach +; RUNNING state when the process needs to exit with status 0 when start_http_server +; config is not set. +command=/bin/bash -c "sleep 2 && python3 /usr/local/bin/http-server" priority=3 autostart=true -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog dependent_startup=true dependent_startup_wait_for=rsyslogd:running -{%- endif -%} -{% endfor %} +{%- endif %} +{%- endfor %} {% endif %} From 7185cf6ebfab460240c17d13a1296ea48c3bc78a Mon Sep 17 00:00:00 2001 From: anamehra <54692434+anamehra@users.noreply.github.com> Date: Fri, 31 Mar 2023 08:53:59 -0700 Subject: [PATCH 4/5] Make /var/www accessible from database docker --- rules/docker-database.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/rules/docker-database.mk b/rules/docker-database.mk index b66583b9bd2c..ba1f3e7f5af9 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -27,6 +27,7 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DATABASE_DBG) $(DOCKER_DATABASE)_CONTAINER_NAME = database $(DOCKER_DATABASE)_RUN_OPT += --privileged -t $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_DATABASE)_RUN_OPT += -v /var/www/:/var/www/:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli $(DOCKER_DATABASE)_FILES += $(SYSCTL_NET_CONFIG) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From 4130990f976b7e97ff2ff562bd331b09bdd17c6c Mon Sep 17 00:00:00 2001 From: anamehra Date: Wed, 12 Jul 2023 20:00:34 -0700 Subject: [PATCH 5/5] Resolved conflict Signed-off-by: anamehra --- rules/docker-database.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/rules/docker-database.mk b/rules/docker-database.mk index ba1f3e7f5af9..92190619cbdd 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -27,6 +27,7 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DATABASE_DBG) $(DOCKER_DATABASE)_CONTAINER_NAME = database $(DOCKER_DATABASE)_RUN_OPT += --privileged -t $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_DATABASE)_RUN_OPT += -v /etc/timezone:/etc/timezone:ro $(DOCKER_DATABASE)_RUN_OPT += -v /var/www/:/var/www/:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli