diff --git a/dockers/docker-base-bullseye/Dockerfile.j2 b/dockers/docker-base-bullseye/Dockerfile.j2 index 8d197d3c9011..479c7f74246d 100644 --- a/dockers/docker-base-bullseye/Dockerfile.j2 +++ b/dockers/docker-base-bullseye/Dockerfile.j2 @@ -86,7 +86,7 @@ RUN pip3 install supervisor==4.2.1 # Add support for supervisord to handle startup dependencies RUN pip3 install supervisord-dependent-startup==1.4.0 -RUN mkdir -p /etc/supervisor /var/log/supervisor +RUN mkdir -p /etc/supervisor /var/log/supervisor /etc/supervisor/conf.d RUN apt-get -y purge \ exim4 \ @@ -109,10 +109,10 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/* /tmp/* ~/.cache -COPY ["etc/rsyslog.conf", "/etc/rsyslog.conf"] COPY ["etc/rsyslog.d/*", "/etc/rsyslog.d/"] COPY ["root/.vimrc", "/root/.vimrc"] RUN ln /usr/bin/vim.tiny /usr/bin/vim COPY ["etc/supervisor/supervisord.conf", "/etc/supervisor/"] +COPY ["etc/supervisor/containercfgd.conf", "/etc/supervisor/conf.d/"] diff --git a/dockers/docker-base-bullseye/etc/rsyslog.conf b/dockers/docker-base-bullseye/etc/rsyslog.conf deleted file mode 100644 index ef249229ab1e..000000000000 --- a/dockers/docker-base-bullseye/etc/rsyslog.conf +++ /dev/null @@ -1,76 +0,0 @@ -# -# /etc/rsyslog.conf Configuration file for rsyslog. -# -# For more information see -# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html - - -################# -#### MODULES #### -################# - -$ModLoad imuxsock # provides support for local system logging - -# -# Set a rate limit on messages from the container -# -$SystemLogRateLimitInterval 300 -$SystemLogRateLimitBurst 20000 - -#$ModLoad imklog # provides kernel logging support -#$ModLoad immark # provides --MARK-- message capability - -# provides UDP syslog reception -#$ModLoad imudp -#$UDPServerRun 514 - -# provides TCP syslog reception -#$ModLoad imtcp -#$InputTCPServerRun 514 - - -########################### -#### GLOBAL DIRECTIVES #### -########################### - -# Set remote syslog server -template (name="ForwardFormatInContainer" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%") -*.* action(type="omfwd" target="127.0.0.1" port="514" protocol="udp" Template="ForwardFormatInContainer") - -# -# Use traditional timestamp format. -# To enable high precision timestamps, comment out the following line. -# -#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat - -# Define a custom template -$template SONiCFileFormat,"%TIMESTAMP%.%timestamp:::date-subseconds% %HOSTNAME% %syslogseverity-text:::uppercase% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" -$ActionFileDefaultTemplate SONiCFileFormat - -# -# Set the default permissions for all log files. -# -$FileOwner root -$FileGroup adm -$FileCreateMode 0640 -$DirCreateMode 0755 -$Umask 0022 - -# -# Where to place spool and state files -# -$WorkDirectory /var/spool/rsyslog - -# -# Include all config files in /etc/rsyslog.d/ -# -$IncludeConfig /etc/rsyslog.d/*.conf - -# -# Suppress duplicate messages and report "message repeated n times" -# -$RepeatedMsgReduction on - -############### -#### RULES #### -############### diff --git a/dockers/docker-base-bullseye/etc/supervisor/containercfgd.conf b/dockers/docker-base-bullseye/etc/supervisor/containercfgd.conf new file mode 100644 index 000000000000..704b5490c3fb --- /dev/null +++ b/dockers/docker-base-bullseye/etc/supervisor/containercfgd.conf @@ -0,0 +1,9 @@ +[program:containercfgd] +command=python3 /usr/local/bin/containercfgd +priority=99 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/dockers/docker-base-buster/Dockerfile.j2 b/dockers/docker-base-buster/Dockerfile.j2 index 9118287cac39..ec9cdb40703d 100644 --- a/dockers/docker-base-buster/Dockerfile.j2 +++ b/dockers/docker-base-buster/Dockerfile.j2 @@ -100,7 +100,7 @@ RUN pip3 install supervisor==4.2.1 # Add support for supervisord to handle startup dependencies RUN pip3 install supervisord-dependent-startup==1.4.0 -RUN mkdir -p /etc/supervisor /var/log/supervisor +RUN mkdir -p /etc/supervisor /var/log/supervisor /etc/supervisor/conf.d RUN apt-get -y purge \ exim4 \ @@ -123,10 +123,10 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/* /tmp/* ~/.cache/ -COPY ["etc/rsyslog.conf", "/etc/rsyslog.conf"] COPY ["etc/rsyslog.d/*", "/etc/rsyslog.d/"] COPY ["root/.vimrc", "/root/.vimrc"] RUN ln /usr/bin/vim.tiny /usr/bin/vim COPY ["etc/supervisor/supervisord.conf", "/etc/supervisor/"] +COPY ["etc/supervisor/containercfgd.conf", "/etc/supervisor/conf.d/"] diff --git a/dockers/docker-base-buster/etc/rsyslog.conf b/dockers/docker-base-buster/etc/rsyslog.conf deleted file mode 100644 index ef249229ab1e..000000000000 --- a/dockers/docker-base-buster/etc/rsyslog.conf +++ /dev/null @@ -1,76 +0,0 @@ -# -# /etc/rsyslog.conf Configuration file for rsyslog. -# -# For more information see -# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html - - -################# -#### MODULES #### -################# - -$ModLoad imuxsock # provides support for local system logging - -# -# Set a rate limit on messages from the container -# -$SystemLogRateLimitInterval 300 -$SystemLogRateLimitBurst 20000 - -#$ModLoad imklog # provides kernel logging support -#$ModLoad immark # provides --MARK-- message capability - -# provides UDP syslog reception -#$ModLoad imudp -#$UDPServerRun 514 - -# provides TCP syslog reception -#$ModLoad imtcp -#$InputTCPServerRun 514 - - -########################### -#### GLOBAL DIRECTIVES #### -########################### - -# Set remote syslog server -template (name="ForwardFormatInContainer" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%") -*.* action(type="omfwd" target="127.0.0.1" port="514" protocol="udp" Template="ForwardFormatInContainer") - -# -# Use traditional timestamp format. -# To enable high precision timestamps, comment out the following line. -# -#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat - -# Define a custom template -$template SONiCFileFormat,"%TIMESTAMP%.%timestamp:::date-subseconds% %HOSTNAME% %syslogseverity-text:::uppercase% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" -$ActionFileDefaultTemplate SONiCFileFormat - -# -# Set the default permissions for all log files. -# -$FileOwner root -$FileGroup adm -$FileCreateMode 0640 -$DirCreateMode 0755 -$Umask 0022 - -# -# Where to place spool and state files -# -$WorkDirectory /var/spool/rsyslog - -# -# Include all config files in /etc/rsyslog.d/ -# -$IncludeConfig /etc/rsyslog.d/*.conf - -# -# Suppress duplicate messages and report "message repeated n times" -# -$RepeatedMsgReduction on - -############### -#### RULES #### -############### diff --git a/dockers/docker-base-buster/etc/supervisor/containercfgd.conf b/dockers/docker-base-buster/etc/supervisor/containercfgd.conf new file mode 100644 index 000000000000..704b5490c3fb --- /dev/null +++ b/dockers/docker-base-buster/etc/supervisor/containercfgd.conf @@ -0,0 +1,9 @@ +[program:containercfgd] +command=python3 /usr/local/bin/containercfgd +priority=99 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index 5603dc502792..2a12483ef814 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -96,7 +96,7 @@ RUN pip install supervisor>=3.4.0 # Add support for supervisord to handle startup dependencies RUN pip install supervisord-dependent-startup==1.4.0 -RUN mkdir -p /etc/supervisor /var/log/supervisor +RUN mkdir -p /etc/supervisor /var/log/supervisor /etc/supervisor/conf.d RUN apt-get -y purge \ exim4 \ @@ -119,10 +119,10 @@ RUN apt-get clean -y && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/* /tmp/* -COPY ["etc/rsyslog.conf", "/etc/rsyslog.conf"] COPY ["etc/rsyslog.d/*", "/etc/rsyslog.d/"] COPY ["root/.vimrc", "/root/.vimrc"] RUN ln /usr/bin/vim.tiny /usr/bin/vim COPY ["etc/supervisor/supervisord.conf", "/etc/supervisor/"] +COPY ["etc/supervisor/containercfgd.conf", "/etc/supervisor/conf.d/"] diff --git a/dockers/docker-base-stretch/etc/rsyslog.conf b/dockers/docker-base-stretch/etc/rsyslog.conf deleted file mode 100644 index ef249229ab1e..000000000000 --- a/dockers/docker-base-stretch/etc/rsyslog.conf +++ /dev/null @@ -1,76 +0,0 @@ -# -# /etc/rsyslog.conf Configuration file for rsyslog. -# -# For more information see -# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html - - -################# -#### MODULES #### -################# - -$ModLoad imuxsock # provides support for local system logging - -# -# Set a rate limit on messages from the container -# -$SystemLogRateLimitInterval 300 -$SystemLogRateLimitBurst 20000 - -#$ModLoad imklog # provides kernel logging support -#$ModLoad immark # provides --MARK-- message capability - -# provides UDP syslog reception -#$ModLoad imudp -#$UDPServerRun 514 - -# provides TCP syslog reception -#$ModLoad imtcp -#$InputTCPServerRun 514 - - -########################### -#### GLOBAL DIRECTIVES #### -########################### - -# Set remote syslog server -template (name="ForwardFormatInContainer" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%") -*.* action(type="omfwd" target="127.0.0.1" port="514" protocol="udp" Template="ForwardFormatInContainer") - -# -# Use traditional timestamp format. -# To enable high precision timestamps, comment out the following line. -# -#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat - -# Define a custom template -$template SONiCFileFormat,"%TIMESTAMP%.%timestamp:::date-subseconds% %HOSTNAME% %syslogseverity-text:::uppercase% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" -$ActionFileDefaultTemplate SONiCFileFormat - -# -# Set the default permissions for all log files. -# -$FileOwner root -$FileGroup adm -$FileCreateMode 0640 -$DirCreateMode 0755 -$Umask 0022 - -# -# Where to place spool and state files -# -$WorkDirectory /var/spool/rsyslog - -# -# Include all config files in /etc/rsyslog.d/ -# -$IncludeConfig /etc/rsyslog.d/*.conf - -# -# Suppress duplicate messages and report "message repeated n times" -# -$RepeatedMsgReduction on - -############### -#### RULES #### -############### diff --git a/dockers/docker-base-stretch/etc/supervisor/containercfgd.conf b/dockers/docker-base-stretch/etc/supervisor/containercfgd.conf new file mode 100644 index 000000000000..704b5490c3fb --- /dev/null +++ b/dockers/docker-base-stretch/etc/supervisor/containercfgd.conf @@ -0,0 +1,9 @@ +[program:containercfgd] +command=python3 /usr/local/bin/containercfgd +priority=99 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/dockers/docker-base/Dockerfile.j2 b/dockers/docker-base/Dockerfile.j2 index 15df3fe8a754..681182d64445 100644 --- a/dockers/docker-base/Dockerfile.j2 +++ b/dockers/docker-base/Dockerfile.j2 @@ -49,7 +49,6 @@ RUN apt-get -y install \ rsyslog \ less -COPY ["etc/rsyslog.conf", "/etc/rsyslog.conf"] COPY ["etc/rsyslog.d/*", "/etc/rsyslog.d/"] COPY ["root/.vimrc", "/root/.vimrc"] @@ -65,9 +64,11 @@ RUN pip install wheel RUN pip install supervisor>=3.4.0 RUN mkdir -p /etc/supervisor +RUN mkdir -p /etc/supervisor/conf.d RUN mkdir -p /var/log/supervisor COPY ["etc/supervisor/supervisord.conf", "/etc/supervisor/"] +COPY ["etc/supervisor/containercfgd.conf", "/etc/supervisor/conf.d/"] RUN apt-get -y purge \ exim4 \ diff --git a/dockers/docker-base/etc/rsyslog.conf b/dockers/docker-base/etc/rsyslog.conf deleted file mode 100644 index 4851ac784475..000000000000 --- a/dockers/docker-base/etc/rsyslog.conf +++ /dev/null @@ -1,80 +0,0 @@ -############################################################################### -# Managed by Ansible -# file: ansible/roles/acs/templates/rsyslog.conf.j2 -############################################################################### -# -# /etc/rsyslog.conf Configuration file for rsyslog. -# -# For more information see -# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html - - -################# -#### MODULES #### -################# - -$ModLoad imuxsock # provides support for local system logging - -# -# Set a rate limit on messages from the container -# -$SystemLogRateLimitInterval 300 -$SystemLogRateLimitBurst 20000 - -#$ModLoad imklog # provides kernel logging support -#$ModLoad immark # provides --MARK-- message capability - -# provides UDP syslog reception -#$ModLoad imudp -#$UDPServerRun 514 - -# provides TCP syslog reception -#$ModLoad imtcp -#$InputTCPServerRun 514 - - -########################### -#### GLOBAL DIRECTIVES #### -########################### - -# Set remote syslog server -template (name="ForwardFormatInContainer" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%") -*.* action(type="omfwd" target="127.0.0.1" port="514" protocol="udp" Template="ForwardFormatInContainer") - -# -# Use traditional timestamp format. -# To enable high precision timestamps, comment out the following line. -# -#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat - -# Define a custom template -$template SONiCFileFormat,"%TIMESTAMP%.%timestamp:::date-subseconds% %HOSTNAME% %syslogseverity-text:::uppercase% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" -$ActionFileDefaultTemplate SONiCFileFormat - -# -# Set the default permissions for all log files. -# -$FileOwner root -$FileGroup adm -$FileCreateMode 0640 -$DirCreateMode 0755 -$Umask 0022 - -# -# Where to place spool and state files -# -$WorkDirectory /var/spool/rsyslog - -# -# Include all config files in /etc/rsyslog.d/ -# -$IncludeConfig /etc/rsyslog.d/*.conf - -# -# Suppress duplicate messages and report "message repeated n times" -# -$RepeatedMsgReduction on - -############### -#### RULES #### -############### diff --git a/dockers/docker-base/etc/supervisor/containercfgd.conf b/dockers/docker-base/etc/supervisor/containercfgd.conf new file mode 100644 index 000000000000..704b5490c3fb --- /dev/null +++ b/dockers/docker-base/etc/supervisor/containercfgd.conf @@ -0,0 +1,9 @@ +[program:containercfgd] +command=python3 /usr/local/bin/containercfgd +priority=99 +autostart=false +autorestart=unexpected +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index e1aa3c4bcd7f..8be3235c2be8 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -2,7 +2,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf # Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 index b063016eb68a..c73c6e783e81 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/supervisord.conf.j2 @@ -3,6 +3,15 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:dependent-startup] +command=python3 -m supervisord_dependent_startup +autostart=true +autorestart=unexpected +startretries=0 +exitcodes=0,3 +events=PROCESS_STATE +buffer_size=1024 + [eventlistener:supervisor-proc-exit-listener] command=/usr/bin/supervisor-proc-exit-listener --container-name database events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING @@ -13,14 +22,15 @@ buffer_size=1024 [program:rsyslogd] command=/usr/sbin/rsyslogd -n -iNONE priority=1 -autostart=true +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true {% if INSTANCES %} {% for redis_inst, redis_items in INSTANCES.items() %} -[program: {{ redis_inst }}] +[program:{{ redis_inst }}] {% if redis_items['hostname'] != '127.0.0.1' and redis_inst != 'redis_chassis' %} {%- set LOOPBACK_IP = '127.0.0.1' -%} {%- else -%} @@ -28,17 +38,21 @@ stderr_logfile=syslog {%- endif -%} 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 --bind {{ LOOPBACK_IP }} {{ redis_items['hostname'] }} --port {{ redis_items['port'] }} --unixsocket {{ redis_items['unix_socket_path'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}" priority=2 -autostart=true +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running {% endfor %} {% endif %} [program:flushdb] command=/bin/bash -c "sleep 300 && /usr/local/bin/flush_unused_database" priority=3 -autostart=true +autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/dockers/docker-dhcp-relay/Dockerfile.j2 b/dockers/docker-dhcp-relay/Dockerfile.j2 index 9a5eb23c38a4..592f381f6d13 100644 --- a/dockers/docker-dhcp-relay/Dockerfile.j2 +++ b/dockers/docker-dhcp-relay/Dockerfile.j2 @@ -3,7 +3,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name ARG image_version -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf # Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index c42f001b830f..d15fc1846232 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -5,7 +5,6 @@ ARG docker_container_name ARG frr_user_uid ARG frr_user_gid -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf # Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-iccpd/Dockerfile.j2 b/dockers/docker-iccpd/Dockerfile.j2 index bdb0a9fbf367..42a73b4cd305 100644 --- a/dockers/docker-iccpd/Dockerfile.j2 +++ b/dockers/docker-iccpd/Dockerfile.j2 @@ -2,7 +2,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-lldp/Dockerfile.j2 b/dockers/docker-lldp/Dockerfile.j2 index d7e38e663be8..9bc6418524cb 100644 --- a/dockers/docker-lldp/Dockerfile.j2 +++ b/dockers/docker-lldp/Dockerfile.j2 @@ -3,7 +3,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name ARG image_version -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf # Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-macsec/Dockerfile.j2 b/dockers/docker-macsec/Dockerfile.j2 index 2e7a412466a5..3ec18b13728d 100644 --- a/dockers/docker-macsec/Dockerfile.j2 +++ b/dockers/docker-macsec/Dockerfile.j2 @@ -2,7 +2,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-mux/Dockerfile.j2 b/dockers/docker-mux/Dockerfile.j2 index 06e89c3ecf2d..5908c432e6d7 100755 --- a/dockers/docker-mux/Dockerfile.j2 +++ b/dockers/docker-mux/Dockerfile.j2 @@ -2,7 +2,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-nat/Dockerfile.j2 b/dockers/docker-nat/Dockerfile.j2 index 04b2883551c3..0c0e6089a8d3 100644 --- a/dockers/docker-nat/Dockerfile.j2 +++ b/dockers/docker-nat/Dockerfile.j2 @@ -2,7 +2,6 @@ FROM docker-swss-layer-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf RUN echo diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index a7a314cdc8c9..3554d74912b4 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -2,7 +2,6 @@ FROM docker-swss-layer-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf # Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-pde/Dockerfile.j2 b/dockers/docker-pde/Dockerfile.j2 index 0ddbfd59ce1e..6a0b21154d9c 100644 --- a/dockers/docker-pde/Dockerfile.j2 +++ b/dockers/docker-pde/Dockerfile.j2 @@ -3,7 +3,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name ENV PYTHONPATH=/usr/share/sonic/platform -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf # Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index 51d944d170dd..5470f3038ac4 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -3,7 +3,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name ARG image_version -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf # Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-sflow/Dockerfile.j2 b/dockers/docker-sflow/Dockerfile.j2 index eb97f5708bf7..162c4eee961a 100644 --- a/dockers/docker-sflow/Dockerfile.j2 +++ b/dockers/docker-sflow/Dockerfile.j2 @@ -2,7 +2,6 @@ FROM docker-swss-layer-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-snmp/Dockerfile.j2 b/dockers/docker-snmp/Dockerfile.j2 index 1eb4ec4b7c8b..8465e4fb94fd 100644 --- a/dockers/docker-snmp/Dockerfile.j2 +++ b/dockers/docker-snmp/Dockerfile.j2 @@ -3,7 +3,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name ARG image_version -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf # Enable -O for all Python calls ENV PYTHONOPTIMIZE 1 diff --git a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 index 823a2c7ff4bf..5c36da43286c 100644 --- a/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 +++ b/dockers/docker-sonic-mgmt-framework/Dockerfile.j2 @@ -1,7 +1,6 @@ FROM docker-config-engine-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-sonic-restapi/Dockerfile.j2 b/dockers/docker-sonic-restapi/Dockerfile.j2 index 029f5ec813d7..ca1a80580ba7 100644 --- a/dockers/docker-sonic-restapi/Dockerfile.j2 +++ b/dockers/docker-sonic-restapi/Dockerfile.j2 @@ -2,7 +2,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-sonic-telemetry/Dockerfile.j2 b/dockers/docker-sonic-telemetry/Dockerfile.j2 index e9b01f751b85..64d679d40c46 100644 --- a/dockers/docker-sonic-telemetry/Dockerfile.j2 +++ b/dockers/docker-sonic-telemetry/Dockerfile.j2 @@ -3,7 +3,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name ARG image_version -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/dockers/docker-teamd/Dockerfile.j2 b/dockers/docker-teamd/Dockerfile.j2 index be5e6984dda9..33cb3af92494 100644 --- a/dockers/docker-teamd/Dockerfile.j2 +++ b/dockers/docker-teamd/Dockerfile.j2 @@ -2,7 +2,6 @@ FROM docker-swss-layer-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index ace39df4e546..004fec488922 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -34,16 +34,24 @@ function updateSyslogConf() # Also update the container name if [[ ($NUM_ASIC -gt 1) ]]; then TARGET_IP=$(docker network inspect bridge --format={{ "'{{(index .IPAM.Config 0).Gateway}}'" }}) - CONTAINER_NAME="$DOCKERNAME" - TMP_FILE="/tmp/rsyslog.$CONTAINER_NAME.conf" - {%- if docker_container_name == "database" %} - python -c "import jinja2, os; paths=['/usr/share/sonic/templates']; loader = jinja2.FileSystemLoader(paths); env = jinja2.Environment(loader=loader, trim_blocks=True); template_file='/usr/share/sonic/templates/rsyslog-container.conf.j2'; template = env.get_template(os.path.basename(template_file)); data=template.render({\"target_ip\":\"$TARGET_IP\",\"container_name\":\"$CONTAINER_NAME\"}); print(data)" > $TMP_FILE - {%- else %} - sonic-cfggen -t /usr/share/sonic/templates/rsyslog-container.conf.j2 -a "{\"target_ip\": \"$TARGET_IP\", \"container_name\": \"$CONTAINER_NAME\" }" > $TMP_FILE - {%- endif %} - docker cp $TMP_FILE ${DOCKERNAME}:/etc/rsyslog.conf - rm -rf $TMP_FILE + else + if [ "$CONTAINER_EXISTS" = "yes" ]; then + # database configuration has been synced to /etc/rsyslog.conf + # no need generate it to save boot time + return + fi + TARGET_IP="127.0.0.1" fi + CONTAINER_NAME="$DOCKERNAME" + TMP_FILE="/tmp/rsyslog.$CONTAINER_NAME.conf" + rm -rf $TMP_FILE + {%- if docker_container_name == "database" %} + python -c "import jinja2, os; paths=['/usr/share/sonic/templates']; loader = jinja2.FileSystemLoader(paths); env = jinja2.Environment(loader=loader, trim_blocks=True); template_file='/usr/share/sonic/templates/rsyslog-container.conf.j2'; template = env.get_template(os.path.basename(template_file)); data=template.render({\"target_ip\":\"$TARGET_IP\",\"container_name\":\"$CONTAINER_NAME\"}); print(data)" > $TMP_FILE + {%- else %} + sonic-cfggen -d -t /usr/share/sonic/templates/rsyslog-container.conf.j2 -a "{\"target_ip\": \"$TARGET_IP\", \"container_name\": \"$CONTAINER_NAME\" }" > $TMP_FILE + {%- endif %} + docker cp $TMP_FILE ${DOCKERNAME}:/etc/rsyslog.conf + rm -rf $TMP_FILE } function ebtables_config() { @@ -342,6 +350,7 @@ start() { DOCKERMOUNT=`getMountPoint "$DOCKERCHECK"` {%- endif %} if [ x"$DOCKERMOUNT" == x"$MOUNTPATH" ]; then + CONTAINER_EXISTS="yes" preStartAction {%- if docker_container_name == "database" %} echo "Starting existing ${DOCKERNAME} container" @@ -536,6 +545,7 @@ start() { {%- endif %} $REDIS_MNT \ -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ + -v /usr/share/sonic/templates/rsyslog-container.conf.j2:/usr/share/sonic/templates/rsyslog-container.conf.j2:ro \ {%- if sonic_asic_platform != "mellanox" %} {%- if mount_default_tmpfs|default("n") == "y" %} --tmpfs /tmp \ @@ -547,6 +557,7 @@ start() { --env "NAMESPACE_ID"="$DEV" \ --env "NAMESPACE_PREFIX"="$NAMESPACE_PREFIX" \ --env "NAMESPACE_COUNT"=$NUM_ASIC \ + --env "CONTAINER_NAME"=$DOCKERNAME \ --name=$DOCKERNAME \ {%- if docker_container_name == "gbsyncd" %} -v /var/run/docker-syncd$DEV:/var/run/sswsyncd \ @@ -617,6 +628,7 @@ fi {%- endif %} NAMESPACE_PREFIX="asic" DOCKERNAME=$DOCKERNAME$DEV +CONTAINER_EXISTS="no" if [ "$DEV" ]; then NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 38bd7c2e43a6..4b1baf3cbb7d 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -63,6 +63,7 @@ "has_global_scope": {% if feature + '.service' in installer_services.split(' ') %}true{% else %}false{% endif %}, "has_per_asic_scope": {% if feature + '@.service' in installer_services.split(' ') %}true{% else %}false{% endif %}, "auto_restart": "{{autorestart}}", + "support_syslog_rate_limit" : "true", {# Set check_up_status to true here when app readiness will be marked in state db #} {# For now, to support the infrastrucure, setting the check_up_status to false for bgp,swss,pmon #} {# Once apps like bgp,synd supports app readiness, then bgp,syncd can set check_up_status to true #} @@ -99,6 +100,20 @@ "rate_limit_interval" : "600", "available_mem_threshold": "10.0" }{%if not loop.last %},{% endif -%} +{% endfor %} + }, + "SYSLOG_CONFIG": { + "GLOBAL": { + "rate_limit_interval" : "0", + "rate_limit_burst" : "0" + } + }, + "SYSLOG_CONFIG_FEATURE": { +{%- for feature, _, _, _ in features %} + "{{feature}}": { + "rate_limit_interval" : "300", + "rate_limit_burst": "20000" + }{%if not loop.last %},{% endif -%} {% endfor %} }, "PASSW_HARDENING": { diff --git a/files/build_templates/manifest.json.j2 b/files/build_templates/manifest.json.j2 index dff92ac21634..3deac2285e9c 100644 --- a/files/build_templates/manifest.json.j2 +++ b/files/build_templates/manifest.json.j2 @@ -28,6 +28,9 @@ "fast-shutdown": { "after": {{ fast_shutdown_after.split()|json if fast_shutdown_after is defined else [] }}, "before": {{ fast_shutdown_before.split()|json if fast_shutdown_before is defined else [] }} + }, + "syslog": { + "support-rate-limit": {{ support_rate_limit if support_rate_limit else 'true' }} } }, "container": { diff --git a/files/image_config/rsyslog/rsyslog-container.conf.j2 b/files/image_config/rsyslog/rsyslog-container.conf.j2 index d17fbb6767ba..7fe659d3815d 100644 --- a/files/image_config/rsyslog/rsyslog-container.conf.j2 +++ b/files/image_config/rsyslog/rsyslog-container.conf.j2 @@ -14,8 +14,24 @@ $ModLoad imuxsock # provides support for local system logging # # Set a rate limit on messages from the container # -$SystemLogRateLimitInterval 300 -$SystemLogRateLimitBurst 20000 + +{% if SYSLOG_CONFIG_FEATURE is defined %} +{% if container_name in SYSLOG_CONFIG_FEATURE %} +{% if 'rate_limit_interval' in SYSLOG_CONFIG_FEATURE[container_name]%} +{% set rate_limit_interval = SYSLOG_CONFIG_FEATURE[container_name]['rate_limit_interval'] %} +{% endif %} +{% if 'rate_limit_burst' in SYSLOG_CONFIG_FEATURE[container_name]%} +{% set rate_limit_burst = SYSLOG_CONFIG_FEATURE[container_name]['rate_limit_burst'] %} +{% endif %} +{% endif %} +{% endif %} + +{% if rate_limit_interval is defined %} +$SystemLogRateLimitInterval {{ rate_limit_interval }} +{% endif %} +{% if rate_limit_burst is defined %} +$SystemLogRateLimitBurst {{ rate_limit_burst }} +{% endif %} #$ModLoad imklog # provides kernel logging support #$ModLoad immark # provides --MARK-- message capability diff --git a/files/image_config/rsyslog/rsyslog.conf.j2 b/files/image_config/rsyslog/rsyslog.conf.j2 index 5db3ec86b795..d20fb5d00aec 100644 --- a/files/image_config/rsyslog/rsyslog.conf.j2 +++ b/files/image_config/rsyslog/rsyslog.conf.j2 @@ -14,6 +14,25 @@ ################# $ModLoad imuxsock # provides support for local system logging + +{% if SYSLOG_CONFIG is defined %} +{% if 'GLOBAL' in SYSLOG_CONFIG %} +{% if 'rate_limit_interval' in SYSLOG_CONFIG['GLOBAL']%} +{% set rate_limit_interval = SYSLOG_CONFIG['GLOBAL']['rate_limit_interval'] %} +{% endif %} +{% if 'rate_limit_burst' in SYSLOG_CONFIG['GLOBAL']%} +{% set rate_limit_burst = SYSLOG_CONFIG['GLOBAL']['rate_limit_burst'] %} +{% endif %} +{% endif %} +{% endif %} + +{% if rate_limit_interval is defined %} +$SystemLogRateLimitInterval {{ rate_limit_interval }} +{% endif %} +{% if rate_limit_burst is defined %} +$SystemLogRateLimitBurst {{ rate_limit_burst }} +{% endif %} + $ModLoad imklog # provides kernel logging support #$ModLoad immark # provides --MARK-- message capability diff --git a/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 b/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 index 92914d7abbf8..291369ca1568 100644 --- a/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-saiserver-brcm/Dockerfile.j2 @@ -2,7 +2,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/broadcom/docker-syncd-brcm-dnx/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm-dnx/Dockerfile.j2 index 230c2628f41d..8bf6a4e50289 100755 --- a/platform/broadcom/docker-syncd-brcm-dnx/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm-dnx/Dockerfile.j2 @@ -3,8 +3,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf - ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 index 6900e7c933b5..4037ddc6af1a 100755 --- a/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 +++ b/platform/broadcom/docker-syncd-brcm/Dockerfile.j2 @@ -3,8 +3,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf - ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 index f60fa0fe5797..5932da253208 100755 --- a/platform/cavium/docker-syncd-cavm/Dockerfile.j2 +++ b/platform/cavium/docker-syncd-cavm/Dockerfile.j2 @@ -2,8 +2,6 @@ FROM docker-config-engine-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf - ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/centec-arm64/docker-saiserver-centec/Dockerfile.j2 b/platform/centec-arm64/docker-saiserver-centec/Dockerfile.j2 index 33941235bf90..2e0e8ecca836 100644 --- a/platform/centec-arm64/docker-saiserver-centec/Dockerfile.j2 +++ b/platform/centec-arm64/docker-saiserver-centec/Dockerfile.j2 @@ -1,7 +1,6 @@ FROM docker-config-engine-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 b/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 index 046de960cd20..175d18505d67 100755 --- a/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 +++ b/platform/centec-arm64/docker-syncd-centec/Dockerfile.j2 @@ -2,8 +2,6 @@ FROM docker-config-engine-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf - ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/centec/docker-saiserver-centec/Dockerfile.j2 b/platform/centec/docker-saiserver-centec/Dockerfile.j2 index 33941235bf90..2e0e8ecca836 100644 --- a/platform/centec/docker-saiserver-centec/Dockerfile.j2 +++ b/platform/centec/docker-saiserver-centec/Dockerfile.j2 @@ -1,7 +1,6 @@ FROM docker-config-engine-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/centec/docker-syncd-centec/Dockerfile.j2 b/platform/centec/docker-syncd-centec/Dockerfile.j2 index c1d122eeb9a0..9993539887a5 100755 --- a/platform/centec/docker-syncd-centec/Dockerfile.j2 +++ b/platform/centec/docker-syncd-centec/Dockerfile.j2 @@ -2,8 +2,6 @@ FROM docker-config-engine-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf - ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/components/docker-gbsyncd-broncos/Dockerfile.j2 b/platform/components/docker-gbsyncd-broncos/Dockerfile.j2 index 154c7735ce97..c2069f7e2c83 100644 --- a/platform/components/docker-gbsyncd-broncos/Dockerfile.j2 +++ b/platform/components/docker-gbsyncd-broncos/Dockerfile.j2 @@ -1,7 +1,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/components/docker-gbsyncd-credo/Dockerfile.j2 b/platform/components/docker-gbsyncd-credo/Dockerfile.j2 index 3010dc7fdad5..24fef740dc34 100644 --- a/platform/components/docker-gbsyncd-credo/Dockerfile.j2 +++ b/platform/components/docker-gbsyncd-credo/Dockerfile.j2 @@ -1,7 +1,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/innovium/docker-syncd-invm/Dockerfile.j2 b/platform/innovium/docker-syncd-invm/Dockerfile.j2 index ef0c3d57e025..0811d044b02b 100755 --- a/platform/innovium/docker-syncd-invm/Dockerfile.j2 +++ b/platform/innovium/docker-syncd-invm/Dockerfile.j2 @@ -1,7 +1,6 @@ FROM docker-config-engine-stretch-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 index 7ec04c49fc4b..d07c2523182c 100755 --- a/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2 @@ -3,8 +3,6 @@ FROM docker-config-engine-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf - ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 index 7ec04c49fc4b..d07c2523182c 100755 --- a/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2 @@ -3,8 +3,6 @@ FROM docker-config-engine-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf - ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 index cb2f7eadb911..4de6df313834 100755 --- a/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 +++ b/platform/marvell/docker-syncd-mrvl/Dockerfile.j2 @@ -3,8 +3,6 @@ FROM docker-config-engine-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf - ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 b/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 index 0f6745d580ab..40cf0634bbb7 100644 --- a/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-saiserver-mlnx/Dockerfile.j2 @@ -18,7 +18,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 index cd3f74bcfaf3..35e94f1c9c72 100755 --- a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 @@ -19,8 +19,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf - RUN mkdir -p /var/run/sx_sdk ## Make apt-get non-interactive diff --git a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 index 5077db796628..d26abf76a051 100755 --- a/platform/nephos/docker-syncd-nephos/Dockerfile.j2 +++ b/platform/nephos/docker-syncd-nephos/Dockerfile.j2 @@ -2,8 +2,6 @@ FROM docker-config-engine-stretch-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf - ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/p4/docker-sonic-p4/Dockerfile.j2 b/platform/p4/docker-sonic-p4/Dockerfile.j2 index e77781223dc1..80503b910e84 100644 --- a/platform/p4/docker-sonic-p4/Dockerfile.j2 +++ b/platform/p4/docker-sonic-p4/Dockerfile.j2 @@ -1,7 +1,6 @@ FROM docker-config-engine-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 b/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 index 4dd9abf49ee7..7e5219f5512e 100644 --- a/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 +++ b/platform/vs/docker-gbsyncd-vs/Dockerfile.j2 @@ -2,8 +2,6 @@ FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf - ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 7585b7f6f6e3..26840efdc3c9 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -1,7 +1,6 @@ FROM docker-config-engine-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/platform/vs/docker-syncd-vs/Dockerfile.j2 b/platform/vs/docker-syncd-vs/Dockerfile.j2 index dd6bc2d0f71e..27506903b7f4 100644 --- a/platform/vs/docker-syncd-vs/Dockerfile.j2 +++ b/platform/vs/docker-syncd-vs/Dockerfile.j2 @@ -2,8 +2,6 @@ FROM docker-config-engine-buster-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} ARG docker_container_name -RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf - ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive diff --git a/rules/docker-config-engine-bullseye.mk b/rules/docker-config-engine-bullseye.mk index ea0ae43b54b9..9548391a6917 100644 --- a/rules/docker-config-engine-bullseye.mk +++ b/rules/docker-config-engine-bullseye.mk @@ -11,8 +11,9 @@ $(DOCKER_CONFIG_ENGINE_BULLSEYE)_DEPENDS += $(LIBSWSSCOMMON) \ $(SONIC_DB_CLI) \ $(SONIC_EVENTD) $(DOCKER_CONFIG_ENGINE_BULLSEYE)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) \ - $(SONIC_YANG_MGMT_PY3) \ - $(SONIC_YANG_MODELS_PY3) + $(SONIC_YANG_MGMT_PY3) \ + $(SONIC_YANG_MODELS_PY3) \ + $(SONIC_CONTAINERCFGD) $(DOCKER_CONFIG_ENGINE_BULLSEYE)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY3) $(DOCKER_CONFIG_ENGINE_BULLSEYE)_LOAD_DOCKERS += $(DOCKER_BASE_BULLSEYE) $(DOCKER_CONFIG_ENGINE_BULLSEYE)_FILES += $(SWSS_VARS_TEMPLATE) diff --git a/rules/docker-config-engine-buster.mk b/rules/docker-config-engine-buster.mk index 38a94bae4c1d..cd6d6f43b46d 100644 --- a/rules/docker-config-engine-buster.mk +++ b/rules/docker-config-engine-buster.mk @@ -11,7 +11,8 @@ $(DOCKER_CONFIG_ENGINE_BUSTER)_DEPENDS += $(LIBSWSSCOMMON) \ $(SONIC_DB_CLI) $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_PY_COMMON_PY3) \ $(SONIC_YANG_MGMT_PY3) \ - $(SONIC_YANG_MODELS_PY3) + $(SONIC_YANG_MODELS_PY3) \ + $(SONIC_CONTAINERCFGD) $(DOCKER_CONFIG_ENGINE_BUSTER)_PYTHON_WHEELS += $(SONIC_CONFIG_ENGINE_PY3) $(DOCKER_CONFIG_ENGINE_BUSTER)_LOAD_DOCKERS += $(DOCKER_BASE_BUSTER) $(DOCKER_CONFIG_ENGINE_BUSTER)_FILES += $(SWSS_VARS_TEMPLATE) diff --git a/rules/functions b/rules/functions index 62b3c8a98375..ab0096d6ac5a 100644 --- a/rules/functions +++ b/rules/functions @@ -198,6 +198,7 @@ define generate_manifest $(eval export config_cli_plugin=$($(1).gz_CLI_CONFIG_PLUGIN)) $(eval export show_cli_plugin=$($(1).gz_CLI_SHOW_PLUGIN)) $(eval export clear_cli_plugin=$($(1).gz_CLI_CLEAR_PLUGIN)) + $(eval export support_rate_limit=$($(1).gz_SUPPORT_RATE_LIMIT)) j2 --customize scripts/j2cli/json_filter.py files/build_templates/manifest.json.j2 > $($(1).gz_PATH)/manifest.common.json if [ -f $($*.gz_PATH)/manifest.part.json.j2 ]; then j2 --customize scripts/j2cli/json_filter.py $($(1).gz_PATH)/manifest.part.json.j2 > $($(1).gz_PATH)/manifest.part.json diff --git a/rules/sonic-containercfgd.mk b/rules/sonic-containercfgd.mk new file mode 100644 index 000000000000..e59f3bbd0b45 --- /dev/null +++ b/rules/sonic-containercfgd.mk @@ -0,0 +1,8 @@ +# sonic-bgpcfgd package + +SONIC_CONTAINERCFGD = sonic_containercfgd-1.0-py3-none-any.whl +$(SONIC_CONTAINERCFGD)_SRC_PATH = $(SRC_PATH)/sonic-containercfgd +$(SONIC_CONTAINERCFGD)_DEPENDS += $(SONIC_PY_COMMON_PY3) +$(SONIC_CONTAINERCFGD)_DEBS_DEPENDS = $(LIBSWSSCOMMON) $(PYTHON3_SWSSCOMMON) +$(SONIC_CONTAINERCFGD)_PYTHON_VERSION = 3 +SONIC_PYTHON_WHEELS += $(SONIC_CONTAINERCFGD) diff --git a/rules/sonic_containercfgd.dep b/rules/sonic_containercfgd.dep new file mode 100644 index 000000000000..439aef063428 --- /dev/null +++ b/rules/sonic_containercfgd.dep @@ -0,0 +1,10 @@ +SPATH := $($(SONIC_CONTAINERCFGD)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-containercfgd.mk rules/sonic-containercfgd.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SONIC_CONTAINERCFGD)_CACHE_MODE := GIT_CONTENT_SHA +$(SONIC_CONTAINERCFGD)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SONIC_CONTAINERCFGD)_DEP_FILES := $(DEP_FILES) +$(SONIC_CONTAINERCFGD)_SMDEP_FILES := $(SMDEP_FILES) +$(SONIC_CONTAINERCFGD)_SMDEP_PATHS := $(SPATH) diff --git a/src/sonic-containercfgd/.gitignore b/src/sonic-containercfgd/.gitignore new file mode 100644 index 000000000000..5ae7a596bfb6 --- /dev/null +++ b/src/sonic-containercfgd/.gitignore @@ -0,0 +1,13 @@ +# Compiled Python files +*.pyc + +# Generated by packaging +*.egg-info/ +.eggs/ +build/ +dist/ + +# Unit test coverage +.coverage +coverage.xml +htmlcov/ diff --git a/src/sonic-containercfgd/containercfgd/__init__.py b/src/sonic-containercfgd/containercfgd/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-containercfgd/containercfgd/containercfgd.py b/src/sonic-containercfgd/containercfgd/containercfgd.py new file mode 100644 index 000000000000..23afe3d6b049 --- /dev/null +++ b/src/sonic-containercfgd/containercfgd/containercfgd.py @@ -0,0 +1,190 @@ +import os +import re +import signal +import subprocess +import sys + +from sonic_py_common import daemon_base, logger +from swsscommon.swsscommon import ConfigDBConnector, RestartWaiter + +SYSLOG_IDENTIFIER = "containercfgd" +logger = logger.Logger(SYSLOG_IDENTIFIER) + +# Table names +FEATURE_TABLE = 'FEATURE' +SYSLOG_CONFIG_FEATURE_TABLE = 'SYSLOG_CONFIG_FEATURE' + +# Table field names +SYSLOG_RATE_LIMIT_INTERVAL = 'rate_limit_interval' +SYSLOG_RATE_LIMIT_BURST = 'rate_limit_burst' + +# Container name +container_name = None + + +def run_command(command): + """ + Utility function to run an shell command and return the output. + :param command: Shell command string. + :return: Output of the shell command. + """ + process = subprocess.Popen(command, shell=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + return process.communicate()[0].strip() + + +class ContainerConfigDaemon(daemon_base.DaemonBase): + handlers = {} + + def __init__(self): + super(ContainerConfigDaemon, self).__init__(SYSLOG_IDENTIFIER) + + def run(self): + """Register config handlers and listen to CONFIG DB changes + """ + config_db = ConfigDBConnector() + config_db.connect(wait_for_init=True, retry_on=True) + for table_name, handler in self.handlers.items(): + config_db.subscribe(table_name, handler.handle_config) + config_db.listen(init_data_handler=self.load) + + def load(self, init_data): + """Handle initial data in CONFIG DB + + Args: + init_data (dict): Initial data when first time connecting to CONFIG DB. {: {: }} + """ + for handler in self.handlers.values(): + handler.handle_init_data(init_data) + + @classmethod + def register_handler(cls, table_name, object_type): + """Register CONFIG DB handler + + Args: + table_name (str): CONFIG DB table name + object_type (class): Class of CONFIG DB handler + """ + cls.handlers[table_name] = object_type() + + def signal_handler(self, sig, frame): + if sig == signal.SIGHUP: + self.log_info("ContainerCfgd: Caught SIGHUP - ignoring...") + elif sig == signal.SIGINT: + self.log_info("ContainerCfgd: Caught SIGINT - exiting...") + sys.exit(128 + sig) + elif sig == signal.SIGTERM: + self.log_info("ContainerCfgd: Caught SIGTERM - exiting...") + sys.exit(128 + sig) + else: + self.log_warning("ContainerCfgd: Caught unhandled signal '{}'".format(sig)) + + +def config_handler(table_name): + """Decorator to register CONFIG DB handler + + Args: + table_name (str): CONFIG DB table name + """ + def wrapper(object_type): + ContainerConfigDaemon.register_handler(table_name, object_type) + return object_type + return wrapper + + +@config_handler(SYSLOG_CONFIG_FEATURE_TABLE) +class SyslogHandler: + # syslog conf file path in docker + SYSLOG_CONF_PATH = '/etc/rsyslog.conf' + # temporary syslog conf file path in docker + TMP_SYSLOG_CONF_PATH = '/tmp/rsyslog.conf' + + # Regular expressions to extract value from rsyslog.conf + INTERVAL_PATTERN = '.*SystemLogRateLimitInterval\s+(\d+).*' + BURST_PATTERN = '.*SystemLogRateLimitBurst\s+(\d+).*' + TARGET_IP_PATTERN = '.*target="(.*?)".*' + + def handle_config(self, table, key, data): + """Handle CONFIG DB change. Callback by ConfigDBConnector. + + Args: + table (str): CONFIG DB table name + key (str): Key of the changed entry + data (dict): Data of the entry: {: } + """ + try: + if key != container_name: + return + self.update_syslog_config(data) + except Exception as e: + logger.log_error('Failed to config syslog for container {} with data {} - {}'.format(key, data, e)) + + def handle_init_data(self, init_data): + """Handle initial data in CONFIG DB. Callback by ConfigDBConnector. + + Args: + init_data (dict): Initial data when first time connecting to CONFIG DB. {: {: }} + """ + if SYSLOG_CONFIG_FEATURE_TABLE in init_data: + if container_name in init_data[SYSLOG_CONFIG_FEATURE_TABLE]: + self.update_syslog_config(init_data[SYSLOG_CONFIG_FEATURE_TABLE][container_name]) + + def update_syslog_config(self, data): + """Parse existing syslog conf and apply new syslog conf. + + Args: + data (dict): Data of the entry: {: } + """ + cur_interval, cur_burst, target_ip = self.parse_syslog_conf() + new_interval = '0' if not data else data.get(SYSLOG_RATE_LIMIT_INTERVAL, '0') + new_burst = '0' if not data else data.get(SYSLOG_RATE_LIMIT_BURST, '0') + + if new_interval == cur_interval and new_burst == cur_burst: + return + + logger.log_notice(f'Configure syslog rate limit interval={new_interval}, burst={new_burst}') + + if os.path.exists(self.TMP_SYSLOG_CONF_PATH): + os.remove(self.TMP_SYSLOG_CONF_PATH) + run_command('sonic-cfggen -d -t /usr/share/sonic/templates/rsyslog-container.conf.j2 -a "{{\\"target_ip\\": \\"{}\\", \\"container_name\\": \\"{}\\" }}" > {}'.format(target_ip, container_name, self.TMP_SYSLOG_CONF_PATH)) + run_command('cp {} {}'.format(self.TMP_SYSLOG_CONF_PATH, self.SYSLOG_CONF_PATH)) + run_command("supervisorctl restart rsyslogd") + + def parse_syslog_conf(self): + """Passe existing syslog conf and extract config values + + Returns: + tuple: interval,burst,target_ip + """ + interval = '0' + burst = '0' + target_ip = None + + with open(self.SYSLOG_CONF_PATH, 'r') as f: + content = f.read() + pattern = re.compile(self.INTERVAL_PATTERN) + for match in pattern.finditer(content): + interval = match.group(1) + break + + pattern = re.compile(self.BURST_PATTERN) + for match in pattern.finditer(content): + burst = match.group(1) + break + + pattern = re.compile(self.TARGET_IP_PATTERN) + for match in pattern.finditer(content): + target_ip = match.group(1) + break + return interval, burst, target_ip + + +def main(): + RestartWaiter.waitAdvancedBootDone() + global container_name + container_name = os.environ['CONTAINER_NAME'] + daemon = ContainerConfigDaemon() + daemon.run() + + +if __name__ == '__main__': + main() diff --git a/src/sonic-containercfgd/pytest.ini b/src/sonic-containercfgd/pytest.ini new file mode 100644 index 000000000000..2fc0931f27a7 --- /dev/null +++ b/src/sonic-containercfgd/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +addopts = --cov=containercfgd --cov-report html --cov-report term --cov-report xml diff --git a/src/sonic-containercfgd/setup.cfg b/src/sonic-containercfgd/setup.cfg new file mode 100644 index 000000000000..b7e478982ccf --- /dev/null +++ b/src/sonic-containercfgd/setup.cfg @@ -0,0 +1,2 @@ +[aliases] +test=pytest diff --git a/src/sonic-containercfgd/setup.py b/src/sonic-containercfgd/setup.py new file mode 100644 index 000000000000..9f60c58135b4 --- /dev/null +++ b/src/sonic-containercfgd/setup.py @@ -0,0 +1,48 @@ +from setuptools import setup + +dependencies = [ + 'sonic_py_common', +] + +setup( + name='sonic-containercfgd', + version='1.0', + description='SONiC container config daemon package', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Junchao Chen', + maintainer_email='junchaow@nvidia.com', + install_requires=dependencies, + entry_points={ + 'console_scripts': [ + 'containercfgd = containercfgd.containercfgd:main', + ] + }, + packages=[ + 'containercfgd', + 'tests' + ], + setup_requires=[ + 'pytest-runner' + ], + tests_require=[ + 'pytest', + 'mock>=2.0.0' + ], + classifiers=[ + 'Development Status :: 4 - Beta', + 'Environment :: No Input/Output (Daemon)', + '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 :: Hardware', + ], + keywords='SONiC sonic container config daemon', + test_suite='setup.get_test_suite' +) diff --git a/src/sonic-containercfgd/tests/conftest.py b/src/sonic-containercfgd/tests/conftest.py new file mode 100644 index 000000000000..e866d85125a7 --- /dev/null +++ b/src/sonic-containercfgd/tests/conftest.py @@ -0,0 +1,5 @@ +import os + + +def init_env(): + os.environ["CONTAINER_NAME"] = "2" \ No newline at end of file diff --git a/src/sonic-containercfgd/tests/mock_empty_rsyslog.conf b/src/sonic-containercfgd/tests/mock_empty_rsyslog.conf new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/sonic-containercfgd/tests/mock_rsyslog.conf b/src/sonic-containercfgd/tests/mock_rsyslog.conf new file mode 100644 index 000000000000..68e917b9344c --- /dev/null +++ b/src/sonic-containercfgd/tests/mock_rsyslog.conf @@ -0,0 +1,29 @@ +$ModLoad imuxsock # provides support for local system logging + +# +# Set a rate limit on messages from the container +# + + +$SystemLogRateLimitInterval 50 +$SystemLogRateLimitBurst 10002 + +#$ModLoad imklog # provides kernel logging support +#$ModLoad immark # provides --MARK-- message capability + +# provides UDP syslog reception +#$ModLoad imudp +#$UDPServerRun 514 + +# provides TCP syslog reception +#$ModLoad imtcp +#$InputTCPServerRun 514 + + +########################### +#### GLOBAL DIRECTIVES #### +########################### + +# Set remote syslog server +template (name="ForwardFormatInContainer" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% pmon#%syslogtag%%msg:::sp-if-no-1st-sp%%msg%") +*.* action(type="omfwd" target="127.0.0.1" port="514" protocol="udp" Template="ForwardFormatInContainer") diff --git a/src/sonic-containercfgd/tests/test_config_daemon.py b/src/sonic-containercfgd/tests/test_config_daemon.py new file mode 100644 index 000000000000..39522d56069e --- /dev/null +++ b/src/sonic-containercfgd/tests/test_config_daemon.py @@ -0,0 +1,54 @@ +import os +import sys +from unittest import mock + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +sys.path.insert(0, modules_path) + +from containercfgd import containercfgd + + +@containercfgd.config_handler('MockTable') +class MockHandler: + def handle_init_data(self, init_data): + pass + + def handle_config(self, table, key, data): + pass + + +def test_handler_register(): + assert 'MockTable' in containercfgd.ContainerConfigDaemon.handlers + assert isinstance(containercfgd.ContainerConfigDaemon.handlers['MockTable'], MockHandler) + + +def test_load(): + mock_handler_cls = mock.MagicMock() + mock_handler_instance = mock.MagicMock() + mock_handler_instance.handle_init_data = mock.MagicMock() + mock_handler_cls.return_value = mock_handler_instance + + containercfgd.ContainerConfigDaemon.register_handler('LoadMock', mock_handler_cls) + daemon = containercfgd.ContainerConfigDaemon() + daemon.load({}) + mock_handler_instance.handle_init_data.assert_called_once + containercfgd.ContainerConfigDaemon.handlers.pop('LoadMock') + + +@mock.patch('containercfgd.containercfgd.ConfigDBConnector') +def test_run(mock_connector): + mock_db = mock.MagicMock() + mock_db.connect = mock.MagicMock() + mock_db.subscribe = mock.MagicMock() + mock_db.listen = mock.MagicMock() + mock_connector.return_value = mock_db + + daemon = containercfgd.ContainerConfigDaemon() + daemon.run() + mock_db.connect.assert_called_once() + expected = [] + for table_name, handler in containercfgd.ContainerConfigDaemon.handlers.items(): + expected.append(mock.call(table_name, handler.handle_config)) + mock_db.subscribe.assert_has_calls(expected, any_order=True) + mock_db.listen.assert_called_once() diff --git a/src/sonic-containercfgd/tests/test_syslog_config.py b/src/sonic-containercfgd/tests/test_syslog_config.py new file mode 100644 index 000000000000..deb465791d88 --- /dev/null +++ b/src/sonic-containercfgd/tests/test_syslog_config.py @@ -0,0 +1,80 @@ +import os +import sys +from unittest import mock + +test_path = os.path.dirname(os.path.abspath(__file__)) +modules_path = os.path.dirname(test_path) +sys.path.insert(0, modules_path) + +from containercfgd import containercfgd + +containercfgd.container_name = 'swss' + + +def test_handle_config(): + handler = containercfgd.SyslogHandler() + handler.update_syslog_config = mock.MagicMock() + + handler.handle_config(containercfgd.SYSLOG_CONFIG_FEATURE_TABLE, + 'bgp', + None) + handler.update_syslog_config.assert_not_called() + + handler.handle_config(containercfgd.SYSLOG_CONFIG_FEATURE_TABLE, + 'swss', + None) + handler.update_syslog_config.assert_called_once() + + handler.update_syslog_config.side_effect = Exception('') + handler.handle_config(containercfgd.SYSLOG_CONFIG_FEATURE_TABLE, + 'swss', + None) + + +def test_handle_init_data(): + handler = containercfgd.SyslogHandler() + handler.update_syslog_config = mock.MagicMock() + + init_data = {} + handler.handle_init_data(init_data) + handler.update_syslog_config.assert_not_called() + + init_data = {containercfgd.SYSLOG_CONFIG_FEATURE_TABLE: {}} + handler.handle_init_data(init_data) + handler.update_syslog_config.assert_not_called() + + init_data = {containercfgd.SYSLOG_CONFIG_FEATURE_TABLE: {'swss': {}}} + handler.handle_init_data(init_data) + handler.update_syslog_config.assert_called_once() + + +@mock.patch('containercfgd.containercfgd.run_command') +def test_update_syslog_config(mock_run_cmd): + handler = containercfgd.SyslogHandler() + handler.parse_syslog_conf = mock.MagicMock(return_value=('100', '200', '127.0.0.1')) + + data = {containercfgd.SYSLOG_RATE_LIMIT_INTERVAL: '100', + containercfgd.SYSLOG_RATE_LIMIT_BURST: '200'} + handler.update_syslog_config(data) + mock_run_cmd.assert_not_called() + + data = {containercfgd.SYSLOG_RATE_LIMIT_INTERVAL: '200', + containercfgd.SYSLOG_RATE_LIMIT_BURST: '200'} + + handler.update_syslog_config(data) + mock_run_cmd.assert_called() + + +def test_parse_syslog_conf(): + handler = containercfgd.SyslogHandler() + handler.SYSLOG_CONF_PATH = os.path.join(test_path, 'mock_rsyslog.conf') + interval, burst, target_ip = handler.parse_syslog_conf() + assert interval == '50' + assert burst == '10002' + assert target_ip == '127.0.0.1' + + handler.SYSLOG_CONF_PATH = os.path.join(test_path, 'mock_empty_rsyslog.conf') + interval, burst, target_ip = handler.parse_syslog_conf() + assert interval is '0' + assert burst is '0' + assert target_ip is None diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 9dec93b52037..63097153282d 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -472,6 +472,22 @@ "vrf": "Vrf_blue" } }, + "SYSLOG_CONFIG" : { + "GLOBAL": { + "rate_limit_interval": "5", + "rate_limit_burst": "100" + } + }, + "SYSLOG_CONFIG_FEATURE" : { + "swss": { + "rate_limit_interval": "5", + "rate_limit_burst": "100" + }, + "bgp": { + "rate_limit_interval": "10", + "rate_limit_burst": "200" + } + }, "CABLE_LENGTH": { "AZURE": { "Ethernet0": "5m", @@ -1514,7 +1530,9 @@ "high_mem_alert": "disabled", "state": "enabled", "set_owner": "local", - "check_up_status": "False" + "check_up_status": "False", + "support_syslog_rate_limit": "True", + "has_customized_syslog_rate_limit": "False" }, "database": { "auto_restart": "always_enabled", @@ -1524,7 +1542,9 @@ "high_mem_alert": "disabled", "state": "always_enabled", "set_owner": "local", - "check_up_status": "false" + "check_up_status": "false", + "support_syslog_rate_limit": "True", + "has_customized_syslog_rate_limit": "False" }, "snmp": { "auto_restart": "enabled", @@ -1534,7 +1554,9 @@ "high_mem_alert": "disabled", "state": "enabled", "set_owner": "kube", - "check_up_status": "true" + "check_up_status": "true", + "support_syslog_rate_limit": "True", + "has_customized_syslog_rate_limit": "False" }, "swss": { "auto_restart": "enabled", @@ -1544,7 +1566,9 @@ "high_mem_alert": "disabled", "state": "enabled", "set_owner": "local", - "check_up_status": "false" + "check_up_status": "false", + "support_syslog_rate_limit": "True", + "has_customized_syslog_rate_limit": "False" }, "syncd": { "auto_restart": "enabled", @@ -1554,7 +1578,9 @@ "high_mem_alert": "disabled", "state": "enabled", "set_owner": "local", - "check_up_status": "false" + "check_up_status": "false", + "support_syslog_rate_limit": "True", + "has_customized_syslog_rate_limit": "False" }, "lldp": { "auto_restart": "enabled", @@ -1564,7 +1590,9 @@ "high_mem_alert": "disabled", "state": "enabled", "set_owner": "kube", - "check_up_status": "false" + "check_up_status": "false", + "support_syslog_rate_limit": "True", + "has_customized_syslog_rate_limit": "False" }, "dhcp_relay": { "auto_restart": "enabled", @@ -1574,7 +1602,9 @@ "high_mem_alert": "disabled", "state": "{% if not (DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined and DEVICE_METADATA['localhost']['type'] != 'ToRRouter') %}enabled{% else %}disabled{% endif %}", "set_owner": "kube", - "check_up_status": "true" + "check_up_status": "true", + "support_syslog_rate_limit": "True", + "has_customized_syslog_rate_limit": "False" } }, "DHCP_RELAY": { diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/syslog.json b/src/sonic-yang-models/tests/yang_model_tests/tests/syslog.json index 8b110fbd8af8..da277f113486 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests/syslog.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/syslog.json @@ -36,5 +36,31 @@ "SYSLOG_SERVER_INVALID_IPV6_ADDR_TEST": { "desc": "Load syslog server table with invalid ipv6 address as syslog server.", "eStrKey": "InvalidValue" + }, + "SYSLOG_CONFIG_VALID": { + "desc": "Configure SYSLOG_CONFIG." + }, + "SYSLOG_CONFIG_INVALID_INTERVAL": { + "desc": "Configure invalid rate limit interval in SYSLOG_CONFIG.", + "eStrKey": "InvalidValue" + }, + "SYSLOG_CONFIG_INVALID_BURST": { + "desc": "Configure invalid rate limit burst in SYSLOG_CONFIG.", + "eStrKey": "InvalidValue" + }, + "SYSLOG_CONFIG_FEATURE_VALID": { + "desc": "Configure SYSLOG_CONFIG_FEATURE." + }, + "SYSLOG_CONFIG_FEATURE_INVALID_SERVICE_NAME": { + "desc": "Configure invalid service in SYSLOG_CONFIG_FEATURE.", + "eStrKey": "LeafRef" + }, + "SYSLOG_CONFIG_FEATURE_INVALID_INTERVAL": { + "desc": "Configure invalid rate_limit_interval in SYSLOG_CONFIG_FEATURE.", + "eStrKey": "InvalidValue" + }, + "SYSLOG_CONFIG_FEATURE_INVALID_BURST": { + "desc": "Configure invalid rate_limit_burst in SYSLOG_CONFIG_FEATURE.", + "eStrKey": "InvalidValue" } } diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/feature.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/feature.json index 08c974d8e45f..f2518a81b0d8 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/feature.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/feature.json @@ -11,7 +11,9 @@ "has_global_scope": "True", "has_per_asic_scope": "True", "set_owner": "local", - "check_up_status": "False" + "check_up_status": "False", + "support_syslog_rate_limit": "true", + "has_customized_syslog_rate_limit": "false" }, { "name": "swss", @@ -21,7 +23,9 @@ "has_global_scope": "false", "has_per_asic_scope": "true", "set_owner": "local", - "check_up_status": "false" + "check_up_status": "false", + "support_syslog_rate_limit": "true", + "has_customized_syslog_rate_limit": "false" }, { "name": "syncd", @@ -31,7 +35,9 @@ "has_global_scope": "false", "has_per_asic_scope": "true", "set_owner": "local", - "check_up_status": "false" + "check_up_status": "false", + "support_syslog_rate_limit": "true", + "has_customized_syslog_rate_limit": "false" }, { "name": "snmp", @@ -41,7 +47,9 @@ "has_global_scope": "true", "has_per_asic_scope": "false", "set_owner": "kube", - "check_up_status": "false" + "check_up_status": "false", + "support_syslog_rate_limit": "true", + "has_customized_syslog_rate_limit": "false" }, { "name": "lldp", @@ -51,7 +59,9 @@ "has_global_scope": "false", "has_per_asic_scope": "true", "set_owner": "kube", - "check_up_status": "false" + "check_up_status": "false", + "support_syslog_rate_limit": "true", + "has_customized_syslog_rate_limit": "false" }, { "name": "dhcp_relay", @@ -61,7 +71,9 @@ "has_global_scope": "false", "has_per_asic_scope": "true", "set_owner": "kube", - "check_up_status": "false" + "check_up_status": "false", + "support_syslog_rate_limit": "true", + "has_customized_syslog_rate_limit": "false" } ] } @@ -79,7 +91,9 @@ "has_global_scope": "false", "has_per_asic_scope": "true", "set_owner": "invalid", - "check_up_status": "false" + "check_up_status": "false", + "support_syslog_rate_limit": "true", + "has_customized_syslog_rate_limit": "false" } ] } @@ -96,7 +110,9 @@ "has_timer": "false", "has_global_scope": "false", "has_per_asic_scope": "true", - "check_up_status": "false" + "check_up_status": "false", + "support_syslog_rate_limit": "true", + "has_customized_syslog_rate_limit": "false" } ] } @@ -113,7 +129,9 @@ "has_timer": "FALSE", "has_global_scope": "TRUE", "has_per_asic_scope": "TRUE", - "check_up_status": "FALSE" + "check_up_status": "FALSE", + "support_syslog_rate_limit": "TRUE", + "has_customized_syslog_rate_limit": "FALSE" } ] } diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/syslog.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/syslog.json index 990fdcf85c72..eaf8cf202493 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/syslog.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/syslog.json @@ -157,5 +157,116 @@ ] } } + }, + "SYSLOG_CONFIG_VALID": { + "sonic-syslog:sonic-syslog": { + "sonic-syslog:SYSLOG_CONFIG": { + "sonic-syslog:GLOBAL": { + "rate_limit_interval": "200", + "rate_limit_burst": "40000" + } + } + } + }, + "SYSLOG_CONFIG_INVALID_INTERVAL": { + "sonic-syslog:sonic-syslog": { + "sonic-syslog:SYSLOG_CONFIG": { + "sonic-syslog:GLOBAL": { + "rate_limit_interval": "-1" + } + } + } + }, + "SYSLOG_CONFIG_INVALID_BURST": { + "sonic-syslog:sonic-syslog": { + "sonic-syslog:SYSLOG_CONFIG": { + "sonic-syslog:GLOBAL": { + "rate_limit_burst": "-1" + } + } + } + }, + "SYSLOG_CONFIG_FEATURE_VALID": { + "sonic-syslog:sonic-syslog": { + "sonic-syslog:SYSLOG_CONFIG_FEATURE": { + "SYSLOG_CONFIG_FEATURE_LIST": [ + { + "service": "bgp", + "rate_limit_interval": "200", + "rate_limit_burst": "40000" + } + ] + } + }, + "sonic-feature:sonic-feature": { + "sonic-feature:FEATURE": { + "FEATURE_LIST": [ + { + "name": "bgp", + "support_syslog_rate_limit": "true", + "has_customized_syslog_rate_limit": "false" + } + ] + } + } + }, + "SYSLOG_CONFIG_FEATURE_INVALID_SERVICE_NAME": { + "sonic-syslog:sonic-syslog": { + "sonic-syslog:SYSLOG_CONFIG_FEATURE": { + "SYSLOG_CONFIG_FEATURE_LIST": [ + { + "service": "invalid", + "rate_limit_interval": "100", + "rate_limit_burst": "20000" + } + ] + } + } + }, + "SYSLOG_CONFIG_FEATURE_INVALID_INTERVAL": { + "sonic-syslog:sonic-syslog": { + "sonic-syslog:SYSLOG_CONFIG_FEATURE": { + "SYSLOG_CONFIG_FEATURE_LIST": [ + { + "service": "bgp", + "rate_limit_interval": "-1" + } + ] + } + }, + "sonic-feature:sonic-feature": { + "sonic-feature:FEATURE": { + "FEATURE_LIST": [ + { + "name": "bgp", + "support_syslog_rate_limit": "true", + "has_customized_syslog_rate_limit": "false" + } + ] + } + } + }, + "SYSLOG_CONFIG_FEATURE_INVALID_BURST": { + "sonic-syslog:sonic-syslog": { + "sonic-syslog:SYSLOG_CONFIG_FEATURE": { + "SYSLOG_CONFIG_FEATURE_LIST": [ + { + "service": "bgp", + "rate_limit_burst": "-1" + } + ] + } + }, + "sonic-feature:sonic-feature": { + "sonic-feature:FEATURE": { + "FEATURE_LIST": [ + { + "name": "bgp", + "support_syslog_rate_limit": "true", + "has_customized_syslog_rate_limit": "false" + } + ] + } + } } } diff --git a/src/sonic-yang-models/yang-models/sonic-feature.yang b/src/sonic-yang-models/yang-models/sonic-feature.yang index f27411788e8d..eef3bfda4555 100644 --- a/src/sonic-yang-models/yang-models/sonic-feature.yang +++ b/src/sonic-yang-models/yang-models/sonic-feature.yang @@ -93,6 +93,19 @@ module sonic-feature{ type stypes:boolean_type; default "false"; } + + leaf support_syslog_rate_limit { + description "This configuration indicates the feature support configuring + syslog rate limit"; + type stypes:boolean_type; + default "false"; + } + + leaf has_customized_syslog_rate_limit { + description "This configuration indicates if the feature has customized syslog rate limit configuration"; + type stypes:boolean_type; + default "false"; + } } } } diff --git a/src/sonic-yang-models/yang-models/sonic-syslog.yang b/src/sonic-yang-models/yang-models/sonic-syslog.yang index c2aa73827f0f..281607439455 100644 --- a/src/sonic-yang-models/yang-models/sonic-syslog.yang +++ b/src/sonic-yang-models/yang-models/sonic-syslog.yang @@ -17,6 +17,10 @@ module sonic-syslog { prefix vrf; } + import sonic-feature { + prefix feature; + } + description "Syslog YANG Module for SONiC OS: remote syslog logging"; revision 2022-04-18 { @@ -74,6 +78,62 @@ module sonic-syslog { /* end of list SYSLOG_SERVER_LIST */ } /* end of container SYSLOG_SERVER */ + + container SYSLOG_CONFIG { + + description "SYSLOG_CONFIG part of config_db.json"; + + container GLOBAL { + leaf rate_limit_interval { + description "Message rate limit interval"; + type uint32 { + range 0..2147483647; + } + } + + leaf rate_limit_burst { + description "Message rate limit burst"; + type uint32 { + range 0..2147483647; + } + } + } + /* end of list SYSLOG_CONFIG_LIST */ + } + /* end of container SYSLOG_CONFIG */ + + container SYSLOG_CONFIG_FEATURE { + + description "SYSLOG_CONFIG_FEATURE part of config_db.json"; + + list SYSLOG_CONFIG_FEATURE_LIST { + + key "service"; + + leaf service { + description "Service name"; + type leafref { + path "/feature:sonic-feature/feature:FEATURE/feature:FEATURE_LIST/feature:name"; + } + } + + leaf rate_limit_interval { + description "Message rate limit interval"; + type uint32 { + range 0..2147483647; + } + } + + leaf rate_limit_burst { + description "Message rate limit burst"; + type uint32 { + range 0..2147483647; + } + } + } + /* end of list SYSLOG_CONFIG_FEATURE_LIST */ + } + /* end of container SYSLOG_CONFIG_FEATURE */ } /* end of container sonic-syslog */ }