diff --git a/Makefile.work b/Makefile.work index df4e6de8a7..21e40fb633 100644 --- a/Makefile.work +++ b/Makefile.work @@ -537,6 +537,7 @@ SONIC_BUILD_INSTRUCTION := $(MAKE) \ SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD=$(SONIC_CONFIG_USE_NATIVE_DOCKERD_FOR_BUILD) \ SONIC_INCLUDE_SYSTEM_TELEMETRY=$(INCLUDE_SYSTEM_TELEMETRY) \ INCLUDE_DHCP_RELAY=$(INCLUDE_DHCP_RELAY) \ + INCLUDE_DHCP_SERVER=$(INCLUDE_DHCP_SERVER) \ INCLUDE_MACSEC=$(INCLUDE_MACSEC) \ SONIC_INCLUDE_RESTAPI=$(INCLUDE_RESTAPI) \ SONIC_INCLUDE_MUX=$(INCLUDE_MUX) \ diff --git a/dockers/docker-dhcp-server/Dockerfile.j2 b/dockers/docker-dhcp-server/Dockerfile.j2 new file mode 100755 index 0000000000..af999e74a4 --- /dev/null +++ b/dockers/docker-dhcp-server/Dockerfile.j2 @@ -0,0 +1,79 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-config-engine-bullseye-{{DOCKER_USERNAME}}:{{DOCKER_USERTAG}} + +ARG docker_container_name +ARG image_version + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +# Pass the image_version to container +ENV IMAGE_VERSION=$image_version + +RUN apt-get update && \ + apt-get install -f -y \ + tcpdump \ +# For kea build environment + automake \ + libtool \ + pkg-config \ + build-essential \ + ccache \ +# For kea dependancies + libboost-dev \ + libboost-system-dev \ + liblog4cplus-dev \ + libssl-dev + +# Install kea from source +RUN apt-get install -f -y devscripts +RUN mkdir kea && cd kea && dget -u http://deb.debian.org/debian/pool/main/i/isc-kea/isc-kea_2.2.0-6.dsc +RUN cd /kea/isc-kea-2.2.0 && autoreconf --install && ./configure --disable-FEATURE \ + --enable-static=no --disable-install-configurations --enable-pgsql-ssl=no --with-PACKAGE=no \ + && make -j$(nproc) && make install +# Create run folder for kea +RUN mkdir -p /run/kea +# Create config folder for kea +RUN mkdir -p /etc/kea +# Remove stuff we don't need to reduce image size +RUN cd /usr/local/lib && rm -v *.la && rm -v kea/hooks/*.la +# Strip debug symbols to reduce file size of binaries +Run find /usr/local/sbin/ /usr/local/lib/ -type f -exec strip --strip-unneeded {} \; +# Remove source code +RUN rm -rf /kea +RUN echo "/usr/local/lib/kea/hooks" > /etc/ld.so.conf.d/kea.conf && \ + ldconfig +# Remove sbin we don't need +RUN cd /usr/local/sbin && rm -f kea-admin kea-ctrl-agent kea-dhcp-ddns kea-dhcp6 keactrl +# Remove hook lib we don't need +RUN cd /usr/local/lib/kea/hooks && rm -f libdhcp_bootp.so libdhcp_flex_option.so libdhcp_stat_cmds.so +# RUN pip3 install psutil + +{% if docker_dhcp_server_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_dhcp_server_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_dhcp_server_debs.split(' ')) }} +{%- endif %} + +# Remove build stuff we don't need +RUN apt-get remove -y devscripts \ + automake \ + libtool \ + pkg-config \ + build-essential \ + ccache + +RUN apt-get clean -y && \ + apt-get autoclean -y && \ + apt-get autoremove -y && \ + rm -rf /debs + +COPY ["docker_init.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor/"] +COPY ["cli", "/cli/"] + +ENTRYPOINT ["/usr/bin/docker_init.sh"] diff --git a/dockers/docker-dhcp-server/cli/clear/plugins/clear_dhcp_server.py b/dockers/docker-dhcp-server/cli/clear/plugins/clear_dhcp_server.py new file mode 100644 index 0000000000..c27ebdcd8c --- /dev/null +++ b/dockers/docker-dhcp-server/cli/clear/plugins/clear_dhcp_server.py @@ -0,0 +1,16 @@ +import click +import utilities_common.cli as clicommon + + +@click.group(cls=clicommon.AliasedGroup, name="dhcp_server") +def dhcp_server(): + pass + + +def register(cli): + # cli.add_command(dhcp_server) + pass + + +if __name__ == '__main__': + dhcp_server() diff --git a/dockers/docker-dhcp-server/cli/config/plugins/dhcp_server.py b/dockers/docker-dhcp-server/cli/config/plugins/dhcp_server.py new file mode 100644 index 0000000000..539a71e6a4 --- /dev/null +++ b/dockers/docker-dhcp-server/cli/config/plugins/dhcp_server.py @@ -0,0 +1,17 @@ +import click +import utilities_common.cli as clicommon + + +@click.group(cls=clicommon.AbbreviationGroup, name="dhcp_server") +def dhcp_server(): + """config DHCP Server information""" + pass + + +def register(cli): + # cli.add_command(dhcp_server) + pass + + +if __name__ == '__main__': + dhcp_server() diff --git a/dockers/docker-dhcp-server/cli/show/plugins/show_dhcp_server.py b/dockers/docker-dhcp-server/cli/show/plugins/show_dhcp_server.py new file mode 100644 index 0000000000..23bf77a427 --- /dev/null +++ b/dockers/docker-dhcp-server/cli/show/plugins/show_dhcp_server.py @@ -0,0 +1,13 @@ +import click +import utilities_common.cli as clicommon + + +@click.group(cls=clicommon.AliasedGroup, name="dhcp_server") +def dhcp_server(): + """show DHCP Server information""" + pass + + +def register(cli): + # cli.add_command(dhcp_server) + pass diff --git a/dockers/docker-dhcp-server/critical_processes b/dockers/docker-dhcp-server/critical_processes new file mode 100644 index 0000000000..e69de29bb2 diff --git a/dockers/docker-dhcp-server/docker_init.sh b/dockers/docker-dhcp-server/docker_init.sh new file mode 100755 index 0000000000..5f5d397213 --- /dev/null +++ b/dockers/docker-dhcp-server/docker_init.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +# The docker container should start this script as PID 1, so now that supervisord is +# properly configured, we exec /usr/local/bin/supervisord so that it runs as PID 1 for the +# duration of the container's lifetime +exec /usr/local/bin/supervisord diff --git a/dockers/docker-dhcp-server/supervisord.conf b/dockers/docker-dhcp-server/supervisord.conf new file mode 100644 index 0000000000..b4ee4f477d --- /dev/null +++ b/dockers/docker-dhcp-server/supervisord.conf @@ -0,0 +1,40 @@ +[supervisord] +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 dhcp_server +events=PROCESS_STATE_EXITED,PROCESS_STATE_RUNNING +autostart=true +autorestart=unexpected +buffer_size=1024 + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n -iNONE +priority=1 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true + +[program:start] +command=/usr/bin/start.sh +priority=2 +autostart=false +autorestart=false +startsecs=0 +stdout_logfile=syslog +stderr_logfile=syslog +dependent_startup=true +dependent_startup_wait_for=rsyslogd:running diff --git a/files/build_templates/dhcp_server.service.j2 b/files/build_templates/dhcp_server.service.j2 new file mode 100644 index 0000000000..bf6af4ddf0 --- /dev/null +++ b/files/build_templates/dhcp_server.service.j2 @@ -0,0 +1,20 @@ +[Unit] +Description=DHCP server container +Requires=swss.service +After=swss.service +After=syncd.service +BindsTo=sonic.target +After=sonic.target +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{ docker_container_name }}.sh start +ExecStart=/usr/bin/{{ docker_container_name }}.sh wait +ExecStop=/usr/bin/{{ docker_container_name }}.sh stop +Restart=always +RestartSec=30 + +[Install] +WantedBy=sonic.target diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 546eb24cb6..32686822b5 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -540,7 +540,9 @@ start() { # TODO: Mellanox will remove the --tmpfs exception after SDK socket path changed in new SDK version {%- endif %} docker create {{docker_image_run_opt}} \ +{%- if docker_container_name != "dhcp_server" %} --net=$NET \ +{%- endif %} -e RUNTIME_OWNER=local \ --uts=host \{# W/A: this should be set per-docker, for those dockers which really need host's UTS namespace #} {%- if install_debug_image == "y" %} diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index b93b565adc..3025da5487 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -44,6 +44,7 @@ {%- if include_router_advertiser == "y" %}{% do features.append(("radv", "enabled", false, "enabled")) %}{% endif %} {%- if include_teamd == "y" %}{% do features.append(("teamd", "{% if not DEVICE_RUNTIME_METADATA['ETHERNET_PORTS_PRESENT'] %}disabled{% else %}enabled{% endif %}", false, "enabled")) %}{% endif %} {% do features.append(("dhcp_relay", "{% if not (DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined and DEVICE_METADATA['localhost']['type'] is not in ['ToRRouter', 'EPMS', 'MgmtTsToR', 'MgmtToRRouter', 'BmcMgmtToRRouter']) %}enabled{% else %}disabled{% endif %}", false, "enabled")) %} +{%- if include_dhcp_server == "y" %}{% do features.append(("dhcp_server", "disabled", false, "enabled")) %}{% endif %} {%- if sonic_asic_platform == "vs" %}{% do features.append(("gbsyncd", "enabled", false, "enabled")) %}{% endif %} {%- if include_iccpd == "y" %}{% do features.append(("iccpd", "disabled", false, "enabled")) %}{% endif %} {%- if include_mgmt_framework == "y" %}{% do features.append(("mgmt-framework", "enabled", true, "enabled")) %}{% endif %} diff --git a/rules/config b/rules/config index cc731a8955..c3c10e2d59 100644 --- a/rules/config +++ b/rules/config @@ -153,6 +153,9 @@ INCLUDE_NAT = y # INCLUDE_DHCP_RELAY - build and install dhcp-relay package INCLUDE_DHCP_RELAY = y +# INCLUDE_DHCP_SERVER - build and install dhcp-server package +INCLUDE_DHCP_SERVER = n + # INCLUDE_P4RT - build docker-p4rt for P4RT support INCLUDE_P4RT = n diff --git a/rules/docker-dhcp-server.dep b/rules/docker-dhcp-server.dep new file mode 100644 index 0000000000..c8c7ee9b40 --- /dev/null +++ b/rules/docker-dhcp-server.dep @@ -0,0 +1,11 @@ + +DPATH := $($(DOCKER_DHCP_SERVER)_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-dhcp-server.mk rules/docker-dhcp-server.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(DPATH)) + +$(DOCKER_DHCP_SERVER)_CACHE_MODE := GIT_CONTENT_SHA +$(DOCKER_DHCP_SERVER)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(DOCKER_DHCP_SERVER)_DEP_FILES := $(DEP_FILES) + +$(eval $(call add_dbg_docker,$(DOCKER_DHCP_SERVER),$(DOCKER_DHCP_SERVER_DBG))) diff --git a/rules/docker-dhcp-server.mk b/rules/docker-dhcp-server.mk new file mode 100644 index 0000000000..af600b81ec --- /dev/null +++ b/rules/docker-dhcp-server.mk @@ -0,0 +1,52 @@ +# Docker image for DHCP server + +DOCKER_DHCP_SERVER_STEM = docker-dhcp-server +DOCKER_DHCP_SERVER = $(DOCKER_DHCP_SERVER_STEM).gz +DOCKER_DHCP_SERVER_DBG = $(DOCKER_DHCP_SERVER_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_DHCP_SERVER)_PATH = $(DOCKERS_PATH)/$(DOCKER_DHCP_SERVER_STEM) + +$(DOCKER_DHCP_SERVER)_DEPENDS = $(SWSS) $(LIBSWSSCOMMON) $(SONIC_RSYSLOG_PLUGIN) +$(DOCKER_DHCP_SERVER)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BULLSEYE)_DBG_DEPENDS) + +$(DOCKER_DHCP_SERVER)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BULLSEYE)_DBG_IMAGE_PACKAGES) + +$(DOCKER_DHCP_SERVER)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BULLSEYE) + +$(DOCKER_DHCP_SERVER)_INSTALL_PYTHON_WHEELS = $(SONIC_UTILITIES_PY3) +$(DOCKER_DHCP_SERVER)_INSTALL_DEBS = $(PYTHON3_SWSSCOMMON) + +SONIC_DOCKER_IMAGES += $(DOCKER_DHCP_SERVER) +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_SERVER_DBG) + +ifeq ($(INCLUDE_KUBERNETES),y) +$(DOCKER_DHCP_SERVER)_DEFAULT_FEATURE_OWNER = kube +endif + +$(DOCKER_DHCP_SERVER)_DEFAULT_FEATURE_STATE_ENABLED = y + +ifeq ($(INCLUDE_DHCP_SERVER), y) +ifeq ($(INSTALL_DEBUG_TOOLS),y) +SONIC_PACKAGES_LOCAL += $(DOCKER_DHCP_SERVER_DBG) +else +SONIC_PACKAGES_LOCAL += $(DOCKER_DHCP_SERVER) +endif +endif + +$(DOCKER_DHCP_SERVER)_CONTAINER_NAME = dhcp_server +$(DOCKER_DHCP_SERVER)_VERSION = 1.0.0 +$(DOCKER_DHCP_SERVER)_PACKAGE_NAME = dhcp-server + +$(DOCKER_MACSEC)_SERVICE_REQUIRES = updategraph +$(DOCKER_MACSEC)_SERVICE_AFTER = swss syncd + +$(DOCKER_DHCP_SERVER)_CONTAINER_PRIVILEGED = true +$(DOCKER_DHCP_SERVER)_CONTAINER_VOLUMES += /etc/sonic:/etc/sonic:ro +$(DOCKER_DHCP_SERVER)_CONTAINER_TMPFS += /tmp/ +$(DOCKER_DHCP_SERVER)_CONTAINER_TMPFS += /var/tmp/ + +$(DOCKER_DHCP_SERVER)_CLI_CONFIG_PLUGIN = /cli/config/plugins/dhcp_server.py +$(DOCKER_DHCP_SERVER)_CLI_SHOW_PLUGIN = /cli/show/plugins/show_dhcp_server.py +$(DOCKER_DHCP_SERVER)_CLI_CLEAR_PLUGIN = /cli/clear/plugins/clear_dhcp_server.py + +$(DOCKER_DHCP_SERVER)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/slave.mk b/slave.mk index 2d5d8d840b..ae4e6171c8 100644 --- a/slave.mk +++ b/slave.mk @@ -419,6 +419,7 @@ $(info "INCLUDE_SFLOW" : "$(INCLUDE_SFLOW)") $(info "ENABLE_SFLOW_DROPMON" : "$(ENABLE_SFLOW_DROPMON)") $(info "INCLUDE_NAT" : "$(INCLUDE_NAT)") $(info "INCLUDE_DHCP_RELAY" : "$(INCLUDE_DHCP_RELAY)") +$(info "INCLUDE_DHCP_SERVER" : "$(INCLUDE_DHCP_SERVER)") $(info "INCLUDE_P4RT" : "$(INCLUDE_P4RT)") $(info "INCLUDE_KUBERNETES" : "$(INCLUDE_KUBERNETES)") $(info "INCLUDE_KUBERNETES_MASTER" : "$(INCLUDE_KUBERNETES_MASTER)") @@ -1295,6 +1296,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export enable_auto_tech_support="$(ENABLE_AUTO_TECH_SUPPORT)" export enable_asan="$(ENABLE_ASAN)" export include_macsec="$(INCLUDE_MACSEC)" + export include_dhcp_server="$(INCLUDE_DHCP_SERVER)" export include_mgmt_framework="$(INCLUDE_MGMT_FRAMEWORK)" export include_iccpd="$(INCLUDE_ICCPD)" export pddf_support="$(PDDF_SUPPORT)"