[PINS] Build P4RT container for PINS (#9083)

- Add INCLUDE_PINS to config to enable/disable container
- Add Docker files and supporting resources
- Add sonic-pins submodule and associated make files

Submission containing materials of a third party:
    Copyright Google LLC; Licensed under Apache 2.0

#### Why I did it

Adds P4RT container to SONiC for PINS

The P4RT app is covered by this HLD:
https://github.com/pins/SONiC/blob/master/doc/pins/p4rt_app_hld.md

#### How I did it

Followed the pattern and templates used for other SONiC applications

#### How to verify it

Build SONiC with INCLUDE_P4RT set to "y".
Verify that the resulting build has a container called "p4rt" running.
You can verify that the service is up by running the following command on the SONiC switch:
```bash
sudo netstat -lpnt | grep p4rt
```
You should see the service listening on TCP port 9559.

#### Which release branch to backport (provide reason below if selected)

None

#### Description for the changelog

Build P4RT container for PINS
This commit is contained in:
Brian O'Connor 2021-12-07 14:11:25 -05:00 committed by Abhishek Dosi
parent 181e7b3b6e
commit 6bffcb9e71
20 changed files with 288 additions and 0 deletions

3
.gitmodules vendored
View File

@ -97,3 +97,6 @@
[submodule "src/linkmgrd"] [submodule "src/linkmgrd"]
path = src/linkmgrd path = src/linkmgrd
url = https://github.com/Azure/sonic-linkmgrd.git url = https://github.com/Azure/sonic-linkmgrd.git
[submodule "src/sonic-p4rt/sonic-pins"]
path = src/sonic-p4rt/sonic-pins
url = https://github.com/Azure/sonic-pins.git

View File

@ -0,0 +1,31 @@
{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %}
FROM docker-config-engine-buster
ARG docker_container_name
ARG git_commit
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
RUN apt-get update
{% if docker_sonic_p4rt_debs.strip() -%}
# Copy locally-built Debian package dependencies
{{ copy_files("debs/", docker_sonic_p4rt_debs.split(' '), "/debs/") }}
# Install locally-built Debian packages and implicitly install their dependencies
{{ install_debian_packages(docker_sonic_p4rt_debs.split(' ')) }}
{%- endif %}
RUN apt-get clean -y && \
apt-get autoclean -y && \
apt-get autoremove -y && \
rm -rf /debs
COPY ["start.sh", "p4rt.sh", "/usr/bin/"]
COPY ["supervisord.conf", "/etc/supervisor/conf.d/"]
COPY ["files/supervisor-proc-exit-listener", "/usr/bin"]
COPY ["critical_processes", "/etc/supervisor"]
ENTRYPOINT ["/usr/local/bin/supervisord"]

View File

@ -0,0 +1 @@
program:p4rt

View File

@ -0,0 +1,5 @@
#!/usr/bin/env bash
P4RT_ARGS=" --alsologtostderr --logbuflevel=-1"
exec /usr/local/bin/p4rt ${P4RT_ARGS}

View File

@ -0,0 +1,4 @@
#!/usr/bin/env bash
mkdir -p /var/sonic
echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status

View File

@ -0,0 +1,49 @@
[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=50
[eventlistener:supervisor-proc-exit-listener]
command=/usr/bin/supervisor-proc-exit-listener --container-name p4rt
events=PROCESS_STATE_EXITED
autostart=true
autorestart=unexpected
[program:rsyslogd]
command=/usr/sbin/rsyslogd -n -iNONE
priority=1
autostart=false
autorestart=unexpected
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
[program:start]
command=/usr/bin/start.sh
priority=2
autostart=true
autorestart=false
startsecs=0
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=rsyslogd:running
[program:p4rt]
command=/usr/bin/p4rt.sh
priority=3
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=start:exited

View File

@ -2,6 +2,7 @@
"DEVICE_METADATA": { "DEVICE_METADATA": {
"localhost": { "localhost": {
"buffer_model": {% if default_buffer_model == "dynamic" %}"dynamic"{% else %}"traditional"{% endif %}, "buffer_model": {% if default_buffer_model == "dynamic" %}"dynamic"{% else %}"traditional"{% endif %},
{%- if include_p4rt == "y" %}"synchronous_mode":"enable",{% endif %}
"default_bgp_status": {% if shutdown_bgp_on_start == "y" %}"down"{% else %}"up"{% endif %}, "default_bgp_status": {% if shutdown_bgp_on_start == "y" %}"down"{% else %}"up"{% endif %},
"default_pfcwd_status": {% if enable_pfcwd_on_start == "y" %}"enable"{% else %}"disable"{% endif %} "default_pfcwd_status": {% if enable_pfcwd_on_start == "y" %}"enable"{% else %}"disable"{% endif %}
} }
@ -41,6 +42,7 @@
{%- if include_mgmt_framework == "y" %}{% do features.append(("mgmt-framework", "enabled", true, "enabled")) %}{% endif %} {%- if include_mgmt_framework == "y" %}{% do features.append(("mgmt-framework", "enabled", true, "enabled")) %}{% endif %}
{%- if include_mux == "y" %}{% do features.append(("mux", "{% if 'subtype' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['subtype'] == 'DualToR' %}enabled{% else %}always_disabled{% endif %}", false, "enabled")) %}{% endif %} {%- if include_mux == "y" %}{% do features.append(("mux", "{% if 'subtype' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['subtype'] == 'DualToR' %}enabled{% else %}always_disabled{% endif %}", false, "enabled")) %}{% endif %}
{%- if include_nat == "y" %}{% do features.append(("nat", "disabled", false, "enabled")) %}{% endif %} {%- if include_nat == "y" %}{% do features.append(("nat", "disabled", false, "enabled")) %}{% endif %}
{%- if include_p4rt == "y" %}{% do features.append(("p4rt", "enabled", false, "enabled")) %}{% endif %}
{%- if include_restapi == "y" %}{% do features.append(("restapi", "enabled", false, "enabled")) %}{% endif %} {%- if include_restapi == "y" %}{% do features.append(("restapi", "enabled", false, "enabled")) %}{% endif %}
{%- if include_sflow == "y" %}{% do features.append(("sflow", "disabled", false, "enabled")) %}{% endif %} {%- if include_sflow == "y" %}{% do features.append(("sflow", "disabled", false, "enabled")) %}{% endif %}
{%- if include_macsec == "y" %}{% do features.append(("macsec", "disabled", false, "enabled")) %}{% endif %} {%- if include_macsec == "y" %}{% do features.append(("macsec", "disabled", false, "enabled")) %}{% endif %}

View File

@ -0,0 +1,20 @@
[Unit]
Description=P4RT App container
Requires=database.service
After=database.service swss.service
BindsTo=sonic.target
After=sonic.target
Before=ntp-config.service
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

View File

@ -144,6 +144,9 @@ INCLUDE_NAT = y
# INCLUDE_DHCP_RELAY - build and install dhcp-relay package # INCLUDE_DHCP_RELAY - build and install dhcp-relay package
INCLUDE_DHCP_RELAY = y INCLUDE_DHCP_RELAY = y
# INCLUDE_P4RT - build docker-p4rt for P4RT support
INCLUDE_P4RT = n
# ENABLE_AUTO_TECH_SUPPORT - Enable the configuration for event-driven techsupport & coredump mgmt feature # ENABLE_AUTO_TECH_SUPPORT - Enable the configuration for event-driven techsupport & coredump mgmt feature
ENABLE_AUTO_TECH_SUPPORT = y ENABLE_AUTO_TECH_SUPPORT = y

10
rules/docker-p4rt.dep Normal file
View File

@ -0,0 +1,10 @@
DPATH := $($(DOCKER_P4RT)_PATH)
DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/docker-p4rt.mk rules/docker-p4rt.dep
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
DEP_FILES += $(shell git ls-files $(DPATH))
$(DOCKER_P4RT)_CACHE_MODE := GIT_CONTENT_SHA
$(DOCKER_P4RT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
$(DOCKER_P4RT)_DEP_FILES := $(DEP_FILES)
$(eval $(call add_dbg_docker,$(DOCKER_P4RT),$(DOCKER_P4RT_DBG)))

35
rules/docker-p4rt.mk Normal file
View File

@ -0,0 +1,35 @@
# docker image for p4rt
DOCKER_P4RT_STEM = docker-sonic-p4rt
DOCKER_P4RT = $(DOCKER_P4RT_STEM).gz
DOCKER_P4RT_DBG = $(DOCKER_P4RT_STEM)-$(DBG_IMAGE_MARK).gz
$(DOCKER_P4RT)_PATH = $(DOCKERS_PATH)/$(DOCKER_P4RT_STEM)
$(DOCKER_P4RT)_DEPENDS += $(SONIC_P4RT)
$(DOCKER_P4RT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS)
$(DOCKER_P4RT)_DBG_DEPENDS += $(SONIC_P4RT_DBG) $(LIBSWSSCOMMON_DBG)
$(DOCKER_P4RT)_DBG_DEPENDS += $(LIBSAIREDIS_DBG)
$(DOCKER_P4RT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES)
$(DOCKER_P4RT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER)
$(DOCKER_P4RT)_VERSION = 1.0.0
$(DOCKER_P4RT)_PACKAGE_NAME = p4rt
$(DOCKER_P4RT)_WARM_SHUTDOWN_BEFORE = swss
$(DOCKER_P4RT)_FAST_SHUTDOWN_BEFORE = swss
SONIC_DOCKER_IMAGES += $(DOCKER_P4RT)
SONIC_DOCKER_DBG_IMAGES += $(DOCKER_P4RT_DBG)
ifeq ($(INCLUDE_P4RT), y)
SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_P4RT)
SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_P4RT_DBG)
endif
$(DOCKER_P4RT)_CONTAINER_NAME = p4rt
$(DOCKER_P4RT)_RUN_OPT += --privileged -t
$(DOCKER_P4RT)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
$(DOCKER_P4RT)_GIT_COMMIT = $(shell cd "$($(SONIC_P4RT)_SRC_PATH)" && git log -n 1 --format=format:"%H %s" || echo "Unable to fetch git log for p4rt")
$(DOCKER_P4RT)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)

12
rules/p4rt.dep Normal file
View File

@ -0,0 +1,12 @@
SPATH := $($(SONIC_P4RT)_SRC_PATH)
DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/p4rt.mk rules/p4rt.dep
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) $(SPATH)/Makefile
SMDEP_PATH := $(SPATH)/sonic-pins
DEP_FILES += $(shell cd $(SPATH) && git ls-files | grep -v ^sonic-pins)
SMDEP_FILES := $(addprefix $(SMDEP_PATH)/,$(shell cd $(SMDEP_PATH) && git ls-files))
$(SONIC_P4RT)_CACHE_MODE := GIT_CONTENT_SHA
$(SONIC_P4RT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
$(SONIC_P4RT)_DEP_FILES := $(DEP_FILES)
$(SONIC_P4RT)_SMDEP_FILES := $(SMDEP_FILES)
$(SONIC_P4RT)_SMDEP_PATHS := $(SMDEP_PATH)

20
rules/p4rt.mk Normal file
View File

@ -0,0 +1,20 @@
# SONiC P4RT package
SONIC_P4RT_VERSION = 0.0.1
SONIC_P4RT = sonic-p4rt_$(SONIC_P4RT_VERSION)_$(CONFIGURED_ARCH).deb
$(SONIC_P4RT)_SRC_PATH = $(SRC_PATH)/sonic-p4rt
$(SONIC_P4RT)_DEPENDS += $(LIBSWSSCOMMON_DEV)
$(SONIC_P4RT)_RDEPENDS += $(LIBSWSSCOMMON)
SONIC_MAKE_DEBS += $(SONIC_P4RT)
SONIC_P4RT_DBG = sonic-p4rt-dbgsym_$(SONIC_P4RT_VERSION)_$(CONFIGURED_ARCH).deb
$(SONIC_P4RT_DBG)_DEPENDS += $(SONIC_P4RT)
$(SONIC_P4RT_DBG)_RDEPENDS += $(SONIC_P4RT)
$(eval $(call add_derived_package,$(SONIC_P4RT),$(SONIC_P4RT_DBG)))
export SONIC_P4RT SONIC_P4RT_DBG SONIC_P4RT_VERSION
# The .c, .cpp, .h & .hpp files under src/{$DBG_SRC_ARCHIVE list}
# are archived into debug one image to facilitate debugging.
DBG_SRC_ARCHIVE += sonic-p4rt

View File

@ -159,6 +159,19 @@ ifeq ($(SONIC_INCLUDE_NAT),y)
INCLUDE_NAT = y INCLUDE_NAT = y
endif endif
ifeq ($(SONIC_INCLUDE_P4RT),y)
INCLUDE_P4RT = y
endif
# Pre-built Bazel is not available for armhf, so exclude P4RT
# TODO(PINS): Remove when Bazel binaries are available for armhf
ifeq ($(CONFIGURED_ARCH),armhf)
ifeq ($(INCLUDE_P4RT),y)
@echo "Disabling P4RT due to incompatible CPU architecture: $(CONFIGURED_ARCH)"
endif
override INCLUDE_P4RT = n
endif
ifeq ($(SONIC_INCLUDE_MACSEC),y) ifeq ($(SONIC_INCLUDE_MACSEC),y)
INCLUDE_MACSEC = y INCLUDE_MACSEC = y
endif endif
@ -290,6 +303,7 @@ $(info "INCLUDE_RESTAPI" : "$(INCLUDE_RESTAPI)")
$(info "INCLUDE_SFLOW" : "$(INCLUDE_SFLOW)") $(info "INCLUDE_SFLOW" : "$(INCLUDE_SFLOW)")
$(info "INCLUDE_NAT" : "$(INCLUDE_NAT)") $(info "INCLUDE_NAT" : "$(INCLUDE_NAT)")
$(info "INCLUDE_DHCP_RELAY" : "$(INCLUDE_DHCP_RELAY)") $(info "INCLUDE_DHCP_RELAY" : "$(INCLUDE_DHCP_RELAY)")
$(info "INCLUDE_P4RT" : "$(INCLUDE_P4RT)")
$(info "INCLUDE_KUBERNETES" : "$(INCLUDE_KUBERNETES)") $(info "INCLUDE_KUBERNETES" : "$(INCLUDE_KUBERNETES)")
$(info "INCLUDE_MACSEC" : "$(INCLUDE_MACSEC)") $(info "INCLUDE_MACSEC" : "$(INCLUDE_MACSEC)")
$(info "INCLUDE_MUX" : "$(INCLUDE_MUX)") $(info "INCLUDE_MUX" : "$(INCLUDE_MUX)")
@ -992,6 +1006,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
export include_system_telemetry="$(INCLUDE_SYSTEM_TELEMETRY)" export include_system_telemetry="$(INCLUDE_SYSTEM_TELEMETRY)"
export include_restapi="$(INCLUDE_RESTAPI)" export include_restapi="$(INCLUDE_RESTAPI)"
export include_nat="$(INCLUDE_NAT)" export include_nat="$(INCLUDE_NAT)"
export include_p4rt="$(INCLUDE_P4RT)"
export include_sflow="$(INCLUDE_SFLOW)" export include_sflow="$(INCLUDE_SFLOW)"
export enable_auto_tech_support="$(ENABLE_AUTO_TECH_SUPPORT)" export enable_auto_tech_support="$(ENABLE_AUTO_TECH_SUPPORT)"
export include_macsec="$(INCLUDE_MACSEC)" export include_macsec="$(INCLUDE_MACSEC)"

View File

@ -518,3 +518,13 @@ RUN apt-get install -y nodejs
# Tell azure pipeline to use node.js in the docker # Tell azure pipeline to use node.js in the docker
LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/bin/node" LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/bin/node"
{% endif -%} {% endif -%}
# Install Bazel build system (amd64 and arm64 architectures are supported using this method)
# TODO(PINS): Remove once pre-build Bazel binaries are available for armhf (armv7l)
{%- if CONFIGURED_ARCH == "amd64" or CONFIGURED_ARCH == "arm64" %}
ARG bazelisk_url=https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-{{ CONFIGURED_ARCH }}
RUN curl -fsSL -o /usr/local/bin/bazel ${bazelisk_url} && chmod 755 /usr/local/bin/bazel
# Bazel requires "python"
# TODO(PINS): remove when Bazel is okay with "python3" binary name
RUN apt install -y python-is-python3
{% endif -%}

View File

@ -542,3 +542,10 @@ RUN apt-get install -y nodejs
# Tell azure pipeline to use node.js in the docker # Tell azure pipeline to use node.js in the docker
LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/bin/node" LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/bin/node"
{% endif -%} {% endif -%}
# Install Bazel build system (amd64 and arm64 architectures are supported using this method)
# TODO(PINS): Remove once pre-build Bazel binaries are available for armhf (armv7l)
{%- if CONFIGURED_ARCH == "amd64" or CONFIGURED_ARCH == "arm64" %}
ARG bazelisk_url=https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-{{ CONFIGURED_ARCH }}
RUN curl -fsSL -o /usr/local/bin/bazel ${bazelisk_url} && chmod 755 /usr/local/bin/bazel
{% endif -%}

View File

@ -354,3 +354,10 @@ RUN pip install m2crypto==0.36.0
# Install swi tools # Install swi tools
RUN python -m pip install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00 RUN python -m pip install git+https://github.com/aristanetworks/swi-tools.git@d51761ec0bb93c73039233f3c01ed48235ffad00
# Install Bazel build system (amd64 and arm64 architectures are supported using this method)
# TODO(PINS): Remove once pre-build Bazel binaries are available for armhf (armv7l)
{%- if CONFIGURED_ARCH == "amd64" or CONFIGURED_ARCH == "arm64" %}
ARG bazelisk_url=https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-{{ CONFIGURED_ARCH }}
RUN curl -fsSL -o /usr/local/bin/bazel ${bazelisk_url} && chmod 755 /usr/local/bin/bazel
{% endif -%}

View File

@ -458,3 +458,10 @@ RUN apt-get install -y nodejs
# Tell azure pipeline to use node.js in the docker # Tell azure pipeline to use node.js in the docker
LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/bin/node" LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/bin/node"
{% endif -%} {% endif -%}
# Install Bazel build system (amd64 and arm64 architectures are supported using this method)
# TODO(PINS): Remove once pre-build Bazel binaries are available for armhf (armv7l)
{%- if CONFIGURED_ARCH == "amd64" or CONFIGURED_ARCH == "arm64" %}
ARG bazelisk_url=https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-{{ CONFIGURED_ARCH }}
RUN curl -fsSL -o /usr/local/bin/bazel ${bazelisk_url} && chmod 755 /usr/local/bin/bazel
{% endif -%}

46
src/sonic-p4rt/Makefile Normal file
View File

@ -0,0 +1,46 @@
.ONESHELL:
SHELL = /bin/bash
.SHELLFLAGS += -e
BAZEL_TARGET_PATH = p4rt_app
BAZEL_BUILD_TARGETS = //p4rt_app:p4rt_deb //p4rt_app:p4rt_dbg_deb
# Enable debug symbols for remote debugging (generate a .dwp).
BAZEL_BUILD_OPTS += --fission=yes --features=per_object_debug_info
# Override sonic_swss_common to use the version specific to this buildimage.
BAZEL_BUILD_OPTS += --override_repository=sonic_swss_common=/sonic/src/sonic-swss-common
# Build optimized, stripped binaries.
BAZEL_BUILD_OPTS += -c opt
# Use a host directory to store Bazel cache, if mounted. This will speed up
# incremental rebuilds on the same system for developers that makes changes
# to sonic-pins code.
#
# To build with Bazel cache, add DOCKER_BUILDER_USER_MOUNT:
# DOCKER_BUILDER_USER_MOUNT=<directory on host system>:$BAZEL_CACHE:rw
#
# For example:
# DOCKER_BUILDER_USER_MOUNT=/tmp/bazel_cache:/bazel:rw make target/...
#
BAZEL_CACHE ?= /bazel
BAZEL_OPTS += $(shell test -d $(BAZEL_CACHE) && echo --output_user_root=$(BAZEL_CACHE)/cache)
MAIN_TARGET = $(SONIC_P4RT)
DERIVED_TARGETS = $(SONIC_P4RT_DBG)
$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
function cleanup {
# Note: make seems to hang if Bazel is still running
cd $(CURDIR)/sonic-pins && bazel $(BAZEL_OPTS) shutdown
}
trap cleanup EXIT
pushd ./sonic-pins
bazel $(BAZEL_OPTS) build $(BAZEL_BUILD_OPTS) $(BAZEL_BUILD_TARGETS)
bazel $(BAZEL_OPTS) test $(BAZEL_BUILD_OPTS) //$(BAZEL_TARGET_PATH)/...
cd ./bazel-bin/$(BAZEL_TARGET_PATH)
mv $* $(DERIVED_TARGETS) $(DEST)/
popd
$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET)

@ -0,0 +1 @@
Subproject commit 36322d349779f99e30fc52c26fee60945b0eb5e8