From: Fabiano Rosas <farosas@suse.de>
To: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>,
qemu-devel@nongnu.org
Cc: "Alex Bennée" <alex.bennee@linaro.org>,
"Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>,
mjt@tls.msk.ru, peterx@redhat.com
Subject: Re: [PATCH v3 1/3] tests/docker/dockerfiles: add release.docker
Date: Mon, 26 Oct 2026 11:31:17 -0300 [thread overview]
Message-ID: <8733tsleiy.fsf@suse.de> (raw)
In-Reply-To: <9aca799c-3f3b-4234-a38b-725879818755@oss.qualcomm.com>
Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> writes:
> On 10/23/2026 9:06 AM, Fabiano Rosas wrote:
>> Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> writes:
>>
>>> This new dockerfile allows to build a distroless image containing only
>>> qemu stripped release binaries, their lib dependencies, and installed
>>> artifacts (roms, keymap, ...). There is no shell, no python, nothing
>>> else. This is achieved thanks to a multi-stage build, where we add qemu
>>> binaries, artifacts and libraries in a new scratch image. Image has
>>> the minimal size possible.
>>>
>>> This is based on Ubuntu, which has the advantage to have working
>>> containers available up to 12.04. Debian old old stable have broken apt
>>> sources for instance. Ubuntu 10.04 binaries segfault due to missing
>>> vsyscall emulation on modern kernels, so 12.04 is the lowest possible.
>>>
>>> This unique dockerfile works for all qemu versions, with 0.12.0 being the
>>> oldest we can build today (based on ubuntu 12.04). Previous ones need an
>>> older compiler.
>>>
>>> To build the image, you need to provide a qemu and ubuntu version:
>>> $ podman build -f release.Dockerfile --build-arg QEMU_VERSION=v11.1.0 --build-arg UBUNTU_VERSION=24.04 -t qemu/v11.1.0
>>>
>>> To run it, as there is no shell, and no defined entrypoint, you need to
>>> choose the binary you want explicitely:
>>> $ podman run -it --rm qemu/v11.1.0 qemu-system-aarch64 --version
>>>
>>> Notes: We could optimize a bit further, by creating a base container for
>>> each ubuntu version, that is reused between all qemu versions built with
>>> it. Given that recent QEMU have around 800MB of binaries + artifacts,
>>> and only 100MB of library dependency, I don't think it's worth the extra
>>> complexity.
>>>
>>> Notes: Also, I considered create one image per binary. Problem is
>>> that qemu depends on other artifacts (rom, keymap, etc) and it's not
>>> easy to identify what is needed for one binary. Thus, I think it's
>>> better to stick to one container with all binaries per release.
>>>
>>
>> Yeah, it's fine this way.
>>
>>> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
>>> ---
>>> tests/docker/dockerfiles/release.docker | 76 +++++++++++++++++++++++++
>>> 1 file changed, 76 insertions(+)
>>> create mode 100644 tests/docker/dockerfiles/release.docker
>>>
>>> diff --git a/tests/docker/dockerfiles/release.docker b/tests/docker/dockerfiles/release.docker
>>> new file mode 100644
>>> index 00000000000..611ecca9859
>>> --- /dev/null
>>> +++ b/tests/docker/dockerfiles/release.docker
>>> @@ -0,0 +1,76 @@
>>> +ARG UBUNTU_VERSION="UBUNTU_VERSION_build_arg_must_be_set"
>>> +FROM ubuntu:$UBUNTU_VERSION as build
>>
>> I believe FROM should be capitalized the same as AS.
>>
>
> Dockerfile instructions are not case sensitive, but yes, AS would be
> more consistent, I'll change it.
>
Docker emits a warning about the mismatch.
>>> +ARG UBUNTU_VERSION
>>
>> Is this duplicated?
>>
>
> ARG have to be duplicated for each stage of the build.
> In this case:
> - pre-stage (to be used in first FROM)
> - first-stage (to be used inside this stage)
>
Got it.
>>> +
>>> +# add deb-src for apt build-dep
>>> +RUN sed -e 's/Types: deb/Types: deb deb-src/' -i /etc/apt/sources.list.d/* || true
>>> +RUN sed -e 's/# deb-src/deb-src/' -i /etc/apt/sources.list
>>> +# archive.canonical.com is not reachable anymore, and cause a long timeout
>>> +RUN sed -e '/archive.canonical.com/d' -i /etc/apt/sources.list
>>> +# LTS < 14.04 are hosted on https://old-releases.ubuntu.com/releases/
>>> +RUN if [ $(echo $UBUNTU_VERSION | cut -f 1 -d '.') -lt 14 ]; then \
>>> + sed -e 's/archive/old-releases/g' -i /etc/apt/sources.list; \
>>> +fi
>>
>> Hm, so I imagine these containers have reached end-of-life? I wonder
>> whether we should cap how further back we go based on this. It's one
>> thing to workaround a few installation bugs we list/install our
>> dependencies, another thing is the distro image poiting to dead URLs.
>>
>
> If we want to cap it, then 14.04 is the lowest limit with fixed url.
> Note that archive.canonical.com still has to be removed, it's present in
> some LTS > 14.04 and create a long timeout for apt update.
>
>>> +
>>> +# use apt-get since apt was missing -y option in some ancient distro
>>
>> Ok, this is a reasonable issue to encounter and fix in the dockerfile. I
>> pointed at this on the cover letter, but we don't gain much in knowing
>> exactly which apt version has -y or not.
>>
>>> +RUN apt-get update && \
>>> +env DEBIAN_FRONTEND=noninteractive apt-get install -y git build-essential
>>> +RUN apt-get update && \
>>> +env DEBIAN_FRONTEND=noninteractive apt-get build-dep -y --arch-only qemu
>>> +# additional dependencies that are missing at some point in history
>>> +RUN apt-get update && \
>>> +env DEBIAN_FRONTEND=noninteractive apt-get install -y ninja-build flex bison libpixman-1-dev
>>
>> So a discrepancy on which QEMU version and how the distro packaged it at
>> the time vs. which dependencies we had. Is this something that would
>> have been solved by lcitool? (Hm, did we even use it back then?)
>>
>
> It's new dependencies added by QEMU over time, that distro didn't
> reflect yet at a past date. (ninja introduction, or recently hexagon
> target which requires flex/bison for idef tool).
>
Right, and they may never add it, because it's either already in the
past or because they simply don't need that dependency for their
package.
If we're around release time and for some reason they change what's in
their package, it would be annoying to have to figure this out to
unbreak CI or something similar.
It's a situation that tends to degenerate to that last line simply
becoming the full list of dependencies. There's also the whack-a-mole-y
job of removing packages (for tidyness) from the last line if they end
up being provided by build-dep.
Granted it's containers and there may be little expectation of things
working indefinitely without code changes, so I'll let the maintainers
do what they prefer.
>>> +# python3-venv didn't exist in ancient ubuntu distro
>>> +RUN apt-get update && \
>>> +if apt-cache show python3-venv; then \
>>> + env DEBIAN_FRONTEND=noninteractive apt-get install -y python3-venv; \
>>> +fi
>>
>> Maybe good to know which version so we know when to drop this block?
>>
>> I see some of these check the ubuntu version, some not, I wonder how
>> easy it will be to break an older image's build when trying to fix a new
>> one. I find it a bit confusing.
>>
>
> Good point, I think I had this written *before* trying to go before
> 14.04, thus the inconsistency.
>
>>> +
>>> +# patch cc and c++ to inject warning suppression options
>>> +RUN mv /usr/bin/cc /usr/bin/cc.real
>>> +RUN echo "#!/usr/bin/env bash" > /usr/bin/cc && \
>>> +echo "exec /usr/bin/cc.real \"\$@\" -Wno-error -Wno-int-conversion" >> /usr/bin/cc && \
>>> +chmod +x /usr/bin/cc
>>> +RUN mv /usr/bin/c++ /usr/bin/c++.real
>>> +RUN echo "#!/usr/bin/env bash" > /usr/bin/c++ && \
>>> +echo "exec /usr/bin/c++.real \"\$@\" -Wno-error -Wno-int-conversion" >> /usr/bin/c++ && \
>>> +chmod +x /usr/bin/c++
>>> +
>>
>> This assumes this dockerfile will not be used to test a current
>> build. Probably ok.
>>
>
> Why is it a problem? It just disables werror in a systematic way,
> without relying on configure --disable-werror that was not always there.
>
Depends on how we use this image. If it runs early in some CI it might
be better to let it catch the warnings.
>>> +# 2.9.0 => 3.1.0: clone git submodules from expired url, replace them with gitlab.
This sentence may need rewording.
>>> +# 2.9.0 => 2.11.0: issue with libfdt version, solved with dtc submodule, which
>>> +# was removed later.
>>> +# Ubuntu < 14.04: git has no --single-branch, so perform manual fetch after clone.
>>
>> See how unstructured this has become? A comment here, the code down
>> there, nothing actually checks the version, the sed happens for all
>> versions, etc. Dockerfiles are bad at this kind of thing.
>>
>
> This one is just a comment, and the code below has a single
> implementation that works over all versions.
> We could have ifs with multiple code paths, just a question of personal
> taste I suppose.
>
Could be.
> Out of the if on ubuntu version at the beginning, the general approach
> was to have a single code path for all versions of QEMU/Ubuntu, without
> ifs per version.
>
Ok, makes sense.
>>> +ARG QEMU_VERSION
>>> +RUN echo "QEMU_VERSION=${QEMU_VERSION:?QEMU_VERSION build arg must be set}"
>>
>> In order to build local trees I added at this point:
>>
>> RUN --mount=type=bind,from=qemu-src,target=/tmp/qemu-src,rw \
>> cd /tmp && \
>> if echo "${QEMU_VERSION}" | grep -q "\."; then \
>> git clone https://gitlab.com/qemu-project/qemu.git --depth 1 && cd qemu && \
>> git fetch origin "${QEMU_VERSION}" --depth 1 && \
>> git checkout FETCH_HEAD; \
>> else \
>> git clone qemu-src qemu && cd qemu && \
>> git checkout "${QEMU_VERSION}"; \
>> fi && \
>>
>
> We can extend to support any sha-1 (it's just a matter of doing full vs
> shallow clone).
>
+1
> For the local build, I don't like the idea to build from local state, it
> has zero guarantee for reproducibility, which goes against what
> dockerfiles are IMHO.
>
Could this be crafted to take the git repo url as argument, then? Your
point is valid, but once this image is used for something that exposes a
bug, it's natural to want to re-execute with a modified codebase to
debug or test a fix.
> Regards,
> Pierrick
next prev parent reply other threads:[~2026-10-26 14:32 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-14 0:53 [PATCH v3 0/3] releases: build and run any QEMU release easily! Pierrick Bouvier
2026-10-14 0:53 ` [PATCH v3 1/3] tests/docker/dockerfiles: add release.docker Pierrick Bouvier
2026-10-23 16:06 ` Fabiano Rosas
2026-10-24 0:28 ` Pierrick Bouvier
2026-10-26 14:31 ` Fabiano Rosas [this message]
2026-10-26 15:57 ` Pierrick Bouvier
2026-10-14 0:53 ` [PATCH v3 2/3] scripts: add build_release_container.sh Pierrick Bouvier
2026-10-14 0:53 ` [PATCH v3 3/3] scripts: add generate_release_wrappers.sh Pierrick Bouvier
2026-10-23 15:33 ` [PATCH v3 0/3] releases: build and run any QEMU release easily! Fabiano Rosas
2026-10-24 1:48 ` Pierrick Bouvier
2026-10-26 16:32 ` Fabiano Rosas
2026-10-26 18:08 ` Pierrick Bouvier
2026-10-27 15:36 ` Fabiano Rosas
2026-10-27 18:06 ` Pierrick Bouvier
2026-10-27 22:54 ` Fabiano Rosas
2026-10-27 23:27 ` Pierrick Bouvier
2026-10-26 21:09 ` Pierrick Bouvier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8733tsleiy.fsf@suse.de \
--to=farosas@suse.de \
--cc=alex.bennee@linaro.org \
--cc=mjt@tls.msk.ru \
--cc=peterx@redhat.com \
--cc=philmd@oss.qualcomm.com \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.