diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index 9ec3926de6fb..acb5e013fb84 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -32,6 +32,9 @@ RUN apt-get clean -y && \ s/^client-output-buffer-limit pubsub [0-9]+mb [0-9]+mb [0-9]+/client-output-buffer-limit pubsub 0 0 0/ \ ' /etc/redis/redis.conf -COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["supervisord.conf.j2", "/usr/share/sonic/templates/"] +COPY ["docker-database-init.sh", "/usr/local/bin/"] +COPY ["ping_pong_db_insts", "/usr/local/bin/"] +COPY ["database_config.json", "/etc/default/sonic-db/"] -ENTRYPOINT ["/usr/bin/supervisord"] +ENTRYPOINT ["/usr/local/bin/docker-database-init.sh"] diff --git a/dockers/docker-database/database_config.json b/dockers/docker-database/database_config.json new file mode 100644 index 000000000000..6725af38c5ea --- /dev/null +++ b/dockers/docker-database/database_config.json @@ -0,0 +1,43 @@ +{ + "INSTANCES": { + "redis":{ + "port": 6379, + "socket": "/var/run/redis/redis.sock" + } + }, + "DATABASES" : { + "APPL_DB" : { + "id" : 0, + "instance" : "redis" + }, + "ASIC_DB" : { + "id" : 1, + "instance" : "redis" + }, + "COUNTERS_DB" : { + "id" : 2, + "instance" : "redis" + }, + "LOGLEVEL_DB" : { + "id" : 3, + "instance" : "redis" + }, + "CONFIG_DB" : { + "id" : 4, + "instance" : "redis" + }, + "PFC_WD_DB" : { + "id" : 5, + "instance" : "redis" + }, + "FLEX_COUNTER_DB" : { + "id" : 5, + "instance" : "redis" + }, + "STATE_DB" : { + "id" : 6, + "instance" : "redis" + } + }, + "VERSION" : "1.0" +} diff --git a/dockers/docker-database/docker-database-init.sh b/dockers/docker-database/docker-database-init.sh new file mode 100755 index 000000000000..ebdcc6abb694 --- /dev/null +++ b/dockers/docker-database/docker-database-init.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +mkdir -p /var/run/redis/sonic-db +if [ -f /etc/sonic/database_config.json ]; then + cp /etc/sonic/database_config.json /var/run/redis/sonic-db +else + cp /etc/default/sonic-db/database_config.json /var/run/redis/sonic-db +fi + +mkdir -p /etc/supervisor/conf.d/ +# generate all redis server supervisord configuration file +sonic-cfggen -j /var/run/redis/sonic-db/database_config.json -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf + +exec /usr/bin/supervisord diff --git a/dockers/docker-database/ping_pong_db_insts b/dockers/docker-database/ping_pong_db_insts new file mode 100755 index 000000000000..484d4da0cfb0 --- /dev/null +++ b/dockers/docker-database/ping_pong_db_insts @@ -0,0 +1,40 @@ +#!/usr/bin/python +import json +import os +import subprocess +import time +import syslog + +def ping_redis(cmd): + output = '' + while True: + try: + output = subprocess.check_output(cmd, shell=True) + except subprocess.CalledProcessError as e: + syslog.syslog(syslog.LOG_ERR, 'ping redis failed, cmd : {}'.format(cmd)) + + if 'PONG' in output: + break + syslog.syslog(syslog.LOG_ERR, 'ping response : {}'.format(output)) + time.sleep(1) + +database_config_file = "/var/run/redis/sonic-db/database_config.json" + +data = {} +while True: + if os.path.isfile(database_config_file): + with open(database_config_file, "r") as read_file: + data = json.load(read_file) + break + time.sleep(1) + syslog.syslog(syslog.LOG_ERR, 'config file {} does not exist right now'.format(database_config_file)) + +while True: + if 'INSTANCES' in data: + for inst in data["INSTANCES"]: + port = data["INSTANCES"][inst]["port"] + cmd = "redis-cli -p " + str(port) + " ping" + ping_redis(cmd) + break + time.sleep(1) + syslog.syslog(syslog.LOG_ERR, 'config file {} does not have INSTANCES'.format(database_config_file)) diff --git a/dockers/docker-database/supervisord.conf b/dockers/docker-database/supervisord.conf deleted file mode 100644 index 798fedd0c895..000000000000 --- a/dockers/docker-database/supervisord.conf +++ /dev/null @@ -1,21 +0,0 @@ -[supervisord] -logfile_maxbytes=1MB -logfile_backups=2 -nodaemon=true - -[program:rsyslogd] -command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n" -priority=1 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - -[program:redis-server] -command=/bin/bash -c "{ [[ -s /var/lib/redis/dump.rdb ]] || rm -f /var/lib/redis/dump.rdb; } && exec /usr/bin/redis-server /etc/redis/redis.conf" -priority=2 -autostart=true -autorestart=false -stdout_logfile=syslog -stderr_logfile=syslog - diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 new file mode 100644 index 000000000000..9e4a42d6b3a4 --- /dev/null +++ b/dockers/docker-database/supervisord.conf.j2 @@ -0,0 +1,24 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:rsyslogd] +command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n" +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +{% if INSTANCES %} +{% for redis_inst, redis_items in INSTANCES.iteritems() %} +[program: {{ redis_inst }}] +command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --port {{ redis_items['port'] }} --unixsocket {{ redis_items['socket'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}" +priority=2 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +{% endfor %} +{% endif %} diff --git a/files/build_templates/database.service.j2 b/files/build_templates/database.service.j2 index efa98b168beb..472b9d328b7d 100644 --- a/files/build_templates/database.service.j2 +++ b/files/build_templates/database.service.j2 @@ -2,6 +2,7 @@ Description=Database container Requires=docker.service After=docker.service +After=rc-local.service [Service] User=root diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 9966728988bd..756ce16a2bc0 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -71,10 +71,7 @@ function postStartAction() { {%- if docker_container_name == "database" %} # Wait until redis starts - REDIS_SOCK="/var/run/redis/redis.sock" - until [[ $(/usr/bin/docker exec database redis-cli -s $REDIS_SOCK ping | grep -c PONG) -gt 0 ]]; do - sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then rm -f $WARM_DIR/dump.rdb else @@ -163,6 +160,11 @@ start() { {%- if docker_container_name == "database" %} echo "Creating new {{docker_container_name}} container" + # if database_config exists in old_config, use it; otherwise use the default one in new image + if [ -f /etc/sonic/old_config/database_config.json ]; then + echo "Use database_config.json from old system..." + mv /etc/sonic/old_config/database_config.json /etc/sonic/ + fi {%- else %} echo "Creating new {{docker_container_name}} container with HWSKU $HWSKU" {%- endif %}