build-unit-test-docker: convert to Python
Do a near identical conversion from bash to Python for the script which
builds the unit-test docker containers. I plan to do additional
enhancements to build the sub-containers in parallel, so I needed to
first do this conversion to Python in order to make that implementation
sane.
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I6df6f294b41f3a01f95fbe23a6dcd1ea21a315a9
diff --git a/build-unit-test-docker.sh b/build-unit-test-docker.sh
deleted file mode 100755
index 20ad2da..0000000
--- a/build-unit-test-docker.sh
+++ /dev/null
@@ -1,534 +0,0 @@
-#!/usr/bin/env bash
-#
-# Build the required docker image to run package unit tests
-#
-# Script Variables:
-# DOCKER_IMG_NAME: <optional, the name of the docker image to generate>
-# default is openbmc/ubuntu-unit-test
-# DISTRO: <optional, the distro to build a docker image against>
-# default is ubuntu:eoan
-# BRANCH: <optional, branch to build from each of the openbmc/
-# repositories>
-# default is master, which will be used if input branch not
-# provided or not found
-# UBUNTU_MIRROR: <optional, the URL of a mirror of Ubuntu to override the
-# default ones in /etc/apt/sources.list>
-# default is empty, and no mirror is used.
-# http_proxy The HTTP address of the proxy server to connect to.
-# Default: "", proxy is not setup if this is not set
-
-set -xeuo pipefail
-
-DOCKER_IMG_NAME=${DOCKER_IMG_NAME:-"openbmc/ubuntu-unit-test"}
-DISTRO=${DISTRO:-"ubuntu:focal"}
-BRANCH=${BRANCH:-"master"}
-UBUNTU_MIRROR=${UBUNTU_MIRROR:-""}
-http_proxy=${http_proxy:-}
-
-# Determine the architecture
-ARCH=$(uname -m)
-case ${ARCH} in
- "ppc64le")
- DOCKER_BASE="ppc64le/"
- ;;
- "x86_64")
- DOCKER_BASE=""
- ;;
- *)
- echo "Unsupported system architecture(${ARCH}) found for docker image"
- exit 1
-esac
-
-# Setup temporary files
-DEPCACHE_FILE=""
-cleanup() {
- local status="$?"
- if [[ -n "$DEPCACHE_FILE" ]]; then
- rm -f "$DEPCACHE_FILE"
- fi
- trap - EXIT ERR
- exit "$status"
-}
-trap cleanup EXIT ERR INT TERM QUIT
-DEPCACHE_FILE="$(mktemp)"
-
-HEAD_PKGS=(
- openbmc/phosphor-objmgr
- openbmc/sdbusplus
- openbmc/sdeventplus
- openbmc/stdplus
- openbmc/gpioplus
- openbmc/phosphor-logging
- openbmc/phosphor-dbus-interfaces
- open-power/pdbg
- openbmc/pldm
-)
-
-# Generate a list of depcache entries
-# We want to do this in parallel since the package list is growing
-# and the network lookup is low overhead but decently high latency.
-# This doesn't worry about producing a stable DEPCACHE_FILE, that is
-# done by readers who need a stable ordering.
-generate_depcache_entry() {
- local package="$1"
-
- local tip
- # Need to continue if branch not found, hence || true at end
- tip=$(git ls-remote --heads "https://github.com/${package}" |
- grep "refs/heads/$BRANCH" | awk '{ print $1 }' || true)
-
- # If specific branch is not found then try master
- if [[ -z "$tip" ]]; then
- tip=$(git ls-remote --heads "https://github.com/${package}" |
- grep "refs/heads/master" | awk '{ print $1 }')
- fi
-
- # Lock the file to avoid interlaced writes
- exec 3>> "$DEPCACHE_FILE"
- flock 3
- echo "$package:$tip" >&3
- exec 3>&-
-}
-for package in "${HEAD_PKGS[@]}"; do
- generate_depcache_entry "$package" &
-done
-wait
-
-# A list of package versions we are building
-# Start off by listing the stating versions of third-party sources
-declare -A PKG_REV=(
- [boost]=1.75.0
- [cereal]=v1.3.0
- [catch2]=v2.12.2
- [CLI11]=v1.9.0
- [fmt]=6.2.1
- # Snapshot from 2020-01-03
- [function2]=3a0746bf5f601dfed05330aefcb6854354fce07d
- # Snapshot from 2020-02-13
- [googletest]=23b2a3b1cf803999fb38175f6e9e038a4495c8a5
- # Release 2020-08-06
- [json]=v3.9.1
- # Snapshot from 2019-05-24
- [lcov]=75fbae1cfc5027f818a0bb865bf6f96fab3202da
- # dev-5.0 2019-05-03
- [linux-headers]=8bf6567e77f7aa68975b7c9c6d044bba690bf327
- # Snapshot from 2019-09-03
- [libvncserver]=1354f7f1bb6962dab209eddb9d6aac1f03408110
- [span-lite]=v0.7.0
- # version from meta-openembedded/meta-oe/recipes-support/libtinyxml2/libtinyxml2_5.0.1.bb
- [tinyxml2]=37bc3aca429f0164adf68c23444540b4a24b5778
- # version from /meta-openembedded/meta-oe/recipes-devtools/boost-url/boost-url_git.bb
- [boost-url]=a56ae0df6d3078319755fbaa67822b4fa7fd352b
- # version from meta-openembedded/meta-oe/recipes-devtools/valijson/valijson_git.bb
- [valijson]=c2f22fddf599d04dc33fcd7ed257c698a05345d9
- # version from meta-openembedded/meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo_git.bb
- [fifo_map]=0dfbf5dacbb15a32c43f912a7e66a54aae39d0f9
-)
-
-# Turn the depcache into a dictionary so we can reference the HEAD of each repo
-while IFS= read -r line; do
- # shellcheck disable=SC2207 # Expecting to word-split tr results.
- linearr=($(echo "$line" | tr ':' ' '))
- PKG_REV["${linearr[0]}"]="${linearr[1]}"
-done < "$DEPCACHE_FILE"
-
-# Define common flags used for builds
-PREFIX="/usr/local"
-CONFIGURE_FLAGS=(
- "--prefix=${PREFIX}"
-)
-CMAKE_FLAGS=(
- "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
- "-DBUILD_SHARED_LIBS=ON"
- "-DCMAKE_INSTALL_PREFIX:PATH=${PREFIX}"
-)
-MESON_FLAGS=(
- "--wrap-mode=nodownload"
- "-Dprefix=${PREFIX}"
-)
-
-stagename()
-{
- local cooked="$1"
-
- if ! echo "$cooked" | grep -q '/'
- then
- cooked=openbmc-"$cooked"
- fi
- echo "$cooked" | tr '/' '-'
-}
-
-# Build the commands needed to compose our final image
-COPY_CMDS=""
-# We must sort the packages, otherwise we might produce an unstable
-# docker file and rebuild the image unnecessarily
-for pkg in $(echo "${!PKG_REV[@]}" | tr ' ' '\n' | LC_COLLATE=C sort -s); do
- COPY_CMDS+="COPY --from=$(stagename "${pkg}") ${PREFIX} ${PREFIX}"$'\n'
- # Workaround for upstream docker bug and multiple COPY cmds
- # https://github.com/moby/moby/issues/37965
- COPY_CMDS+="RUN true"$'\n'
-done
-
-################################# docker img # #################################
-# Create docker image that can run package unit tests
-if [[ "${DISTRO}" == "ubuntu"* ]]; then
-
-MIRROR=""
-if [[ -n "${UBUNTU_MIRROR}" ]]; then
- MIRROR="RUN echo \"deb ${UBUNTU_MIRROR} \$(. /etc/os-release && echo \$VERSION_CODENAME) main restricted universe multiverse\" > /etc/apt/sources.list && \
- echo \"deb ${UBUNTU_MIRROR} \$(. /etc/os-release && echo \$VERSION_CODENAME)-updates main restricted universe multiverse\" >> /etc/apt/sources.list && \
- echo \"deb ${UBUNTU_MIRROR} \$(. /etc/os-release && echo \$VERSION_CODENAME)-security main restricted universe multiverse\" >> /etc/apt/sources.list && \
- echo \"deb ${UBUNTU_MIRROR} \$(. /etc/os-release && echo \$VERSION_CODENAME)-proposed main restricted universe multiverse\" >> /etc/apt/sources.list && \
- echo \"deb ${UBUNTU_MIRROR} \$(. /etc/os-release && echo \$VERSION_CODENAME)-backports main restricted universe multiverse\" >> /etc/apt/sources.list"
-
-fi
-
-PROXY_CMD=""
-if [[ -n "${http_proxy}" ]]; then
- PROXY_CMD="RUN echo \"[http]\" > \$HOME/.gitconfig && \
- echo \"proxy = ${http_proxy}\" >> \$HOME/.gitconfig"
-fi
-
-Dockerfile=$(cat << EOF
-FROM ${DOCKER_BASE}${DISTRO} as openbmc-base
-
-${MIRROR}
-
-ENV DEBIAN_FRONTEND noninteractive
-
-ENV PYTHONPATH "/usr/local/lib/python3.8/site-packages/"
-
-# We need the keys to be imported for dbgsym repos
-# New releases have a package, older ones fall back to manual fetching
-# https://wiki.ubuntu.com/Debug%20Symbol%20Packages
-RUN apt-get update && ( apt-get install ubuntu-dbgsym-keyring || ( apt-get install -yy dirmngr && \
- apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F2EDC64DC5AEE1F6B9C621F0C8CAB6595FDFF622 ) )
-
-# Parse the current repo list into a debug repo list
-RUN sed -n '/^deb /s,^deb [^ ]* ,deb http://ddebs.ubuntu.com ,p' /etc/apt/sources.list >/etc/apt/sources.list.d/debug.list
-
-# Remove non-existent debug repos
-RUN sed -i '/-\(backports\|security\) /d' /etc/apt/sources.list.d/debug.list
-
-RUN cat /etc/apt/sources.list.d/debug.list
-
-RUN apt-get update && apt-get dist-upgrade -yy && apt-get install -yy \
- gcc-10 \
- g++-10 \
- libc6-dbg \
- libc6-dev \
- libtool \
- bison \
- libdbus-1-dev \
- flex \
- cmake \
- python3 \
- python3-dev\
- python3-yaml \
- python3-mako \
- python3-pip \
- python3-setuptools \
- python3-git \
- python3-socks \
- pkg-config \
- autoconf \
- autoconf-archive \
- libsystemd-dev \
- systemd \
- libssl-dev \
- libevdev-dev \
- libevdev2-dbgsym \
- libjpeg-dev \
- libpng-dev \
- ninja-build \
- sudo \
- curl \
- git \
- dbus \
- iputils-ping \
- clang-10 \
- clang-format-10 \
- clang-tidy-10 \
- clang-tools-10 \
- shellcheck \
- npm \
- iproute2 \
- libnl-3-dev \
- libnl-genl-3-dev \
- libconfig++-dev \
- libsnmp-dev \
- valgrind \
- valgrind-dbg \
- libpam0g-dev \
- xxd \
- libi2c-dev \
- wget \
- libldap2-dev \
- libprotobuf-dev \
- libperlio-gzip-perl \
- libjson-perl \
- protobuf-compiler \
- libgpiod-dev \
- device-tree-compiler \
- cppcheck \
- libpciaccess-dev \
- libmimetic-dev \
- libxml2-utils \
- libxml-simple-perl
-
-RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 1000 \
- --slave /usr/bin/g++ g++ /usr/bin/g++-10 \
- --slave /usr/bin/gcov gcov /usr/bin/gcov-10 \
- --slave /usr/bin/gcov-dump gcov-dump /usr/bin/gcov-dump-10 \
- --slave /usr/bin/gcov-tool gcov-tool /usr/bin/gcov-tool-10
-
-
-RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-10 1000 \
- --slave /usr/bin/clang++ clang++ /usr/bin/clang++-10 \
- --slave /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-10 \
- --slave /usr/bin/clang-format clang-format /usr/bin/clang-format-10 \
- --slave /usr/bin/run-clang-tidy.py run-clang-tidy.py /usr/bin/run-clang-tidy-10.py
-
-RUN pip3 install inflection
-RUN pip3 install pycodestyle
-RUN pip3 install jsonschema
-RUN pip3 install meson==0.54.3
-RUN pip3 install protobuf
-
-FROM openbmc-base as openbmc-lcov
-RUN curl -L https://github.com/linux-test-project/lcov/archive/${PKG_REV['lcov']}.tar.gz | tar -xz && \
-cd lcov-* && \
-make -j$(nproc) && \
-make install
-
-FROM openbmc-base as openbmc-function2
-RUN mkdir ${PREFIX}/include/function2 && \
-curl -L -o ${PREFIX}/include/function2/function2.hpp https://raw.githubusercontent.com/Naios/function2/${PKG_REV['function2']}/include/function2/function2.hpp
-
-FROM openbmc-base as openbmc-googletest
-RUN curl -L https://github.com/google/googletest/archive/${PKG_REV['googletest']}.tar.gz | tar -xz && \
-cd googletest-* && \
-mkdir build && \
-cd build && \
-CXXFLAGS=-std=c++17 cmake ${CMAKE_FLAGS[@]} -DTHREADS_PREFER_PTHREAD_FLAG=ON .. && \
-make -j$(nproc) && \
-make install
-
-FROM openbmc-base as openbmc-catch2
-RUN curl -L https://github.com/catchorg/Catch2/archive/${PKG_REV['catch2']}.tar.gz | tar -xz && \
-cd Catch2-* && \
-mkdir build && \
-cd build && \
-cmake ${CMAKE_FLAGS[@]} -DBUILD_TESTING=OFF -DCATCH_INSTALL_DOCS=OFF .. && \
-make -j$(nproc) && \
-make install
-
-FROM openbmc-base as openbmc-cereal
-RUN curl -L https://github.com/USCiLab/cereal/archive/${PKG_REV['cereal']}.tar.gz | tar -xz && \
-cp -a cereal-*/include/cereal/ ${PREFIX}/include/
-
-FROM openbmc-base as openbmc-CLI11
-RUN curl -L https://github.com/CLIUtils/CLI11/archive/${PKG_REV['CLI11']}.tar.gz | tar -xz && \
-cd CLI11-* && \
-mkdir build && \
-cd build && \
-cmake ${CMAKE_FLAGS[@]} -DCLI11_BUILD_DOCS=OFF -DBUILD_TESTING=OFF -DCLI11_BUILD_EXAMPLES=OFF .. && \
-make -j$(nproc) && \
-make install
-
-FROM openbmc-base as openbmc-fmt
-RUN curl -L https://github.com/fmtlib/fmt/archive/${PKG_REV['fmt']}.tar.gz | tar -xz && \
-cd fmt-* && \
-mkdir build && \
-cd build && \
-cmake ${CMAKE_FLAGS[@]} -DFMT_DOC=OFF -DFMT_TEST=OFF .. && \
-make -j$(nproc) && \
-make install
-
-FROM openbmc-base as openbmc-json
-RUN mkdir ${PREFIX}/include/nlohmann/ && \
-curl -L -o ${PREFIX}/include/nlohmann/json.hpp https://github.com/nlohmann/json/releases/download/${PKG_REV['json']}/json.hpp && \
-ln -s nlohmann/json.hpp ${PREFIX}/include/json.hpp
-
-FROM openbmc-base as openbmc-fifo_map
-RUN curl -L https://github.com/nlohmann/fifo_map/archive/${PKG_REV['fifo_map']}.tar.gz | tar -xz && \
-cd fifo_map-*/src && cp fifo_map.hpp ${PREFIX}/include/
-
-FROM openbmc-base as openbmc-span-lite
-RUN curl -L https://github.com/martinmoene/span-lite/archive/${PKG_REV['span-lite']}.tar.gz | tar -xz && \
-cd span-lite-* && \
-mkdir build && \
-cd build && \
-cmake ${CMAKE_FLAGS[@]} -DSPAN_LITE_OPT_BUILD_TESTS=OFF .. && \
-make -j$(nproc) && \
-make install
-
-FROM openbmc-base as openbmc-linux-headers
-RUN curl -L https://github.com/openbmc/linux/archive/${PKG_REV['linux-headers']}.tar.gz | tar -xz && \
-cd linux-* && \
-make -j$(nproc) defconfig && \
-make INSTALL_HDR_PATH=/usr/local headers_install
-
-FROM openbmc-base as openbmc-boost
-RUN curl -L https://dl.bintray.com/boostorg/release/${PKG_REV['boost']}/source/boost_$(echo "${PKG_REV['boost']}" | tr '.' '_').tar.bz2 | tar -xj && \
-cd boost_*/ && \
-./bootstrap.sh --prefix=${PREFIX} --with-libraries=context,coroutine && \
-./b2 && ./b2 install --prefix=${PREFIX}
-
-FROM openbmc-base as openbmc-tinyxml2
-RUN curl -L https://github.com/leethomason/tinyxml2/archive/${PKG_REV['tinyxml2']}.tar.gz | tar -xz && \
-cd tinyxml2-* && \
-mkdir build && \
-cd build && \
-cmake ${CMAKE_FLAGS[@]} .. && \
-make -j$(nproc) && \
-make install
-
-FROM openbmc-base as openbmc-boost-url
-RUN curl -L https://github.com/CPPAlliance/url/archive/${PKG_REV['boost-url']}.tar.gz | tar -xz && \
-cd url-* && \
-mkdir buildir && \
-cd buildir && \
-cmake ${CMAKE_FLAGS[@]} -DBOOST_URL_STANDALONE=ON -DBOOST_URL_BUILD_TESTS=OFF -DBOOST_URL_BUILD_EXAMPLES=OFF .. && \
-make -j$(nproc) && \
-make install
-
-FROM openbmc-base as openbmc-valijson
-RUN curl -L https://github.com/tristanpenman/valijson/archive/${PKG_REV['valijson']}.tar.gz | tar -xz && \
-cd valijson-* && \
-mkdir build && \
-cd build && \
-cmake ${CMAKE_FLAGS[@]} -DINSTALL_HEADERS=1 -DBUILD_TESTS=0 .. && \
-make -j$(nproc) && \
-make install
-
-FROM openbmc-base as openbmc-libvncserver
-RUN curl -L https://github.com/LibVNC/libvncserver/archive/${PKG_REV['libvncserver']}.tar.gz | tar -xz && \
-cd libvncserver-* && \
-mkdir build && \
-cd build && \
-cmake ${CMAKE_FLAGS[@]} .. && \
-make -j$(nproc) && \
-make install
-
-FROM openbmc-base as openbmc-stdplus
-COPY --from=openbmc-fmt ${PREFIX} ${PREFIX}
-COPY --from=openbmc-span-lite ${PREFIX} ${PREFIX}
-RUN curl -L https://github.com/openbmc/stdplus/archive/${PKG_REV['openbmc/stdplus']}.tar.gz | tar -xz && \
-cd stdplus-* && \
-meson build ${MESON_FLAGS[@]} -Dtests=disabled -Dexamples=false && \
-ninja -C build && \
-ninja -C build install
-
-FROM openbmc-base as openbmc-sdbusplus
-RUN curl -L https://github.com/openbmc/sdbusplus/archive/${PKG_REV['openbmc/sdbusplus']}.tar.gz | tar -xz && \
-cd sdbusplus-* && \
-cd tools && ./setup.py install --root=/ --prefix=${PREFIX} && \
-cd .. && meson build ${MESON_FLAGS[@]} -Dtests=disabled -Dexamples=disabled && \
-ninja -C build && \
-ninja -C build install
-
-FROM openbmc-base as openbmc-sdeventplus
-COPY --from=openbmc-function2 ${PREFIX} ${PREFIX}
-COPY --from=openbmc-stdplus ${PREFIX} ${PREFIX}
-RUN curl -L https://github.com/openbmc/sdeventplus/archive/${PKG_REV['openbmc/sdeventplus']}.tar.gz | tar -xz && \
-cd sdeventplus-* && \
-meson build ${MESON_FLAGS[@]} -Dtests=disabled -Dexamples=false && \
-ninja -C build && \
-ninja -C build install
-
-FROM openbmc-base as openbmc-gpioplus
-COPY --from=openbmc-stdplus ${PREFIX} ${PREFIX}
-RUN curl -L https://github.com/openbmc/gpioplus/archive/${PKG_REV['openbmc/gpioplus']}.tar.gz | tar -xz && \
-cd gpioplus-* && \
-meson build ${MESON_FLAGS[@]} -Dtests=disabled -Dexamples=false && \
-ninja -C build && \
-ninja -C build install
-
-FROM openbmc-base as openbmc-phosphor-dbus-interfaces
-COPY --from=openbmc-sdbusplus ${PREFIX} ${PREFIX}
-RUN curl -L https://github.com/openbmc/phosphor-dbus-interfaces/archive/${PKG_REV['openbmc/phosphor-dbus-interfaces']}.tar.gz | tar -xz && \
-cd phosphor-dbus-interfaces-* && \
-meson build ${MESON_FLAGS[@]} -Ddata_org_open_power=true -Ddata_com_ibm=true && \
-ninja -C build && \
-ninja -C build install
-
-FROM openbmc-base as openbmc-phosphor-logging
-COPY --from=openbmc-cereal ${PREFIX} ${PREFIX}
-COPY --from=openbmc-sdbusplus ${PREFIX} ${PREFIX}
-COPY --from=openbmc-sdeventplus ${PREFIX} ${PREFIX}
-COPY --from=openbmc-phosphor-dbus-interfaces ${PREFIX} ${PREFIX}
-COPY --from=openbmc-fifo_map ${PREFIX} ${PREFIX}
-RUN curl -L https://github.com/openbmc/phosphor-logging/archive/${PKG_REV['openbmc/phosphor-logging']}.tar.gz | tar -xz && \
-cd phosphor-logging-* && \
-./bootstrap.sh && \
-./configure ${CONFIGURE_FLAGS[@]} --enable-metadata-processing YAML_DIR=${PREFIX}/share/phosphor-dbus-yaml/yaml && \
-make -j$(nproc) && \
-make install
-
-FROM openbmc-base as openbmc-phosphor-objmgr
-COPY --from=openbmc-boost ${PREFIX} ${PREFIX}
-COPY --from=openbmc-sdbusplus ${PREFIX} ${PREFIX}
-COPY --from=openbmc-tinyxml2 ${PREFIX} ${PREFIX}
-COPY --from=openbmc-phosphor-logging ${PREFIX} ${PREFIX}
-RUN curl -L https://github.com/openbmc/phosphor-objmgr/archive/${PKG_REV['openbmc/phosphor-objmgr']}.tar.gz | tar -xz && \
-cd phosphor-objmgr-* && \
-./bootstrap.sh && \
-./configure ${CONFIGURE_FLAGS[@]} && \
-make -j$(nproc) && \
-make install
-
-FROM openbmc-base as open-power-pdbg
-RUN curl -L https://github.com/open-power/pdbg/archive/${PKG_REV['open-power/pdbg']}.tar.gz | tar -xz && \
-cd pdbg-* && \
-./bootstrap.sh && \
-./configure ${CONFIGURE_FLAGS[@]} && \
-make -j$(nproc) && \
-make install
-
-FROM openbmc-base as openbmc-pldm
-COPY --from=openbmc-sdbusplus ${PREFIX} ${PREFIX}
-COPY --from=openbmc-sdeventplus ${PREFIX} ${PREFIX}
-COPY --from=openbmc-boost ${PREFIX} ${PREFIX}
-COPY --from=openbmc-phosphor-dbus-interfaces ${PREFIX} ${PREFIX}
-COPY --from=openbmc-phosphor-logging ${PREFIX} ${PREFIX}
-COPY --from=openbmc-json ${PREFIX} ${PREFIX}
-COPY --from=openbmc-CLI11 ${PREFIX} ${PREFIX}
-RUN curl -L https://github.com/openbmc/pldm/archive/${PKG_REV['openbmc/pldm']}.tar.gz | tar -xz && \
-cd pldm-* && \
-meson build ${MESON_FLAGS[@]} -Dlibpldm-only=enabled -Doem-ibm=enabled -Dtests=disabled && \
-ninja -C build && \
-ninja -C build install
-
-# Build the final output image
-FROM openbmc-base
-${COPY_CMDS}
-
-# Some of our infrastructure still relies on the presence of this file
-# even though it is no longer needed to rebuild the docker environment
-# NOTE: The file is sorted to ensure the ordering is stable.
-RUN echo '$(LC_COLLATE=C sort -s "$DEPCACHE_FILE" | tr '\n' ',')' > /tmp/depcache
-
-# Final configuration for the workspace
-RUN grep -q ${GROUPS[0]} /etc/group || groupadd -g ${GROUPS[0]} ${USER}
-RUN mkdir -p "$(dirname "${HOME}")"
-RUN grep -q ${UID} /etc/passwd || useradd -d ${HOME} -m -u ${UID} -g ${GROUPS[0]} ${USER}
-RUN sed -i '1iDefaults umask=000' /etc/sudoers
-RUN echo "${USER} ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers
-
-${PROXY_CMD}
-
-RUN /bin/bash
-EOF
-)
-fi
-################################# docker img # #################################
-
-proxy_args=""
-if [[ -n "${http_proxy}" ]]; then
- proxy_args="--build-arg http_proxy=${http_proxy} --build-arg https_proxy=${http_proxy}"
-fi
-
-# Build above image
-# shellcheck disable=SC2086 # proxy_args requires word splitting.
-docker build ${proxy_args} --network=host -t "${DOCKER_IMG_NAME}" - <<< "${Dockerfile}"
diff --git a/jenkins/run-build-script-ci b/jenkins/run-build-script-ci
index 2c60164..3181b80 100755
--- a/jenkins/run-build-script-ci
+++ b/jenkins/run-build-script-ci
@@ -9,8 +9,8 @@
export LANG=en_US.UTF8
-cd ${WORKSPACE}/openbmc-build-scripts
+cd "${WORKSPACE}"/openbmc-build-scripts
# Now run some of our most used CI scripts
-./build-unit-test-docker.sh
+./scripts/build-unit-test-docker
./scripts/build-qemu-robot-docker.sh
diff --git a/run-unit-test-docker.sh b/run-unit-test-docker.sh
index 40e1a51..696b6b8 100755
--- a/run-unit-test-docker.sh
+++ b/run-unit-test-docker.sh
@@ -85,12 +85,12 @@
# Configure docker build
cd "${WORKSPACE}"/${OBMC_BUILD_SCRIPTS}
-echo "Building docker image with build-unit-test-docker.sh"
+echo "Building docker image with build-unit-test-docker"
# Export input env variables
export DOCKER_IMG_NAME
export DISTRO
export BRANCH
-./build-unit-test-docker.sh
+./scripts/build-unit-test-docker
# Allow the user to pass options through to unit-test.py:
# EXTRA_UNIT_TEST_ARGS="-r 100" ...
diff --git a/scripts/build-unit-test-docker b/scripts/build-unit-test-docker
new file mode 100755
index 0000000..94baa67
--- /dev/null
+++ b/scripts/build-unit-test-docker
@@ -0,0 +1,520 @@
+#!/usr/bin/env python3
+#
+# Build the required docker image to run package unit tests
+#
+# Script Variables:
+# DOCKER_IMG_NAME: <optional, the name of the docker image to generate>
+# default is openbmc/ubuntu-unit-test
+# DISTRO: <optional, the distro to build a docker image against>
+# default is ubuntu:eoan
+# BRANCH: <optional, branch to build from each of the openbmc/
+# repositories>
+# default is master, which will be used if input branch not
+# provided or not found
+# UBUNTU_MIRROR: <optional, the URL of a mirror of Ubuntu to override the
+# default ones in /etc/apt/sources.list>
+# default is empty, and no mirror is used.
+# http_proxy The HTTP address of the proxy server to connect to.
+# Default: "", proxy is not setup if this is not set
+
+import os
+import sys
+from sh import docker, git, nproc, uname
+
+# Read a bunch of environment variables.
+docker_image_name = os.environ.get("DOCKER_IMAGE_NAME", "openbmc/ubuntu-unit-test")
+distro = os.environ.get("DISTRO", "ubuntu:focal")
+branch = os.environ.get("BRANCH", "master")
+ubuntu_mirror = os.environ.get("UBUNTU_MIRROR")
+http_proxy = os.environ.get("http_proxy")
+
+# Set up some common variables.
+proc_count = nproc().strip()
+username = os.environ.get("USER")
+homedir = os.environ.get("HOME")
+gid = os.getgid()
+uid = os.getuid()
+
+# Determine the architecture for Docker.
+arch = uname("-m").strip()
+if arch == "ppc64le":
+ docker_base = "ppc64le/"
+elif arch == "x86_64":
+ docker_base = ""
+else:
+ print(f"Unsupported system architecture({arch}) found for docker image")
+ sys.exit(1)
+
+# These packages we use 'HEAD' for.
+head_pkgs = [
+ "openbmc/phosphor-objmgr",
+ "openbmc/sdbusplus",
+ "openbmc/sdeventplus",
+ "openbmc/stdplus",
+ "openbmc/gpioplus",
+ "openbmc/phosphor-logging",
+ "openbmc/phosphor-dbus-interfaces",
+ "open-power/pdbg",
+ "openbmc/pldm",
+]
+
+# Packages with fixed revisions.
+pkg_rev = {
+ "boost": "1.74.0",
+ "cereal": "v1.3.0",
+ "catch2": "v2.12.2",
+ "CLI11": "v1.9.0",
+ "fmt": "6.2.1",
+ # Snapshot from 2020-01-03
+ "function2": "3a0746bf5f601dfed05330aefcb6854354fce07d",
+ # Snapshot from 2020-02-13
+ "googletest": "23b2a3b1cf803999fb38175f6e9e038a4495c8a5",
+ # Release 2020-08-06
+ "json": "v3.9.1",
+ # Snapshot from 2019-05-24
+ "lcov": "75fbae1cfc5027f818a0bb865bf6f96fab3202da",
+ # dev-5.0 2019-05-03
+ "linux-headers": "8bf6567e77f7aa68975b7c9c6d044bba690bf327",
+ # Snapshot from 2019-09-03
+ "libvncserver": "1354f7f1bb6962dab209eddb9d6aac1f03408110",
+ "span-lite": "v0.7.0",
+ # version from meta-openembedded/meta-oe/recipes-support/libtinyxml2/libtinyxml2_5.0.1.bb
+ "tinyxml2": "37bc3aca429f0164adf68c23444540b4a24b5778",
+ # version from /meta-openembedded/meta-oe/recipes-devtools/boost-url/boost-url_git.bb
+ "boost-url": "a56ae0df6d3078319755fbaa67822b4fa7fd352b",
+ # version from meta-openembedded/meta-oe/recipes-devtools/valijson/valijson_git.bb
+ "valijson": "c2f22fddf599d04dc33fcd7ed257c698a05345d9",
+ # version from meta-openembedded/meta-oe/recipes-devtools/nlohmann-fifo/nlohmann-fifo_git.bb
+ "fifo_map": "0dfbf5dacbb15a32c43f912a7e66a54aae39d0f9",
+}
+
+# Look up the HEAD for 'head_pkgs' and insert them into 'pkg_rev'.
+pkg_lookups = {}
+for pkg in head_pkgs:
+ pkg_lookups[pkg] = git(
+ "ls-remote", "--heads", f"https://github.com/{pkg}", _bg=True
+ )
+for pkg, result in pkg_lookups.items():
+ for line in result.stdout.decode().split("\n"):
+ if f"refs/heads/{branch}" in line:
+ pkg_rev[pkg] = line.strip().split()[0]
+ elif "refs/heads/master" in line and p not in pkg_rev:
+ pkg_rev[pkg] = line.strip().split()[0]
+
+# Create the contents of the '/tmp/depcache'.
+# This needs to be sorted for consistency.
+depcache = ""
+for pkg in sorted(head_pkgs):
+ if pkg in pkg_rev:
+ depcache += "%s:%s," % (pkg, pkg_rev[pkg])
+
+# Define common flags used for builds
+prefix = "/usr/local"
+configure_flags = " ".join(
+ [
+ f"--prefix={prefix}",
+ ]
+)
+cmake_flags = " ".join(
+ [
+ "-DCMAKE_BUILD_TYPE=RelWithDebInfo",
+ "-DBUILD_SHARED_LIBS=ON",
+ f"-DCMAKE_INSTALL_PREFIX:PATH={prefix}",
+ ]
+)
+meson_flags = " ".join(
+ [
+ "--wrap-mode=nodownload",
+ f"-Dprefix={prefix}",
+ ]
+)
+
+
+def stagename(name):
+ if not name.startswith("openbmc/"):
+ name = "openbmc/" + name
+ return name.replace("/", "-")
+
+
+# Build the commands needed to compose our final image
+# We must sort the packages, otherwise we might produce an unstable
+# docker file and rebuild the image unnecessarily
+copy_cmds = ""
+for pkg in sorted(pkg_rev.keys()):
+ copy_cmds += f"COPY --from={stagename(pkg)} {prefix} {prefix}\n"
+ # Workaround for upstream docker bug and multiple COPY cmds
+ # https://github.com/moby/moby/issues/37965
+ copy_cmds += "RUN true\n"
+
+# Special flags if setting up a deb mirror.
+mirror = ""
+if "ubuntu" in distro and ubuntu_mirror:
+ mirror = f"""
+RUN echo "deb {ubuntu_mirror} $(. /etc/os-release && echo $VERSION_CODENAME) main restricted universe multiverse" > /etc/apt/sources.list && \\
+ echo "deb {ubuntu_mirror} $(. /etc/os-release && echo $VERSION_CODENAME)-updates main restricted universe multiverse" >> /etc/apt/sources.list && \\
+ echo "deb {ubuntu_mirror} $(. /etc/os-release && echo $VERSION_CODENAME)-security main restricted universe multiverse" >> /etc/apt/sources.list && \\
+ echo "deb {ubuntu_mirror} $(. /etc/os-release && echo $VERSION_CODENAME)-proposed main restricted universe multiverse" >> /etc/apt/sources.list && \\
+ echo "deb {ubuntu_mirror} $(. /etc/os-release && echo $VERSION_CODENAME)-backports main restricted universe multiverse" >> /etc/apt/sources.list
+"""
+
+# Special flags for proxying.
+proxy_cmd = ""
+proxy_args = []
+if http_proxy:
+ proxy_cmd = f"""
+RUN echo "[http]" >> {homedir}/.gitconfig && \
+ echo "proxy = {http_proxy}" >> {homedir}/.gitconfig
+"""
+ proxy_args.extend(
+ [
+ "--build-arg",
+ f"http_proxy={http_proxy}",
+ "--build-arg",
+ "https_proxy={https_proxy}",
+ ]
+ )
+
+# Create docker image that can run package unit tests
+dockerfile = f"""
+FROM {docker_base}{distro} as openbmc-base
+
+{mirror}
+
+ENV DEBIAN_FRONTEND noninteractive
+
+ENV PYTHONPATH "/usr/local/lib/python3.8/site-packages/"
+
+# We need the keys to be imported for dbgsym repos
+# New releases have a package, older ones fall back to manual fetching
+# https://wiki.ubuntu.com/Debug%20Symbol%20Packages
+RUN apt-get update && ( apt-get install ubuntu-dbgsym-keyring || ( apt-get install -yy dirmngr && \
+ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F2EDC64DC5AEE1F6B9C621F0C8CAB6595FDFF622 ) )
+
+# Parse the current repo list into a debug repo list
+RUN sed -n '/^deb /s,^deb [^ ]* ,deb http://ddebs.ubuntu.com ,p' /etc/apt/sources.list >/etc/apt/sources.list.d/debug.list
+
+# Remove non-existent debug repos
+RUN sed -i '/-\(backports\|security\) /d' /etc/apt/sources.list.d/debug.list
+
+RUN cat /etc/apt/sources.list.d/debug.list
+
+RUN apt-get update && apt-get dist-upgrade -yy && apt-get install -yy \
+ gcc-10 \
+ g++-10 \
+ libc6-dbg \
+ libc6-dev \
+ libtool \
+ bison \
+ libdbus-1-dev \
+ flex \
+ cmake \
+ python3 \
+ python3-dev\
+ python3-yaml \
+ python3-mako \
+ python3-pip \
+ python3-setuptools \
+ python3-git \
+ python3-socks \
+ pkg-config \
+ autoconf \
+ autoconf-archive \
+ libsystemd-dev \
+ systemd \
+ libssl-dev \
+ libevdev-dev \
+ libevdev2-dbgsym \
+ libjpeg-dev \
+ libpng-dev \
+ ninja-build \
+ sudo \
+ curl \
+ git \
+ dbus \
+ iputils-ping \
+ clang-10 \
+ clang-format-10 \
+ clang-tidy-10 \
+ clang-tools-10 \
+ shellcheck \
+ npm \
+ iproute2 \
+ libnl-3-dev \
+ libnl-genl-3-dev \
+ libconfig++-dev \
+ libsnmp-dev \
+ valgrind \
+ valgrind-dbg \
+ libpam0g-dev \
+ xxd \
+ libi2c-dev \
+ wget \
+ libldap2-dev \
+ libprotobuf-dev \
+ libperlio-gzip-perl \
+ libjson-perl \
+ protobuf-compiler \
+ libgpiod-dev \
+ device-tree-compiler \
+ cppcheck \
+ libpciaccess-dev \
+ libmimetic-dev \
+ libxml2-utils \
+ libxml-simple-perl
+
+RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 1000 \
+ --slave /usr/bin/g++ g++ /usr/bin/g++-10 \
+ --slave /usr/bin/gcov gcov /usr/bin/gcov-10 \
+ --slave /usr/bin/gcov-dump gcov-dump /usr/bin/gcov-dump-10 \
+ --slave /usr/bin/gcov-tool gcov-tool /usr/bin/gcov-tool-10
+
+
+RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-10 1000 \
+ --slave /usr/bin/clang++ clang++ /usr/bin/clang++-10 \
+ --slave /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-10 \
+ --slave /usr/bin/clang-format clang-format /usr/bin/clang-format-10 \
+ --slave /usr/bin/run-clang-tidy.py run-clang-tidy.py /usr/bin/run-clang-tidy-10.py
+
+RUN pip3 install inflection
+RUN pip3 install pycodestyle
+RUN pip3 install jsonschema
+RUN pip3 install meson==0.54.3
+RUN pip3 install protobuf
+
+FROM openbmc-base as openbmc-lcov
+RUN curl -L https://github.com/linux-test-project/lcov/archive/{pkg_rev['lcov']}.tar.gz | tar -xz && \
+cd lcov-* && \
+make -j{proc_count} && \
+make install
+
+FROM openbmc-base as openbmc-function2
+RUN mkdir {prefix}/include/function2 && \
+curl -L -o {prefix}/include/function2/function2.hpp https://raw.githubusercontent.com/Naios/function2/{pkg_rev['function2']}/include/function2/function2.hpp
+
+FROM openbmc-base as openbmc-googletest
+RUN curl -L https://github.com/google/googletest/archive/{pkg_rev['googletest']}.tar.gz | tar -xz && \
+cd googletest-* && \
+mkdir build && \
+cd build && \
+CXXFLAGS=-std=c++17 cmake {cmake_flags} -DTHREADS_PREFER_PTHREAD_FLAG=ON .. && \
+make -j{proc_count} && \
+make install
+
+FROM openbmc-base as openbmc-catch2
+RUN curl -L https://github.com/catchorg/Catch2/archive/{pkg_rev['catch2']}.tar.gz | tar -xz && \
+cd Catch2-* && \
+mkdir build && \
+cd build && \
+cmake {cmake_flags} -DBUILD_TESTING=OFF -DCATCH_INSTALL_DOCS=OFF .. && \
+make -j{proc_count} && \
+make install
+
+FROM openbmc-base as openbmc-cereal
+RUN curl -L https://github.com/USCiLab/cereal/archive/{pkg_rev['cereal']}.tar.gz | tar -xz && \
+cp -a cereal-*/include/cereal/ {prefix}/include/
+
+FROM openbmc-base as openbmc-CLI11
+RUN curl -L https://github.com/CLIUtils/CLI11/archive/{pkg_rev['CLI11']}.tar.gz | tar -xz && \
+cd CLI11-* && \
+mkdir build && \
+cd build && \
+cmake {cmake_flags} -DCLI11_BUILD_DOCS=OFF -DBUILD_TESTING=OFF -DCLI11_BUILD_EXAMPLES=OFF .. && \
+make -j{proc_count} && \
+make install
+
+FROM openbmc-base as openbmc-fmt
+RUN curl -L https://github.com/fmtlib/fmt/archive/{pkg_rev['fmt']}.tar.gz | tar -xz && \
+cd fmt-* && \
+mkdir build && \
+cd build && \
+cmake {cmake_flags} -DFMT_DOC=OFF -DFMT_TEST=OFF .. && \
+make -j{proc_count} && \
+make install
+
+FROM openbmc-base as openbmc-json
+RUN mkdir {prefix}/include/nlohmann/ && \
+curl -L -o {prefix}/include/nlohmann/json.hpp https://github.com/nlohmann/json/releases/download/{pkg_rev['json']}/json.hpp && \
+ln -s nlohmann/json.hpp {prefix}/include/json.hpp
+
+FROM openbmc-base as openbmc-fifo_map
+RUN curl -L https://github.com/nlohmann/fifo_map/archive/{pkg_rev['fifo_map']}.tar.gz | tar -xz && \
+cd fifo_map-*/src && cp fifo_map.hpp {prefix}/include/
+
+FROM openbmc-base as openbmc-span-lite
+RUN curl -L https://github.com/martinmoene/span-lite/archive/{pkg_rev['span-lite']}.tar.gz | tar -xz && \
+cd span-lite-* && \
+mkdir build && \
+cd build && \
+cmake {cmake_flags} -DSPAN_LITE_OPT_BUILD_TESTS=OFF .. && \
+make -j{proc_count} && \
+make install
+
+FROM openbmc-base as openbmc-linux-headers
+RUN curl -L https://github.com/openbmc/linux/archive/{pkg_rev['linux-headers']}.tar.gz | tar -xz && \
+cd linux-* && \
+make -j{proc_count} defconfig && \
+make INSTALL_HDR_PATH=/usr/local headers_install
+
+FROM openbmc-base as openbmc-boost
+RUN curl -L https://dl.bintray.com/boostorg/release/{pkg_rev['boost']}/source/boost_$(echo "{pkg_rev['boost']}" | tr '.' '_').tar.bz2 | tar -xj && \
+cd boost_*/ && \
+./bootstrap.sh --prefix={prefix} --with-libraries=context,coroutine && \
+./b2 && ./b2 install --prefix={prefix}
+
+FROM openbmc-base as openbmc-tinyxml2
+RUN curl -L https://github.com/leethomason/tinyxml2/archive/{pkg_rev['tinyxml2']}.tar.gz | tar -xz && \
+cd tinyxml2-* && \
+mkdir build && \
+cd build && \
+cmake {cmake_flags} .. && \
+make -j{proc_count} && \
+make install
+
+FROM openbmc-base as openbmc-boost-url
+RUN curl -L https://github.com/CPPAlliance/url/archive/{pkg_rev['boost-url']}.tar.gz | tar -xz && \
+cd url-* && \
+mkdir buildir && \
+cd buildir && \
+cmake {cmake_flags} -DBOOST_URL_STANDALONE=ON -DBOOST_URL_BUILD_TESTS=OFF -DBOOST_URL_BUILD_EXAMPLES=OFF .. && \
+make -j{proc_count} && \
+make install
+
+FROM openbmc-base as openbmc-valijson
+RUN curl -L https://github.com/tristanpenman/valijson/archive/{pkg_rev['valijson']}.tar.gz | tar -xz && \
+cd valijson-* && \
+mkdir build && \
+cd build && \
+cmake {cmake_flags} -DINSTALL_HEADERS=1 -DBUILD_TESTS=0 .. && \
+make -j{proc_count} && \
+make install
+
+FROM openbmc-base as openbmc-libvncserver
+RUN curl -L https://github.com/LibVNC/libvncserver/archive/{pkg_rev['libvncserver']}.tar.gz | tar -xz && \
+cd libvncserver-* && \
+mkdir build && \
+cd build && \
+cmake {cmake_flags} .. && \
+make -j{proc_count} && \
+make install
+
+FROM openbmc-base as openbmc-stdplus
+COPY --from=openbmc-fmt {prefix} {prefix}
+COPY --from=openbmc-span-lite {prefix} {prefix}
+RUN curl -L https://github.com/openbmc/stdplus/archive/{pkg_rev['openbmc/stdplus']}.tar.gz | tar -xz && \
+cd stdplus-* && \
+meson build {meson_flags} -Dtests=disabled -Dexamples=false && \
+ninja -C build && \
+ninja -C build install
+
+FROM openbmc-base as openbmc-sdbusplus
+RUN curl -L https://github.com/openbmc/sdbusplus/archive/{pkg_rev['openbmc/sdbusplus']}.tar.gz | tar -xz && \
+cd sdbusplus-* && \
+cd tools && ./setup.py install --root=/ --prefix={prefix} && \
+cd .. && meson build {meson_flags} -Dtests=disabled -Dexamples=disabled && \
+ninja -C build && \
+ninja -C build install
+
+FROM openbmc-base as openbmc-sdeventplus
+COPY --from=openbmc-function2 {prefix} {prefix}
+COPY --from=openbmc-stdplus {prefix} {prefix}
+RUN curl -L https://github.com/openbmc/sdeventplus/archive/{pkg_rev['openbmc/sdeventplus']}.tar.gz | tar -xz && \
+cd sdeventplus-* && \
+meson build {meson_flags} -Dtests=disabled -Dexamples=false && \
+ninja -C build && \
+ninja -C build install
+
+FROM openbmc-base as openbmc-gpioplus
+COPY --from=openbmc-stdplus {prefix} {prefix}
+RUN curl -L https://github.com/openbmc/gpioplus/archive/{pkg_rev['openbmc/gpioplus']}.tar.gz | tar -xz && \
+cd gpioplus-* && \
+meson build {meson_flags} -Dtests=disabled -Dexamples=false && \
+ninja -C build && \
+ninja -C build install
+
+FROM openbmc-base as openbmc-phosphor-dbus-interfaces
+COPY --from=openbmc-sdbusplus {prefix} {prefix}
+RUN curl -L https://github.com/openbmc/phosphor-dbus-interfaces/archive/{pkg_rev['openbmc/phosphor-dbus-interfaces']}.tar.gz | tar -xz && \
+cd phosphor-dbus-interfaces-* && \
+meson build {meson_flags} -Ddata_org_open_power=true -Ddata_com_ibm=true && \
+ninja -C build && \
+ninja -C build install
+
+FROM openbmc-base as openbmc-phosphor-logging
+COPY --from=openbmc-cereal {prefix} {prefix}
+COPY --from=openbmc-sdbusplus {prefix} {prefix}
+COPY --from=openbmc-sdeventplus {prefix} {prefix}
+COPY --from=openbmc-phosphor-dbus-interfaces {prefix} {prefix}
+COPY --from=openbmc-fifo_map {prefix} {prefix}
+RUN curl -L https://github.com/openbmc/phosphor-logging/archive/{pkg_rev['openbmc/phosphor-logging']}.tar.gz | tar -xz && \
+cd phosphor-logging-* && \
+./bootstrap.sh && \
+./configure {configure_flags} --enable-metadata-processing YAML_DIR={prefix}/share/phosphor-dbus-yaml/yaml && \
+make -j{proc_count} && \
+make install
+
+FROM openbmc-base as openbmc-phosphor-objmgr
+COPY --from=openbmc-boost {prefix} {prefix}
+COPY --from=openbmc-sdbusplus {prefix} {prefix}
+COPY --from=openbmc-tinyxml2 {prefix} {prefix}
+COPY --from=openbmc-phosphor-logging {prefix} {prefix}
+RUN curl -L https://github.com/openbmc/phosphor-objmgr/archive/{pkg_rev['openbmc/phosphor-objmgr']}.tar.gz | tar -xz && \
+cd phosphor-objmgr-* && \
+./bootstrap.sh && \
+./configure {configure_flags} && \
+make -j{proc_count} && \
+make install
+
+FROM openbmc-base as openbmc-open-power-pdbg
+RUN curl -L https://github.com/open-power/pdbg/archive/{pkg_rev['open-power/pdbg']}.tar.gz | tar -xz && \
+cd pdbg-* && \
+./bootstrap.sh && \
+./configure {configure_flags} && \
+make -j{proc_count} && \
+make install
+
+FROM openbmc-base as openbmc-pldm
+COPY --from=openbmc-sdbusplus {prefix} {prefix}
+COPY --from=openbmc-sdeventplus {prefix} {prefix}
+COPY --from=openbmc-boost {prefix} {prefix}
+COPY --from=openbmc-phosphor-dbus-interfaces {prefix} {prefix}
+COPY --from=openbmc-phosphor-logging {prefix} {prefix}
+COPY --from=openbmc-json {prefix} {prefix}
+COPY --from=openbmc-CLI11 {prefix} {prefix}
+RUN curl -L https://github.com/openbmc/pldm/archive/{pkg_rev['openbmc/pldm']}.tar.gz | tar -xz && \
+cd pldm-* && \
+meson build {meson_flags} -Dlibpldm-only=enabled -Doem-ibm=enabled -Dtests=disabled && \
+ninja -C build && \
+ninja -C build install
+
+# Build the final output image
+FROM openbmc-base
+{copy_cmds}
+
+# Some of our infrastructure still relies on the presence of this file
+# even though it is no longer needed to rebuild the docker environment
+# NOTE: The file is sorted to ensure the ordering is stable.
+RUN echo '{depcache}' > /tmp/depcache
+
+# Final configuration for the workspace
+RUN grep -q {gid} /etc/group || groupadd -g {gid} {username}
+RUN mkdir -p "{os.path.dirname(homedir)}"
+RUN grep -q {uid} /etc/passwd || useradd -d {homedir} -m -u {uid} -g {gid} {username}
+RUN sed -i '1iDefaults umask=000' /etc/sudoers
+RUN echo "{username} ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers
+
+{proxy_cmd}
+
+RUN /bin/bash
+"""
+
+# Do the docker build.
+for line in docker.build(
+ proxy_args,
+ "--network=host",
+ "-t",
+ docker_image_name,
+ "-",
+ _in=dockerfile,
+ _iter=True,
+):
+ print(line, end="", flush=True)