From 2836570abd2c493f38a3ed81923059e170cef58e Mon Sep 17 00:00:00 2001 From: Travis Brown Date: Fri, 6 Feb 2026 12:03:45 -0800 Subject: [PATCH] [Nexthop] Add a Distro Image demo container example **Pre-submission checklist** - [X] I've ran the linters locally and fixed lint errors related to the files I modified in this PR. You can install the linters by running `pip install -r requirements-dev.txt && pre-commit install` - [X] `pre-commit run` This adds an example of an other_dependency which creates and runs a custom container. Here a simple clock service inside a container is added as this example. Add this to the image manifest: ``` "other_dependencies": [ { "execute": "examples/demo_container/build.sh" } ] ``` When the device boots, you can check the time: ``` [root@dut ~]# cat /var/clock/time.txt ________________________________________ | Current time is Thu Feb 5 18:34:43 2026 | ======================================== \ \ \ \ .-=-==--==--. ..-==" ,'o`) `. ,' `"' \ : ( `.__...._ | ) / `-=-. : ,vv.-._ / / `---==-._ \/\/\/VV ^ d88`;' / `. `` ^/d88P!' / , `._ ^/ !' ,. , / "-,,__,,--'""""-. ^/ !' ,' \ . .( ( _ ) ) ) ) ))_,-.\ ^(__ ,!',"' ;:+.:%:a. \:.. . ,' ) ) ) ) ,"' ' ',,,'',' /o:::":%:%a. \:.:.: . ) ) _,' """' ;':::'' `+%%%a._ \%:%| ;.). _,-"" ,-='_.-' ``:%::) )%:| /:._," (/(/" ," ,'_,'%%%: (_,' ( (//(`.___; \ \ \ ` ` `. `. `. : \. . .\ : . . . : \. . .: `.. . .: `..:.:\ \:...\ ;:.:.; ::...: ):%:: :::::; __,::%:( ::::: ,;:%%%%%%%: ;:%:: ;,--""-.`\ ,=--':%:%:\ /" "| /-".:%%%%%%%\ ;,-"'`)%%) /" "| [root@dut ~]# ``` --- fboss-image/examples/demo_container/README.md | 1 + fboss-image/examples/demo_container/build.sh | 13 +++++++ .../rpmbuild/SOURCES/Dockerfile | 9 +++++ .../rpmbuild/SOURCES/demo_container.service | 15 ++++++++ .../demo_container/rpmbuild/SOURCES/time.py | 10 ++++++ .../rpmbuild/SPECS/demo_container.spec | 35 +++++++++++++++++++ 6 files changed, 83 insertions(+) create mode 100644 fboss-image/examples/demo_container/README.md create mode 100755 fboss-image/examples/demo_container/build.sh create mode 100644 fboss-image/examples/demo_container/rpmbuild/SOURCES/Dockerfile create mode 100644 fboss-image/examples/demo_container/rpmbuild/SOURCES/demo_container.service create mode 100755 fboss-image/examples/demo_container/rpmbuild/SOURCES/time.py create mode 100644 fboss-image/examples/demo_container/rpmbuild/SPECS/demo_container.spec diff --git a/fboss-image/examples/demo_container/README.md b/fboss-image/examples/demo_container/README.md new file mode 100644 index 0000000000000..f6f4b6460a1ab --- /dev/null +++ b/fboss-image/examples/demo_container/README.md @@ -0,0 +1 @@ +This example shows how to build a docker container to be run on a device inside the Distro Image. diff --git a/fboss-image/examples/demo_container/build.sh b/fboss-image/examples/demo_container/build.sh new file mode 100755 index 0000000000000..1b1315f1cd9f3 --- /dev/null +++ b/fboss-image/examples/demo_container/build.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e + +dnf builddep -y --spec rpmbuild/SPECS/demo_container.spec + +rpmdir=$(pwd)/rpmbuild +mkdir -p ${rpmdir}/{RPMS,SRPMS,BUILD,BUILDROOT} + +rpmbuild -bb --define "_topdir ${rpmdir}" ${rpmdir}/SPECS/demo_container.spec + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" +mkdir -p ${SCRIPT_DIR}/dist +cp ${rpmdir}/RPMS/*/*.rpm ${SCRIPT_DIR}/dist diff --git a/fboss-image/examples/demo_container/rpmbuild/SOURCES/Dockerfile b/fboss-image/examples/demo_container/rpmbuild/SOURCES/Dockerfile new file mode 100644 index 0000000000000..cc5055677dd8c --- /dev/null +++ b/fboss-image/examples/demo_container/rpmbuild/SOURCES/Dockerfile @@ -0,0 +1,9 @@ +FROM python:alpine + +RUN mkdir /output + +RUN pip install cowsay + +COPY time.py /time.py + +CMD ["python", "/time.py"] diff --git a/fboss-image/examples/demo_container/rpmbuild/SOURCES/demo_container.service b/fboss-image/examples/demo_container/rpmbuild/SOURCES/demo_container.service new file mode 100644 index 0000000000000..3968f5a1c3697 --- /dev/null +++ b/fboss-image/examples/demo_container/rpmbuild/SOURCES/demo_container.service @@ -0,0 +1,15 @@ +# /usr/lib/systemd/system/demo_container.service +[Unit] +Description=Demo Container +After=network.target + +[Service] +Type=simple +Restart=on-failure +TimeoutStartSec=180s +TimeoutStopSec=10s +ExecStart=/usr/bin/docker run --rm --name demo_container -v /var/clock:/output --net none demo_container +ExecStop=/usr/bin/docker stop demo_container + +[Install] +WantedBy=multi-user.target diff --git a/fboss-image/examples/demo_container/rpmbuild/SOURCES/time.py b/fboss-image/examples/demo_container/rpmbuild/SOURCES/time.py new file mode 100755 index 0000000000000..4592adb2f6115 --- /dev/null +++ b/fboss-image/examples/demo_container/rpmbuild/SOURCES/time.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python3 +import cowsay +import time + +while True: + time.sleep(1) + + s = cowsay.get_output_string("trex", "Current time is " + time.ctime()) + "\n" + with open("/output/time.txt", "w") as f: + f.write(s) diff --git a/fboss-image/examples/demo_container/rpmbuild/SPECS/demo_container.spec b/fboss-image/examples/demo_container/rpmbuild/SPECS/demo_container.spec new file mode 100644 index 0000000000000..ee6df99028c5a --- /dev/null +++ b/fboss-image/examples/demo_container/rpmbuild/SPECS/demo_container.spec @@ -0,0 +1,35 @@ +Name: demo_container +Version: 1.0 +Release: 1 +Summary: Demo Container +License: GPL +BuildRequires: podman-docker +Requires: podman-docker + +%description +Demo building, installing, and running a container on a device inside the Distro Image. + +%prep +cp %{_sourcedir}/Dockerfile . +cp %{_sourcedir}/time.py . + +%build +docker build . -t demo_container +rm -f demo_container.tar +docker save demo_container -o demo_container.tar + +%install +%{__install} -D -m 644 demo_container.tar %{buildroot}/usr/share/demo_container/demo_container.tar +%{__install} -D -m 644 %{_sourcedir}/demo_container.service %{buildroot}/usr/lib/systemd/system/demo_container.service +mkdir -p %{buildroot}/var/clock + +%files +%defattr(-,root,root,-) +/var/clock +%config(missingok) /usr/share/demo_container/demo_container.tar +/usr/lib/systemd/system/demo_container.service + +%post +docker load -i /usr/share/demo_container/demo_container.tar +rm -rf /usr/share/demo_container +systemctl enable demo_container.service