Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion dockers/docker-base-bookworm/Dockerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ RUN apt update && \
libwrap0 \
libatomic1

# Security fixes: upgrade vulnerable base packages (S360 scan remediation)
RUN apt-get update && apt-get upgrade -y \
&& rm -rf /var/lib/apt/lists/*

# Add a config file to allow pip to install packages outside of apt/the Debian repos
COPY ["pip.conf", "/etc/pip.conf"]

Expand All @@ -88,7 +92,8 @@ RUN apt-get -y purge \
exim4 \
exim4-base \
exim4-config \
exim4-daemon-light
exim4-daemon-light \
2>/dev/null; apt-get -y autoremove || true

{% if docker_base_bookworm_debs.strip() -%}
# Copy locally-built Debian package dependencies
Expand Down
139 changes: 127 additions & 12 deletions dockers/docker-ptf/Dockerfile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,39 @@ RUN apt-get update \
iproute2 \
wireshark-common \
freeradius \
quilt
quilt \
&& rm -rf /var/lib/apt/lists/*

# Install Go toolchain for building grpcurl and gnoic from source
# to ensure they use a patched Go stdlib (GO-2026-4337: crypto/tls)
{% if CONFIGURED_ARCH == "armhf" %}
RUN GO_ARCH=armv6l \
{% elif CONFIGURED_ARCH == "arm64" %}
RUN GO_ARCH=arm64 \
{% else %}
RUN GO_ARCH=amd64 \
{% endif %}
&& GO_VERSION=1.25.8 \
&& curl -L "https://go.dev/dl/go${GO_VERSION}.linux-${GO_ARCH}.tar.gz" -o /tmp/go.tar.gz \
&& tar -C /usr/local -xzf /tmp/go.tar.gz \
&& rm /tmp/go.tar.gz

ENV PATH="/usr/local/go/bin:$HOME/go/bin:$PATH"

# Build grpcurl from source with patched Go and golang.org/x/* deps
# upgraded to latest to address current and future golang.org/x/* CVEs.
RUN GRPCURL_VERSION=v1.9.3 \
&& git clone --depth 1 --branch "${GRPCURL_VERSION}" https://github.com/fullstorydev/grpcurl.git /tmp/grpcurl \
&& cd /tmp/grpcurl \
&& go get google.golang.org/[email protected] \
&& go get golang.org/x/crypto@latest golang.org/x/net@latest golang.org/x/text@latest golang.org/x/sys@latest golang.org/x/oauth2@latest \
&& go mod tidy \
&& go build -o /usr/local/bin/grpcurl ./cmd/grpcurl \
&& chmod +x /usr/local/bin/grpcurl \
&& rm -rf /tmp/grpcurl
# Security fixes: upgrade all vulnerable system packages (S360 scan remediation)
RUN apt-get update && apt-get upgrade -y \
&& rm -rf /var/lib/apt/lists/*
{% if PTF_ENV_PY_VER == "py3" %}
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 1 \
&& update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1 \
Expand All @@ -112,7 +143,7 @@ RUN rm -rf /debs \
&& rm -f get-pip.py \
&& pip install setuptools \
&& pip install supervisor \
&& pip install ipython==5.4.1 \
&& pip install ipython \
&& git clone https://github.com/p4lang/scapy-vxlan.git \
&& cd scapy-vxlan \
&& python setup.py install \
Expand Down Expand Up @@ -171,14 +202,41 @@ RUN rm -rf /debs \
&& cd /opt \
&& wget https://raw.githubusercontent.com/p4lang/ptf/master/ptf_nn/ptf_nn_agent.py

{% if PTF_ENV_PY_VER == "mixed" %}
RUN python3 -m venv --system-site-packages env-python3
{% if PTF_ENV_PY_VER == "py3" %}
RUN curl -L -o tacacs.tar.gz https://shrubbery.net/pub/tac_plus/tacacs-F4.0.4.31.tar.gz\
&& mkdir -p tac_plus\
&& tar -xvzf tacacs.tar.gz -C tac_plus\
&& cd tac_plus \
&& cd tacacs-F4.0.4.31 \
&& ./configure LDFLAGS="-Wl,-rpath=/usr/local/lib" \
&& make install \
&& ln -s /usr/local/sbin/tac_plus /usr/sbin/tac_plus \
&& ln -s /usr/local/bin/tac_pwd /usr/sbin/tac_pwd \
&& mkdir /etc/tacacs+ \
&& chmod 0755 /etc/tacacs+
COPY ["tacacs_plus", "/etc/init.d"]
COPY ["tacacs+", "/etc/default"]
{% endif %}

# Workaround: Tornado installed outside of the
# virtualenv as the call to the process API
# Ansible -> Supervisor -> ExaBGP -> Process API
# causes the process API to have a restricted
# environment without access to the virtualenv.
{% if PTF_ENV_PY_VER == "py3" %}
RUN pip3 install --break-system-packages tornado
{% endif %}


RUN python3 -m venv env-python3
# Activating a virtualenv. The virtualenv automatically works for RUN, ENV and CMD.
ENV VIRTUAL_ENV=/root/env-python3
ARG BACKUP_OF_PATH="$PATH"
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 PYTHONIOENCODING=UTF-8
{% endif %}

# Upgrade pip to address CVE vulnerabilities in older pip versions
RUN pip3 install --upgrade pip

{% if PTF_ENV_PY_VER == "mixed" %}
RUN python3 -m pip install --upgrade --ignore-installed pip
Expand Down Expand Up @@ -212,9 +270,17 @@ RUN pip3 install setuptools \
&& pip3 install six==1.16.0 \
&& pip3 install itsdangerous \
&& pip3 install retrying \
&& pip3 install jinja2 \
&& pip3 install scapy==2.5.0 \
&& pip3 install thrift
&& pip3 install jinja2

# gnxi/gnmi_cli_py ships pre-generated _pb2.py stubs; they are
# Pin to 6.33.5 to match grpcio-tools keep a known-good version.
RUN set -e; \
. /etc/os-release; \
if [ "$VERSION_CODENAME" = "bookworm" ]; then \
pip install protobuf==6.33.5; \
else \
pip install protobuf; \
fi

{% if docker_ptf_whls.strip() -%}
# Copy locally-built Python wheel dependencies
Expand All @@ -229,6 +295,9 @@ RUN pip3 install setuptools \
ENV PATH="$BACKUP_OF_PATH"
{% endif %}

# Ensure setuptools >= 70.0.0 to address GHSA-cx63-2mw6-8hw5
RUN pip3 install "setuptools>=70.0.0"

## Adjust sshd settings
RUN mkdir /var/run/sshd \
&& echo 'root:root' | chpasswd \
Expand All @@ -255,16 +324,58 @@ RUN git clone https://github.com/google/gnxi.git \

COPY gnxi-patches/ gnxi/patches/

{% if PTF_ENV_PY_VER == "mixed" %}
RUN cd gnxi \
&& quilt push -a \
&& cd gnmi_cli_py \
{% if PTF_ENV_PY_VER == "mixed" %}
&& pip install -r requirements.txt
&& pip install -r requirements.txt \
&& pip3 install protobuf==6.33.5 --no-binary=protobuf
{% else %}
&& cat requirements.txt | grep -v futures > /tmp/requirements.txt \
&& pip3 install -r /tmp/requirements.txt

# Since gnxi were generated with proto 3.x we need to regenerate _pb2 with the new proto version
RUN cd gnxi \
&& quilt push -a \
&& cd gnmi_cli_py \
&& wget -q -O gnmi_ext.proto https://raw.githubusercontent.com/openconfig/gnmi/master/proto/gnmi_ext/gnmi_ext.proto \
&& wget -q -O gnmi.proto https://raw.githubusercontent.com/openconfig/gnmi/master/proto/gnmi/gnmi.proto \
&& sed -i 's|github.com/openconfig/gnmi/proto/gnmi_ext/gnmi_ext.proto|gnmi_ext.proto|' gnmi.proto \
&& python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. gnmi_ext.proto gnmi.proto \
&& rm -f gnmi.proto gnmi_ext.proto
{% endif %}

# Deactivating a virtualenv.
# ENV PATH="$BACKUP_OF_PATH"

# Build gnoic from source with patched Go and golang.org/x/* deps
# upgraded to latest to address current and future golang.org/x/* CVEs.
RUN git clone https://github.com/karimra/gnoic.git \
&& cd gnoic \
&& git checkout 27bc5a6 \
&& go get google.golang.org/[email protected] \
&& go get github.com/go-viper/mapstructure/[email protected] \
&& go get golang.org/x/crypto@latest golang.org/x/net@latest golang.org/x/text@latest golang.org/x/sys@latest golang.org/x/oauth2@latest \
&& go mod tidy \
&& go build -o /usr/local/bin/gnoic . \
&& cd .. \
&& rm -rf gnoic

# Build gnmic from source with patched Go and upgraded deps
# to address CVE-2026-33186 (grpc), CVE-2025-8556/CVE-2026-1229 (circl),
# CVE-2026-25934 (go-git), CVE-2026-27571 (nats-server), CVE-2026-24051 (otel)
RUN GNMIC_VERSION=v0.43.0 \
&& git clone --depth 1 --branch "${GNMIC_VERSION}" https://github.com/openconfig/gnmic.git /tmp/gnmic \
&& cd /tmp/gnmic \
&& go get google.golang.org/[email protected] \
&& go get github.com/cloudflare/[email protected] \
&& go get github.com/go-git/go-git/[email protected] \
&& go get github.com/nats-io/nats-server/[email protected] \
&& go get go.opentelemetry.io/otel/[email protected] \
&& go get golang.org/x/crypto@latest golang.org/x/net@latest golang.org/x/text@latest golang.org/x/sys@latest golang.org/x/oauth2@latest \
&& go mod tidy \
&& go build -o /usr/local/bin/gnmic . \
&& chmod +x /usr/local/bin/gnmic \
&& rm -rf /tmp/gnmic

COPY \
{% for deb in docker_ptf_debs.split(' ') -%}
debs/{{ deb }}{{' '}}
Expand All @@ -276,6 +387,10 @@ RUN dpkg -i \
debs/{{ deb }}{{' '}}
{%- endfor %}

# Remove Go toolchain to reduce image size
RUN rm -rf /usr/local/go "$(go env GOPATH 2>/dev/null || echo $HOME/go)"
ENV PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

{% if PTF_ENV_PY_VER == "py3" %}
# Create symlink so that test scripts and ptf_runner invocation path
# is same across python 2 and python 3 envs. Note that for virtual-env
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ index dab2db6..e32b3ff 100644
-grpcio-tools==1.15.0
+grpcio==1.41.1
+grpcio-tools==1.41.1
protobuf==3.6.1 --no-binary=protobuf
protobuf==6.33.5 --no-binary=protobuf
six==1.12.0
--
2.48.1.windows.1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
From 82efb3e99dfffbb137858bce18a6acdec79c1e44 Mon Sep 17 00:00:00 2001
From: Austin Pham <[email protected]>
Date: Thu, 12 Mar 2026 09:57:50 +1100
Subject: [PATCH] chore: remove deprecated use_aliases field and fix syntax
warning is not

Signed-off-by: Austin Pham <[email protected]>
---
gnmi_cli_py/py_gnmicli.py | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/gnmi_cli_py/py_gnmicli.py b/gnmi_cli_py/py_gnmicli.py
index b7d1165..150239a 100644
--- a/gnmi_cli_py/py_gnmicli.py
+++ b/gnmi_cli_py/py_gnmicli.py
@@ -172,7 +172,6 @@ def _create_parser():
parser.add_argument('--subscribe_mode', default=0, type=int, help='[0=STREAM, 1=ONCE, 2=POLL]')
parser.add_argument('--encoding', default=0, type=int, help='[0=JSON, 1=BYTES, 2=PROTO, 3=ASCII, 4=JSON_IETF]')
parser.add_argument('--qos', default=0, type=int, help='')
- parser.add_argument('--use_alias', action='store_true', help='use alias')
parser.add_argument('--create_connections', type=int, nargs='?', const=1, default=1,
help='Creates specific number of TCP connections with gNMI server side. '
'Default number of TCP connections is 1 and use -1 to create '
@@ -489,7 +488,7 @@ def gen_request(paths, opt, prefix):
myqos = None
mysblist = gnmi_pb2.SubscriptionList(prefix=myprefix, mode=opt['subscribe_mode'],
allow_aggregation=opt['aggregate'], encoding=opt['encoding'],
- subscription=mysubs, use_aliases=opt['use_alias'], qos=myqos)
+ subscription=mysubs, qos=myqos)
mysubreq = gnmi_pb2.SubscribeRequest(subscribe=mysblist)

print('Sending SubscribeRequest\n'+str(mysubreq))
@@ -538,9 +537,9 @@ def subscribe_start(stub, options, req_iterator):
' received\n'+str(response.error.message) + str(response.error))
elif response.HasField('update'):
if filter_event_regex is not None:
- if filter_event_regex is not "":
+ if filter_event_regex != "":
match = check_event_response(response, filter_event_regex)
- if len(match) is not 0:
+ if len(match) != 0:
print(response)
update_count = update_count + 1
else:
--
2.34.1

1 change: 1 addition & 0 deletions dockers/docker-ptf/gnxi-patches/series
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
0005-Enhance-gnmi_cli_py-4.patch
0006-Add-support-for-extensive-configurations.patch
0007-Fix-py_gnmicli.py-POLL-mode.patch
0009-chore-remove-deprecated-use_aliases-field-and-fix-syntax.patch
11 changes: 11 additions & 0 deletions dockers/dockerfile-macros.j2
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,14 @@ COPY \
{%- endfor %}
{{ dest }}
{%- endmacro %}

{% macro install_offending_packages(packages) -%}
{%- for pkg in packages %}
RUN pip3 install {{ pkg }}
RUN pip3 install setuptools
{%- endfor %}
{%- endmacro %}

{% macro rsync_from_builder_stage() -%}
RUN --mount=type=bind,from=base,target=/changes-to-image rsync -axAX --omit-dir-times --no-D --exclude=/sys --exclude=/proc --exclude=/dev --exclude=resolv.conf /changes-to-image/ /
{%- endmacro %}
2 changes: 1 addition & 1 deletion rules/config
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ BUILD_REDUCE_IMAGE_SIZE = n

# SONIC_PTF_ENV_PY_VER - SONiC PTF test Python version. Set to 'mixed' to build the
# image with both Python 2 and 3. Set to 'py3' to build a Python 3 only image
SONIC_PTF_ENV_PY_VER = mixed
SONIC_PTF_ENV_PY_VER = py3

# Add timeout on some process which may hangs
BUILD_PROCESS_TIMEOUT ?= 0
Loading