107 lines
4.2 KiB
Docker
107 lines
4.2 KiB
Docker
# syntax=docker/dockerfile:1.6
|
|
#
|
|
# ecu-tests image — mock-only by default, hardware variant via:
|
|
# --build-arg INCLUDE_MELEXIS=1
|
|
#
|
|
# Build context = repository root. Always invoke from there:
|
|
#
|
|
# docker build -f docker/Dockerfile -t ecu-tests:mock .
|
|
#
|
|
# DOCKER_BUILDKIT=1 docker build \
|
|
# -f docker/Dockerfile -t ecu-tests:hw \
|
|
# --build-arg INCLUDE_MELEXIS=1 \
|
|
# --secret id=melexis_tarball,src=./melexis-pkgs.tar.gz \
|
|
# .
|
|
#
|
|
# See docs/20_docker_image.md for the full reference, including how
|
|
# to produce melexis-pkgs.tar.gz from a licensed Melexis IDE install.
|
|
|
|
ARG PYTHON_VERSION=3.11
|
|
|
|
# ──────────────────────────────────────────────────────────────────────
|
|
# Stage 1: builder — install deps into a venv under /opt/venv
|
|
# ──────────────────────────────────────────────────────────────────────
|
|
FROM python:${PYTHON_VERSION}-slim AS builder
|
|
|
|
ARG INCLUDE_MELEXIS=0
|
|
|
|
# Build-time OS deps:
|
|
# build-essential, libffi-dev — for any wheel that needs to compile
|
|
# libusb-1.0-0 — pyserial uses it on some adapters
|
|
# git — VCS deps in requirements.txt (if any)
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends \
|
|
build-essential \
|
|
libffi-dev \
|
|
libusb-1.0-0 \
|
|
git \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
PIP_NO_CACHE_DIR=1 \
|
|
PIP_DISABLE_PIP_VERSION_CHECK=1
|
|
|
|
RUN python -m venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:${PATH}"
|
|
|
|
WORKDIR /build
|
|
COPY requirements.txt ./
|
|
RUN pip install --upgrade pip wheel \
|
|
&& pip install -r requirements.txt
|
|
|
|
# Melexis packages — passed in via BuildKit secret so the proprietary
|
|
# tarball never lands in an image layer. Skipped entirely when
|
|
# INCLUDE_MELEXIS=0 (the mock-only path).
|
|
RUN --mount=type=secret,id=melexis_tarball,required=false \
|
|
if [ "$INCLUDE_MELEXIS" = "1" ]; then \
|
|
set -e; \
|
|
test -s /run/secrets/melexis_tarball \
|
|
|| { echo 'INCLUDE_MELEXIS=1 but no melexis_tarball secret bound'; exit 2; }; \
|
|
SITE_PACKAGES=$(python -c "import site; print(site.getsitepackages()[0])"); \
|
|
tar -xzf /run/secrets/melexis_tarball -C "$SITE_PACKAGES"; \
|
|
python -c "import pylin, pymumclient; print('melexis pkgs OK')"; \
|
|
fi
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────
|
|
# Stage 2: runtime — slim image with the venv + repo
|
|
# ──────────────────────────────────────────────────────────────────────
|
|
FROM python:${PYTHON_VERSION}-slim AS runtime
|
|
|
|
# Runtime-only OS deps. tini handles signal forwarding so Ctrl-C tears
|
|
# pytest down cleanly.
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends \
|
|
libusb-1.0-0 \
|
|
ca-certificates \
|
|
tini \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Pull the prebuilt venv (with Melexis pkgs if requested) from builder.
|
|
COPY --from=builder /opt/venv /opt/venv
|
|
|
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONUNBUFFERED=1 \
|
|
PATH="/opt/venv/bin:${PATH}"
|
|
|
|
# The repo. .dockerignore at the build-context root excludes .venv,
|
|
# reports/, vendor/BabyLIN*, __pycache__, etc.
|
|
WORKDIR /workspace
|
|
COPY . /workspace
|
|
|
|
# Reports volume so artifacts survive the container's lifetime.
|
|
RUN mkdir -p /reports
|
|
VOLUME ["/reports"]
|
|
|
|
# Drop root. Inherit the host's serial group at runtime via
|
|
# `--group-add dialout` when you bind-mount /dev/ttyUSB*.
|
|
RUN useradd -m -u 1000 -s /bin/bash tester \
|
|
&& chown -R tester:tester /workspace /reports
|
|
USER tester
|
|
|
|
ENTRYPOINT ["/usr/bin/tini", "--"]
|
|
|
|
# Safe default: collect-only of the non-hardware suite. An accidental
|
|
# `docker run ecu-tests:hw` will list tests, not fire bench actions.
|
|
CMD ["pytest", "-m", "not hardware", "--collect-only", "-q"]
|