├── .gitattributes ├── .github └── workflows │ ├── ci.yml │ └── verify-templating.yml ├── .gitignore ├── 10.0 ├── Dockerfile ├── Dockerfile.native ├── qemu-signals.patch └── start-qemu ├── 10.1 ├── Dockerfile ├── Dockerfile.native ├── qemu-signals.patch └── start-qemu ├── 7.2 ├── Dockerfile ├── Dockerfile.native ├── qemu-signals.patch └── start-qemu ├── 9.1 ├── Dockerfile ├── Dockerfile.native ├── qemu-signals.patch └── start-qemu ├── 9.2 ├── Dockerfile ├── Dockerfile.native ├── qemu-signals.patch └── start-qemu ├── Dockerfile.template ├── README.md ├── apply-templates.sh ├── generate-stackbrew-library.sh ├── start-qemu ├── update.sh ├── versions.json └── versions.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | /*/**/Dockerfile* linguist-generated 2 | /*/**/start-qemu linguist-generated 3 | Dockerfile* linguist-language=Dockerfile 4 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: GitHub CI 2 | 3 | on: 4 | pull_request: 5 | push: 6 | workflow_dispatch: 7 | schedule: 8 | - cron: 0 0 * * 0 9 | 10 | defaults: 11 | run: 12 | shell: 'bash -Eeuo pipefail -x {0}' 13 | 14 | concurrency: 15 | group: ${{ github.ref }} 16 | cancel-in-progress: true 17 | 18 | jobs: 19 | 20 | generate-jobs: 21 | name: Generate Jobs 22 | runs-on: ubuntu-latest 23 | outputs: 24 | strategy: ${{ steps.generate-jobs.outputs.strategy }} 25 | steps: 26 | - uses: actions/checkout@v4 27 | - uses: docker-library/bashbrew@HEAD 28 | - id: generate-jobs 29 | name: Generate Jobs 30 | run: | 31 | export BASHBREW_NAMESPACE='tianon' 32 | image="${GITHUB_REPOSITORY##*/}" 33 | image="${image#docker-}" 34 | export GITHUB_REPOSITORY="$image" 35 | 36 | strategy="$("$BASHBREW_SCRIPTS/github-actions/generate.sh")" 37 | 38 | EOF="EOF-$RANDOM-$RANDOM-$RANDOM" 39 | echo "strategy<<$EOF" >> "$GITHUB_OUTPUT" 40 | jq <<<"$strategy" . | tee -a "$GITHUB_OUTPUT" 41 | echo "$EOF" >> "$GITHUB_OUTPUT" 42 | 43 | test: 44 | needs: generate-jobs 45 | strategy: ${{ fromJson(needs.generate-jobs.outputs.strategy) }} 46 | name: ${{ matrix.name }} 47 | runs-on: ${{ matrix.os }} 48 | steps: 49 | - uses: actions/checkout@v4 50 | - name: Prepare Environment 51 | run: ${{ matrix.runs.prepare }} 52 | - name: Pull Dependencies 53 | run: ${{ matrix.runs.pull }} 54 | - name: Build ${{ matrix.name }} 55 | run: ${{ matrix.runs.build }} 56 | - name: History ${{ matrix.name }} 57 | run: ${{ matrix.runs.history }} 58 | - name: Test ${{ matrix.name }} 59 | run: ${{ matrix.runs.test }} 60 | - name: '"docker images"' 61 | run: ${{ matrix.runs.images }} 62 | -------------------------------------------------------------------------------- /.github/workflows/verify-templating.yml: -------------------------------------------------------------------------------- 1 | name: Verify Templating 2 | 3 | on: 4 | pull_request: 5 | push: 6 | 7 | defaults: 8 | run: 9 | shell: 'bash -Eeuo pipefail -x {0}' 10 | 11 | jobs: 12 | apply-templates: 13 | name: Check For Uncomitted Changes 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: Apply Templates 18 | run: ./apply-templates.sh 19 | - name: Check Git Status 20 | run: | 21 | status="$(git status --short)" 22 | [ -z "$status" ] 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .jq-template.awk 2 | -------------------------------------------------------------------------------- /10.0/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM debian:trixie-slim 8 | 9 | RUN set -eux; \ 10 | # add backports for (potentially) newer QEMU firmware packages 11 | if grep backports /etc/apt/sources.list.d/debian.sources; then exit 1; fi; \ 12 | sed -ri -e 's/([[:space:]])([^[:space:]]+)-updates($|[[:space:]])/\0\1\2-backports\3/' /etc/apt/sources.list.d/debian.sources; \ 13 | grep backports /etc/apt/sources.list.d/debian.sources; \ 14 | # and add APT pinning to ensure we don't accidentally get QEMU from Debian 15 | { \ 16 | echo 'Package: src:edk2'; \ 17 | echo 'Pin: release a=*-backports'; \ 18 | echo 'Pin-Priority: 600'; \ 19 | echo; \ 20 | echo 'Package: src:qemu'; \ 21 | echo 'Pin: version *'; \ 22 | echo 'Pin-Priority: -10'; \ 23 | } > /etc/apt/preferences.d/qemu.pref; \ 24 | apt-get update; \ 25 | # https://github.com/tianon/docker-qemu/issues/30 26 | apt-get install -y --no-install-recommends ca-certificates; \ 27 | # include "swtpm" for TPM emulation -- not automatically launched, but small and useful for running a TPM sidecar container (https://qemu-project.gitlab.io/qemu/specs/tpm.html#the-qemu-tpm-emulator-device) 28 | apt-get install -y --no-install-recommends swtpm; \ 29 | # install "firmware" packages (easier UEFI, etc) 30 | apt-get install -y --no-install-recommends \ 31 | # amd64 32 | ovmf \ 33 | # arm64 34 | qemu-efi-aarch64 \ 35 | # armel | armhf 36 | qemu-efi-arm \ 37 | # i386 38 | ovmf-ia32 \ 39 | # riscv64 40 | opensbi u-boot-qemu \ 41 | ; \ 42 | apt-get dist-clean 43 | 44 | COPY *.patch /qemu-patches/ 45 | 46 | # https://wiki.qemu.org/SecurityProcess 47 | ENV QEMU_KEYS \ 48 | # Michael Roth 49 | CEACC9E15534EBABB82D3FA03353C9CEF108B584 50 | # https://wiki.qemu.org/Planning/ReleaseProcess#Sign_the_resulting_tarball_with_GPG: (they get signed by whoever is making the release) 51 | 52 | # https://www.qemu.org/download/#source 53 | # https://download.qemu.org/?C=M;O=D 54 | ENV QEMU_VERSION 10.0.5 55 | ENV QEMU_URL https://download.qemu.org/qemu-10.0.5.tar.xz 56 | 57 | RUN set -eux; \ 58 | \ 59 | savedAptMark="$(apt-mark showmanual)"; \ 60 | \ 61 | apt-get install --update -y --no-install-recommends \ 62 | gnupg \ 63 | wget \ 64 | xz-utils \ 65 | \ 66 | patch \ 67 | \ 68 | bzip2 \ 69 | gcc \ 70 | gnutls-dev \ 71 | libaio-dev \ 72 | libbz2-dev \ 73 | libc-dev \ 74 | libcap-dev \ 75 | libcap-ng-dev \ 76 | libcurl4-gnutls-dev \ 77 | libglib2.0-dev \ 78 | libiscsi-dev \ 79 | libjpeg-dev \ 80 | libncursesw5-dev \ 81 | libnfs-dev \ 82 | libnuma-dev \ 83 | libpixman-1-dev \ 84 | libpng-dev \ 85 | librbd-dev \ 86 | libseccomp-dev \ 87 | libssh-dev \ 88 | libusb-1.0-0-dev \ 89 | libusbredirparser-dev \ 90 | libxen-dev \ 91 | make \ 92 | pkg-config \ 93 | python3 \ 94 | zlib1g-dev \ 95 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 96 | ninja-build \ 97 | python3-setuptools \ 98 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 99 | libfuse3-dev \ 100 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 101 | libslirp-dev \ 102 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 103 | python3-venv \ 104 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 105 | git \ 106 | ; \ 107 | \ 108 | tarball="$(basename "$QEMU_URL")"; \ 109 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 110 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 111 | \ 112 | export GNUPGHOME="$(mktemp -d)"; \ 113 | for key in $QEMU_KEYS; do \ 114 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 115 | done; \ 116 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 117 | gpgconf --kill all; \ 118 | rm -rf "$GNUPGHOME"; \ 119 | \ 120 | mkdir /usr/src/qemu; \ 121 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 122 | rm "$tarball" "$tarball.sig"; \ 123 | \ 124 | cd /usr/src/qemu; \ 125 | \ 126 | for p in /qemu-patches/*.patch; do \ 127 | patch --strip 1 --input "$p"; \ 128 | done; \ 129 | rm -rf /qemu-patches; \ 130 | \ 131 | ./configure --help; \ 132 | ./configure \ 133 | # let's add a link to our source code in the output of "--version" in case our users end up filing bugs against the QEMU project O:) 134 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 135 | --target-list=' \ 136 | # system targets 137 | # (https://sources.debian.org/src/qemu/buster/debian/rules/#L59-L63, slimmed) 138 | i386-softmmu x86_64-softmmu aarch64-softmmu arm-softmmu m68k-softmmu \ 139 | mips64-softmmu mips64el-softmmu ppc64-softmmu riscv64-softmmu \ 140 | sparc64-softmmu s390x-softmmu \ 141 | ' \ 142 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 143 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 144 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 145 | --disable-docs \ 146 | --disable-gtk --disable-vte \ 147 | --disable-sdl \ 148 | --enable-attr \ 149 | --enable-bzip2 \ 150 | --enable-cap-ng \ 151 | --enable-curl \ 152 | --enable-curses \ 153 | --enable-fdt \ 154 | --enable-gnutls \ 155 | --enable-kvm \ 156 | --enable-libiscsi \ 157 | --enable-libnfs \ 158 | --enable-libssh \ 159 | --enable-libusb \ 160 | --enable-linux-aio \ 161 | --enable-modules \ 162 | --enable-numa \ 163 | --enable-rbd \ 164 | --enable-seccomp \ 165 | --enable-strip \ 166 | --enable-tools \ 167 | --enable-usb-redir \ 168 | --enable-vhost-net \ 169 | --enable-vhost-user \ 170 | --enable-vhost-vdpa \ 171 | --enable-virtfs \ 172 | --enable-vnc \ 173 | --enable-vnc-jpeg \ 174 | --enable-xen \ 175 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 176 | # --enable-vde \ 177 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 178 | --enable-fuse \ 179 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 180 | --enable-slirp \ 181 | ; \ 182 | make -j "$(nproc)"; \ 183 | make install; \ 184 | \ 185 | cd /; \ 186 | rm -rf /usr/src/qemu; \ 187 | \ 188 | apt-mark auto '.*' > /dev/null; \ 189 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 190 | find /usr/local \ 191 | -type f \ 192 | \( -executable -o -name '*.so' \) \ 193 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 194 | -not -name 'block-rbd.so' \ 195 | -exec ldd '{}' ';' \ 196 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 197 | | sort -u \ 198 | | xargs -r dpkg-query --search \ 199 | | cut -d: -f1 \ 200 | | sort -u \ 201 | | xargs -r apt-mark manual \ 202 | ; \ 203 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 204 | apt-get dist-clean; \ 205 | \ 206 | # basic smoke test 207 | qemu-img --version 208 | 209 | STOPSIGNAL SIGHUP 210 | 211 | EXPOSE 22 212 | EXPOSE 5900 213 | 214 | COPY start-qemu /usr/local/bin/ 215 | CMD ["start-qemu"] 216 | -------------------------------------------------------------------------------- /10.0/Dockerfile.native: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM debian:trixie-slim 8 | 9 | RUN set -eux; \ 10 | # add backports for (potentially) newer QEMU firmware packages 11 | if grep backports /etc/apt/sources.list.d/debian.sources; then exit 1; fi; \ 12 | sed -ri -e 's/([[:space:]])([^[:space:]]+)-updates($|[[:space:]])/\0\1\2-backports\3/' /etc/apt/sources.list.d/debian.sources; \ 13 | grep backports /etc/apt/sources.list.d/debian.sources; \ 14 | # and add APT pinning to ensure we don't accidentally get QEMU from Debian 15 | { \ 16 | echo 'Package: src:edk2'; \ 17 | echo 'Pin: release a=*-backports'; \ 18 | echo 'Pin-Priority: 600'; \ 19 | echo; \ 20 | echo 'Package: src:qemu'; \ 21 | echo 'Pin: version *'; \ 22 | echo 'Pin-Priority: -10'; \ 23 | } > /etc/apt/preferences.d/qemu.pref; \ 24 | apt-get update; \ 25 | # https://github.com/tianon/docker-qemu/issues/30 26 | apt-get install -y --no-install-recommends ca-certificates; \ 27 | # include "swtpm" for TPM emulation -- not automatically launched, but small and useful for running a TPM sidecar container (https://qemu-project.gitlab.io/qemu/specs/tpm.html#the-qemu-tpm-emulator-device) 28 | apt-get install -y --no-install-recommends swtpm; \ 29 | # install "firmware" packages (easier UEFI, etc) 30 | arch="$(dpkg --print-architecture)"; \ 31 | case "$arch" in \ 32 | amd64) apt-get install -y --no-install-recommends ovmf ;; \ 33 | arm64) apt-get install -y --no-install-recommends qemu-efi-aarch64 ;; \ 34 | armel | armhf) apt-get install -y --no-install-recommends qemu-efi-arm ;; \ 35 | i386) apt-get install -y --no-install-recommends ovmf-ia32 ;; \ 36 | riscv64) apt-get install -y --no-install-recommends opensbi u-boot-qemu ;; \ 37 | *) echo >&2 "warning: architecture '$arch' unknown 😅 (is there a 'QEMU firmware' package that should be installed here? likely candidates: https://packages.debian.org/source/$suite/edk2)" ;; \ 38 | esac; \ 39 | apt-get dist-clean 40 | 41 | COPY *.patch /qemu-patches/ 42 | 43 | # https://wiki.qemu.org/SecurityProcess 44 | ENV QEMU_KEYS \ 45 | # Michael Roth 46 | CEACC9E15534EBABB82D3FA03353C9CEF108B584 47 | # https://wiki.qemu.org/Planning/ReleaseProcess#Sign_the_resulting_tarball_with_GPG: (they get signed by whoever is making the release) 48 | 49 | # https://www.qemu.org/download/#source 50 | # https://download.qemu.org/?C=M;O=D 51 | ENV QEMU_VERSION 10.0.5 52 | ENV QEMU_URL https://download.qemu.org/qemu-10.0.5.tar.xz 53 | 54 | RUN set -eux; \ 55 | \ 56 | savedAptMark="$(apt-mark showmanual)"; \ 57 | \ 58 | apt-get install --update -y --no-install-recommends \ 59 | gnupg \ 60 | wget \ 61 | xz-utils \ 62 | \ 63 | patch \ 64 | \ 65 | bzip2 \ 66 | gcc \ 67 | gnutls-dev \ 68 | libaio-dev \ 69 | libbz2-dev \ 70 | libc-dev \ 71 | libcap-dev \ 72 | libcap-ng-dev \ 73 | libcurl4-gnutls-dev \ 74 | libglib2.0-dev \ 75 | libiscsi-dev \ 76 | libjpeg-dev \ 77 | libncursesw5-dev \ 78 | libnfs-dev \ 79 | libnuma-dev \ 80 | libpixman-1-dev \ 81 | libpng-dev \ 82 | librbd-dev \ 83 | libseccomp-dev \ 84 | libssh-dev \ 85 | libusb-1.0-0-dev \ 86 | libusbredirparser-dev \ 87 | libxen-dev \ 88 | make \ 89 | pkg-config \ 90 | python3 \ 91 | zlib1g-dev \ 92 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 93 | ninja-build \ 94 | python3-setuptools \ 95 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 96 | libfuse3-dev \ 97 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 98 | libslirp-dev \ 99 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 100 | python3-venv \ 101 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 102 | git \ 103 | ; \ 104 | \ 105 | tarball="$(basename "$QEMU_URL")"; \ 106 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 107 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 108 | \ 109 | export GNUPGHOME="$(mktemp -d)"; \ 110 | for key in $QEMU_KEYS; do \ 111 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 112 | done; \ 113 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 114 | gpgconf --kill all; \ 115 | rm -rf "$GNUPGHOME"; \ 116 | \ 117 | mkdir /usr/src/qemu; \ 118 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 119 | rm "$tarball" "$tarball.sig"; \ 120 | \ 121 | cd /usr/src/qemu; \ 122 | \ 123 | for p in /qemu-patches/*.patch; do \ 124 | patch --strip 1 --input "$p"; \ 125 | done; \ 126 | rm -rf /qemu-patches; \ 127 | \ 128 | arch="$(dpkg --print-architecture)"; \ 129 | case "$arch" in \ 130 | amd64) targetList='x86_64-softmmu' ;; \ 131 | arm64) targetList='aarch64-softmmu' ;; \ 132 | armel | armhf) targetList='arm-softmmu' ;; \ 133 | i386) targetList='i386-softmmu' ;; \ 134 | mips64el) targetList='mips64el-softmmu' ;; \ 135 | ppc64el) targetList='ppc64-softmmu' ;; \ 136 | s390x) targetList='s390x-softmmu' ;; \ 137 | *) echo >&2 "error: architecture '$arch' unimplemented 😅"; exit 1 ;; \ 138 | esac; \ 139 | \ 140 | ./configure --help; \ 141 | ./configure \ 142 | # let's add a link to our source code in the output of "--version" in case our users end up filing bugs against the QEMU project O:) 143 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 144 | --target-list="$targetList" \ 145 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 146 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 147 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 148 | --disable-docs \ 149 | --disable-gtk --disable-vte \ 150 | --disable-sdl \ 151 | --enable-attr \ 152 | --enable-bzip2 \ 153 | --enable-cap-ng \ 154 | --enable-curl \ 155 | --enable-curses \ 156 | --enable-fdt \ 157 | --enable-gnutls \ 158 | --enable-kvm \ 159 | --enable-libiscsi \ 160 | --enable-libnfs \ 161 | --enable-libssh \ 162 | --enable-libusb \ 163 | --enable-linux-aio \ 164 | --enable-modules \ 165 | --enable-numa \ 166 | --enable-rbd \ 167 | --enable-seccomp \ 168 | --enable-strip \ 169 | --enable-tools \ 170 | --enable-usb-redir \ 171 | --enable-vhost-net \ 172 | --enable-vhost-user \ 173 | --enable-vhost-vdpa \ 174 | --enable-virtfs \ 175 | --enable-vnc \ 176 | --enable-vnc-jpeg \ 177 | --enable-xen \ 178 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 179 | # --enable-vde \ 180 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 181 | --enable-fuse \ 182 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 183 | --enable-slirp \ 184 | ; \ 185 | make -j "$(nproc)"; \ 186 | make install; \ 187 | \ 188 | cd /; \ 189 | rm -rf /usr/src/qemu; \ 190 | \ 191 | apt-mark auto '.*' > /dev/null; \ 192 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 193 | find /usr/local \ 194 | -type f \ 195 | \( -executable -o -name '*.so' \) \ 196 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 197 | -not -name 'block-rbd.so' \ 198 | -exec ldd '{}' ';' \ 199 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 200 | | sort -u \ 201 | | xargs -r dpkg-query --search \ 202 | | cut -d: -f1 \ 203 | | sort -u \ 204 | | xargs -r apt-mark manual \ 205 | ; \ 206 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 207 | apt-get dist-clean; \ 208 | \ 209 | # basic smoke test 210 | qemu-img --version 211 | 212 | STOPSIGNAL SIGHUP 213 | 214 | EXPOSE 22 215 | EXPOSE 5900 216 | 217 | COPY start-qemu /usr/local/bin/ 218 | CMD ["start-qemu"] 219 | -------------------------------------------------------------------------------- /10.0/qemu-signals.patch: -------------------------------------------------------------------------------- 1 | Origin: https://bugs.launchpad.net/qemu/+bug/1217339/comments/2 2 | Origin: https://lists.nongnu.org/archive/html/qemu-devel/2017-03/msg03039.html 3 | 4 | diff --git a/system/runstate.c b/system/runstate.c 5 | index 272801d307..3270467799 100644 6 | --- a/system/runstate.c 7 | +++ b/system/runstate.c 8 | @@ -714,7 +714,11 @@ void qemu_system_killed(int signal, pid_t pid) 9 | /* Cannot call qemu_system_shutdown_request directly because 10 | * we are in a signal handler. 11 | */ 12 | + if (signal == SIGHUP) { 13 | + powerdown_requested = 1; 14 | + } else { // indentation of the following is "wrong" on purpose so the patch diff is smaller (and the relation to the original code more obvious) 15 | shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 16 | + } 17 | qemu_notify_event(); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /10.0/start-qemu: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # main available options: 5 | # QEMU_CPU=n (cores) 6 | # QEMU_RAM=nnn (megabytes) 7 | # QEMU_HDA (filename) 8 | # QEMU_HDA_SIZE (bytes, suffixes like "G" allowed) 9 | # QEMU_CDROM (filename) 10 | # QEMU_BOOT (-boot) 11 | # QEMU_PORTS="xxx[ xxx ...]" (space separated port numbers) 12 | # QEMU_NET_USER_EXTRA="net=192.168.76.0/24,dhcpstart=192.168.76.9" (extra raw args for "-net user,...") 13 | # QEMU_NO_NET=1 (suppress ALL -netdev - thus no port forwards, etc) 14 | # QEMU_NO_SSH=1 (suppress automatic port 22 forwarding) 15 | # QEMU_NO_SERIAL=1 (suppress automatic "-serial stdio") 16 | # QEMU_NO_VNC=1 (suppress automatic "-vnc ':0'") 17 | 18 | hostArch="$(uname -m)" 19 | qemuArch="${QEMU_ARCH:-$hostArch}" 20 | qemu="${QEMU_BIN:-qemu-system-$qemuArch}" 21 | qemuArgs=() 22 | 23 | qemuPorts=() 24 | if [ -z "${QEMU_NO_SSH:-}" ]; then 25 | qemuPorts+=( 22 ) 26 | fi 27 | qemuPorts+=( ${QEMU_PORTS:-} ) 28 | 29 | if [ -e /dev/kvm ] && sh -c 'echo -n > /dev/kvm' &> /dev/null; then 30 | # https://github.com/tianon/docker-qemu/issues/4 31 | qemuArgs+=( -enable-kvm ) 32 | elif [ "$hostArch" = "$qemuArch" ]; then 33 | echo >&2 34 | echo >&2 'warning: /dev/kvm not found' 35 | echo >&2 ' PERFORMANCE WILL SUFFER' 36 | echo >&2 ' (hint: docker run --device /dev/kvm ...)' 37 | echo >&2 38 | sleep 3 39 | fi 40 | 41 | qemuArgs+=( -smp "${QEMU_CPU:-1}" ) 42 | qemuArgs+=( -m "${QEMU_RAM:-512}" ) 43 | 44 | if [ -n "${QEMU_HDA:-}" ]; then 45 | if [ ! -f "$QEMU_HDA" -o ! -s "$QEMU_HDA" ]; then 46 | ( 47 | set -x 48 | qemu-img create -f qcow2 -o preallocation=off "$QEMU_HDA" "${QEMU_HDA_SIZE:-8G}" 49 | ) 50 | fi 51 | 52 | # http://wiki.qemu.org/download/qemu-doc.html#Invocation 53 | qemuScsiDevice='virtio-scsi-pci' 54 | case "$qemuArch" in 55 | arm | riscv64) qemuScsiDevice='virtio-scsi-device' ;; 56 | esac 57 | 58 | #qemuArgs+=( -hda "$QEMU_HDA" ) 59 | #qemuArgs+=( -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap ) 60 | qemuArgs+=( 61 | -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap,detect-zeroes=unmap,if=none,id=hda 62 | -device "$qemuScsiDevice" 63 | -device scsi-hd,drive=hda 64 | ) 65 | fi 66 | 67 | if [ -n "${QEMU_CDROM:-}" ]; then 68 | qemuArgs+=( -cdrom "$QEMU_CDROM" ) 69 | fi 70 | 71 | if [ -n "${QEMU_BOOT:-}" ]; then 72 | qemuArgs+=( -boot "$QEMU_BOOT" ) 73 | fi 74 | 75 | if [ -z "${QEMU_NO_NET:-}" ]; then 76 | netArg='user' 77 | netArg+=",hostname=$(hostname)" 78 | if [ -n "${QEMU_NET_USER_EXTRA:-}" ]; then 79 | netArg+=",$QEMU_NET_USER_EXTRA" 80 | fi 81 | for port in "${qemuPorts[@]}"; do 82 | netArg+=",hostfwd=tcp::$port-:$port" 83 | netArg+=",hostfwd=udp::$port-:$port" 84 | done 85 | 86 | qemuNetDevice='virtio-net-pci' 87 | case "$qemuArch" in 88 | arm | riscv64) qemuNetDevice='virtio-net-device' ;; 89 | esac 90 | 91 | qemuArgs+=( 92 | -netdev "$netArg,id=net" 93 | -device "$qemuNetDevice,netdev=net" 94 | ) 95 | fi 96 | 97 | if [ -z "${QEMU_NO_SERIAL:-}" ]; then 98 | qemuArgs+=( 99 | -serial stdio 100 | ) 101 | fi 102 | 103 | if [ -z "${QEMU_NO_VNC:-}" ]; then 104 | qemuArgs+=( 105 | -vnc ':0' 106 | ) 107 | fi 108 | 109 | qemuArgs+=( "$@" ) 110 | 111 | set -x 112 | exec "$qemu" "${qemuArgs[@]}" 113 | -------------------------------------------------------------------------------- /10.1/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM debian:trixie-slim 8 | 9 | RUN set -eux; \ 10 | # add backports for (potentially) newer QEMU firmware packages 11 | if grep backports /etc/apt/sources.list.d/debian.sources; then exit 1; fi; \ 12 | sed -ri -e 's/([[:space:]])([^[:space:]]+)-updates($|[[:space:]])/\0\1\2-backports\3/' /etc/apt/sources.list.d/debian.sources; \ 13 | grep backports /etc/apt/sources.list.d/debian.sources; \ 14 | # and add APT pinning to ensure we don't accidentally get QEMU from Debian 15 | { \ 16 | echo 'Package: src:edk2'; \ 17 | echo 'Pin: release a=*-backports'; \ 18 | echo 'Pin-Priority: 600'; \ 19 | echo; \ 20 | echo 'Package: src:qemu'; \ 21 | echo 'Pin: version *'; \ 22 | echo 'Pin-Priority: -10'; \ 23 | } > /etc/apt/preferences.d/qemu.pref; \ 24 | apt-get update; \ 25 | # https://github.com/tianon/docker-qemu/issues/30 26 | apt-get install -y --no-install-recommends ca-certificates; \ 27 | # include "swtpm" for TPM emulation -- not automatically launched, but small and useful for running a TPM sidecar container (https://qemu-project.gitlab.io/qemu/specs/tpm.html#the-qemu-tpm-emulator-device) 28 | apt-get install -y --no-install-recommends swtpm; \ 29 | # install "firmware" packages (easier UEFI, etc) 30 | apt-get install -y --no-install-recommends \ 31 | # amd64 32 | ovmf \ 33 | # arm64 34 | qemu-efi-aarch64 \ 35 | # armel | armhf 36 | qemu-efi-arm \ 37 | # i386 38 | ovmf-ia32 \ 39 | # riscv64 40 | opensbi u-boot-qemu \ 41 | ; \ 42 | apt-get dist-clean 43 | 44 | COPY *.patch /qemu-patches/ 45 | 46 | # https://wiki.qemu.org/SecurityProcess 47 | ENV QEMU_KEYS \ 48 | # Michael Roth 49 | CEACC9E15534EBABB82D3FA03353C9CEF108B584 50 | # https://wiki.qemu.org/Planning/ReleaseProcess#Sign_the_resulting_tarball_with_GPG: (they get signed by whoever is making the release) 51 | 52 | # https://www.qemu.org/download/#source 53 | # https://download.qemu.org/?C=M;O=D 54 | ENV QEMU_VERSION 10.1.1 55 | ENV QEMU_URL https://download.qemu.org/qemu-10.1.1.tar.xz 56 | 57 | RUN set -eux; \ 58 | \ 59 | savedAptMark="$(apt-mark showmanual)"; \ 60 | \ 61 | apt-get install --update -y --no-install-recommends \ 62 | gnupg \ 63 | wget \ 64 | xz-utils \ 65 | \ 66 | patch \ 67 | \ 68 | bzip2 \ 69 | gcc \ 70 | gnutls-dev \ 71 | libaio-dev \ 72 | libbz2-dev \ 73 | libc-dev \ 74 | libcap-dev \ 75 | libcap-ng-dev \ 76 | libcurl4-gnutls-dev \ 77 | libglib2.0-dev \ 78 | libiscsi-dev \ 79 | libjpeg-dev \ 80 | libncursesw5-dev \ 81 | libnfs-dev \ 82 | libnuma-dev \ 83 | libpixman-1-dev \ 84 | libpng-dev \ 85 | librbd-dev \ 86 | libseccomp-dev \ 87 | libssh-dev \ 88 | libusb-1.0-0-dev \ 89 | libusbredirparser-dev \ 90 | libxen-dev \ 91 | make \ 92 | pkg-config \ 93 | python3 \ 94 | zlib1g-dev \ 95 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 96 | ninja-build \ 97 | python3-setuptools \ 98 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 99 | libfuse3-dev \ 100 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 101 | libslirp-dev \ 102 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 103 | python3-venv \ 104 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 105 | git \ 106 | ; \ 107 | \ 108 | tarball="$(basename "$QEMU_URL")"; \ 109 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 110 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 111 | \ 112 | export GNUPGHOME="$(mktemp -d)"; \ 113 | for key in $QEMU_KEYS; do \ 114 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 115 | done; \ 116 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 117 | gpgconf --kill all; \ 118 | rm -rf "$GNUPGHOME"; \ 119 | \ 120 | mkdir /usr/src/qemu; \ 121 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 122 | rm "$tarball" "$tarball.sig"; \ 123 | \ 124 | cd /usr/src/qemu; \ 125 | \ 126 | for p in /qemu-patches/*.patch; do \ 127 | patch --strip 1 --input "$p"; \ 128 | done; \ 129 | rm -rf /qemu-patches; \ 130 | \ 131 | ./configure --help; \ 132 | ./configure \ 133 | # let's add a link to our source code in the output of "--version" in case our users end up filing bugs against the QEMU project O:) 134 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 135 | --target-list=' \ 136 | # system targets 137 | # (https://sources.debian.org/src/qemu/buster/debian/rules/#L59-L63, slimmed) 138 | i386-softmmu x86_64-softmmu aarch64-softmmu arm-softmmu m68k-softmmu \ 139 | mips64-softmmu mips64el-softmmu ppc64-softmmu riscv64-softmmu \ 140 | sparc64-softmmu s390x-softmmu \ 141 | ' \ 142 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 143 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 144 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 145 | --disable-docs \ 146 | --disable-gtk --disable-vte \ 147 | --disable-sdl \ 148 | --enable-attr \ 149 | --enable-bzip2 \ 150 | --enable-cap-ng \ 151 | --enable-curl \ 152 | --enable-curses \ 153 | --enable-fdt \ 154 | --enable-gnutls \ 155 | --enable-kvm \ 156 | --enable-libiscsi \ 157 | --enable-libnfs \ 158 | --enable-libssh \ 159 | --enable-libusb \ 160 | --enable-linux-aio \ 161 | --enable-modules \ 162 | --enable-numa \ 163 | --enable-rbd \ 164 | --enable-seccomp \ 165 | --enable-strip \ 166 | --enable-tools \ 167 | --enable-usb-redir \ 168 | --enable-vhost-net \ 169 | --enable-vhost-user \ 170 | --enable-vhost-vdpa \ 171 | --enable-virtfs \ 172 | --enable-vnc \ 173 | --enable-vnc-jpeg \ 174 | --enable-xen \ 175 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 176 | # --enable-vde \ 177 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 178 | --enable-fuse \ 179 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 180 | --enable-slirp \ 181 | ; \ 182 | make -j "$(nproc)"; \ 183 | make install; \ 184 | \ 185 | cd /; \ 186 | rm -rf /usr/src/qemu; \ 187 | \ 188 | apt-mark auto '.*' > /dev/null; \ 189 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 190 | find /usr/local \ 191 | -type f \ 192 | \( -executable -o -name '*.so' \) \ 193 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 194 | -not -name 'block-rbd.so' \ 195 | -exec ldd '{}' ';' \ 196 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 197 | | sort -u \ 198 | | xargs -r dpkg-query --search \ 199 | | cut -d: -f1 \ 200 | | sort -u \ 201 | | xargs -r apt-mark manual \ 202 | ; \ 203 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 204 | apt-get dist-clean; \ 205 | \ 206 | # basic smoke test 207 | qemu-img --version 208 | 209 | STOPSIGNAL SIGHUP 210 | 211 | EXPOSE 22 212 | EXPOSE 5900 213 | 214 | COPY start-qemu /usr/local/bin/ 215 | CMD ["start-qemu"] 216 | -------------------------------------------------------------------------------- /10.1/Dockerfile.native: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM debian:trixie-slim 8 | 9 | RUN set -eux; \ 10 | # add backports for (potentially) newer QEMU firmware packages 11 | if grep backports /etc/apt/sources.list.d/debian.sources; then exit 1; fi; \ 12 | sed -ri -e 's/([[:space:]])([^[:space:]]+)-updates($|[[:space:]])/\0\1\2-backports\3/' /etc/apt/sources.list.d/debian.sources; \ 13 | grep backports /etc/apt/sources.list.d/debian.sources; \ 14 | # and add APT pinning to ensure we don't accidentally get QEMU from Debian 15 | { \ 16 | echo 'Package: src:edk2'; \ 17 | echo 'Pin: release a=*-backports'; \ 18 | echo 'Pin-Priority: 600'; \ 19 | echo; \ 20 | echo 'Package: src:qemu'; \ 21 | echo 'Pin: version *'; \ 22 | echo 'Pin-Priority: -10'; \ 23 | } > /etc/apt/preferences.d/qemu.pref; \ 24 | apt-get update; \ 25 | # https://github.com/tianon/docker-qemu/issues/30 26 | apt-get install -y --no-install-recommends ca-certificates; \ 27 | # include "swtpm" for TPM emulation -- not automatically launched, but small and useful for running a TPM sidecar container (https://qemu-project.gitlab.io/qemu/specs/tpm.html#the-qemu-tpm-emulator-device) 28 | apt-get install -y --no-install-recommends swtpm; \ 29 | # install "firmware" packages (easier UEFI, etc) 30 | arch="$(dpkg --print-architecture)"; \ 31 | case "$arch" in \ 32 | amd64) apt-get install -y --no-install-recommends ovmf ;; \ 33 | arm64) apt-get install -y --no-install-recommends qemu-efi-aarch64 ;; \ 34 | armel | armhf) apt-get install -y --no-install-recommends qemu-efi-arm ;; \ 35 | i386) apt-get install -y --no-install-recommends ovmf-ia32 ;; \ 36 | riscv64) apt-get install -y --no-install-recommends opensbi u-boot-qemu ;; \ 37 | *) echo >&2 "warning: architecture '$arch' unknown 😅 (is there a 'QEMU firmware' package that should be installed here? likely candidates: https://packages.debian.org/source/$suite/edk2)" ;; \ 38 | esac; \ 39 | apt-get dist-clean 40 | 41 | COPY *.patch /qemu-patches/ 42 | 43 | # https://wiki.qemu.org/SecurityProcess 44 | ENV QEMU_KEYS \ 45 | # Michael Roth 46 | CEACC9E15534EBABB82D3FA03353C9CEF108B584 47 | # https://wiki.qemu.org/Planning/ReleaseProcess#Sign_the_resulting_tarball_with_GPG: (they get signed by whoever is making the release) 48 | 49 | # https://www.qemu.org/download/#source 50 | # https://download.qemu.org/?C=M;O=D 51 | ENV QEMU_VERSION 10.1.1 52 | ENV QEMU_URL https://download.qemu.org/qemu-10.1.1.tar.xz 53 | 54 | RUN set -eux; \ 55 | \ 56 | savedAptMark="$(apt-mark showmanual)"; \ 57 | \ 58 | apt-get install --update -y --no-install-recommends \ 59 | gnupg \ 60 | wget \ 61 | xz-utils \ 62 | \ 63 | patch \ 64 | \ 65 | bzip2 \ 66 | gcc \ 67 | gnutls-dev \ 68 | libaio-dev \ 69 | libbz2-dev \ 70 | libc-dev \ 71 | libcap-dev \ 72 | libcap-ng-dev \ 73 | libcurl4-gnutls-dev \ 74 | libglib2.0-dev \ 75 | libiscsi-dev \ 76 | libjpeg-dev \ 77 | libncursesw5-dev \ 78 | libnfs-dev \ 79 | libnuma-dev \ 80 | libpixman-1-dev \ 81 | libpng-dev \ 82 | librbd-dev \ 83 | libseccomp-dev \ 84 | libssh-dev \ 85 | libusb-1.0-0-dev \ 86 | libusbredirparser-dev \ 87 | libxen-dev \ 88 | make \ 89 | pkg-config \ 90 | python3 \ 91 | zlib1g-dev \ 92 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 93 | ninja-build \ 94 | python3-setuptools \ 95 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 96 | libfuse3-dev \ 97 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 98 | libslirp-dev \ 99 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 100 | python3-venv \ 101 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 102 | git \ 103 | ; \ 104 | \ 105 | tarball="$(basename "$QEMU_URL")"; \ 106 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 107 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 108 | \ 109 | export GNUPGHOME="$(mktemp -d)"; \ 110 | for key in $QEMU_KEYS; do \ 111 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 112 | done; \ 113 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 114 | gpgconf --kill all; \ 115 | rm -rf "$GNUPGHOME"; \ 116 | \ 117 | mkdir /usr/src/qemu; \ 118 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 119 | rm "$tarball" "$tarball.sig"; \ 120 | \ 121 | cd /usr/src/qemu; \ 122 | \ 123 | for p in /qemu-patches/*.patch; do \ 124 | patch --strip 1 --input "$p"; \ 125 | done; \ 126 | rm -rf /qemu-patches; \ 127 | \ 128 | arch="$(dpkg --print-architecture)"; \ 129 | case "$arch" in \ 130 | amd64) targetList='x86_64-softmmu' ;; \ 131 | arm64) targetList='aarch64-softmmu' ;; \ 132 | armel | armhf) targetList='arm-softmmu' ;; \ 133 | i386) targetList='i386-softmmu' ;; \ 134 | mips64el) targetList='mips64el-softmmu' ;; \ 135 | ppc64el) targetList='ppc64-softmmu' ;; \ 136 | s390x) targetList='s390x-softmmu' ;; \ 137 | *) echo >&2 "error: architecture '$arch' unimplemented 😅"; exit 1 ;; \ 138 | esac; \ 139 | \ 140 | ./configure --help; \ 141 | ./configure \ 142 | # let's add a link to our source code in the output of "--version" in case our users end up filing bugs against the QEMU project O:) 143 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 144 | --target-list="$targetList" \ 145 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 146 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 147 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 148 | --disable-docs \ 149 | --disable-gtk --disable-vte \ 150 | --disable-sdl \ 151 | --enable-attr \ 152 | --enable-bzip2 \ 153 | --enable-cap-ng \ 154 | --enable-curl \ 155 | --enable-curses \ 156 | --enable-fdt \ 157 | --enable-gnutls \ 158 | --enable-kvm \ 159 | --enable-libiscsi \ 160 | --enable-libnfs \ 161 | --enable-libssh \ 162 | --enable-libusb \ 163 | --enable-linux-aio \ 164 | --enable-modules \ 165 | --enable-numa \ 166 | --enable-rbd \ 167 | --enable-seccomp \ 168 | --enable-strip \ 169 | --enable-tools \ 170 | --enable-usb-redir \ 171 | --enable-vhost-net \ 172 | --enable-vhost-user \ 173 | --enable-vhost-vdpa \ 174 | --enable-virtfs \ 175 | --enable-vnc \ 176 | --enable-vnc-jpeg \ 177 | --enable-xen \ 178 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 179 | # --enable-vde \ 180 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 181 | --enable-fuse \ 182 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 183 | --enable-slirp \ 184 | ; \ 185 | make -j "$(nproc)"; \ 186 | make install; \ 187 | \ 188 | cd /; \ 189 | rm -rf /usr/src/qemu; \ 190 | \ 191 | apt-mark auto '.*' > /dev/null; \ 192 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 193 | find /usr/local \ 194 | -type f \ 195 | \( -executable -o -name '*.so' \) \ 196 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 197 | -not -name 'block-rbd.so' \ 198 | -exec ldd '{}' ';' \ 199 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 200 | | sort -u \ 201 | | xargs -r dpkg-query --search \ 202 | | cut -d: -f1 \ 203 | | sort -u \ 204 | | xargs -r apt-mark manual \ 205 | ; \ 206 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 207 | apt-get dist-clean; \ 208 | \ 209 | # basic smoke test 210 | qemu-img --version 211 | 212 | STOPSIGNAL SIGHUP 213 | 214 | EXPOSE 22 215 | EXPOSE 5900 216 | 217 | COPY start-qemu /usr/local/bin/ 218 | CMD ["start-qemu"] 219 | -------------------------------------------------------------------------------- /10.1/qemu-signals.patch: -------------------------------------------------------------------------------- 1 | Origin: https://bugs.launchpad.net/qemu/+bug/1217339/comments/2 2 | Origin: https://lists.nongnu.org/archive/html/qemu-devel/2017-03/msg03039.html 3 | 4 | diff --git a/system/runstate.c b/system/runstate.c 5 | index 6178b0091a..dda0d43c1b 100644 6 | --- a/system/runstate.c 7 | +++ b/system/runstate.c 8 | @@ -780,8 +780,12 @@ void qemu_system_killed(int signal, pid_t pid) 9 | /* Cannot call qemu_system_shutdown_request directly because 10 | * we are in a signal handler. 11 | */ 12 | + if (signal == SIGHUP) { 13 | + powerdown_requested = 1; 14 | + } else { // indentation of the following is "wrong" on purpose so the patch diff is smaller (and the relation to the original code more obvious) 15 | shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 16 | force_shutdown = true; 17 | + } 18 | qemu_notify_event(); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /10.1/start-qemu: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # main available options: 5 | # QEMU_CPU=n (cores) 6 | # QEMU_RAM=nnn (megabytes) 7 | # QEMU_HDA (filename) 8 | # QEMU_HDA_SIZE (bytes, suffixes like "G" allowed) 9 | # QEMU_CDROM (filename) 10 | # QEMU_BOOT (-boot) 11 | # QEMU_PORTS="xxx[ xxx ...]" (space separated port numbers) 12 | # QEMU_NET_USER_EXTRA="net=192.168.76.0/24,dhcpstart=192.168.76.9" (extra raw args for "-net user,...") 13 | # QEMU_NO_NET=1 (suppress ALL -netdev - thus no port forwards, etc) 14 | # QEMU_NO_SSH=1 (suppress automatic port 22 forwarding) 15 | # QEMU_NO_SERIAL=1 (suppress automatic "-serial stdio") 16 | # QEMU_NO_VNC=1 (suppress automatic "-vnc ':0'") 17 | 18 | hostArch="$(uname -m)" 19 | qemuArch="${QEMU_ARCH:-$hostArch}" 20 | qemu="${QEMU_BIN:-qemu-system-$qemuArch}" 21 | qemuArgs=() 22 | 23 | qemuPorts=() 24 | if [ -z "${QEMU_NO_SSH:-}" ]; then 25 | qemuPorts+=( 22 ) 26 | fi 27 | qemuPorts+=( ${QEMU_PORTS:-} ) 28 | 29 | if [ -e /dev/kvm ] && sh -c 'echo -n > /dev/kvm' &> /dev/null; then 30 | # https://github.com/tianon/docker-qemu/issues/4 31 | qemuArgs+=( -enable-kvm ) 32 | elif [ "$hostArch" = "$qemuArch" ]; then 33 | echo >&2 34 | echo >&2 'warning: /dev/kvm not found' 35 | echo >&2 ' PERFORMANCE WILL SUFFER' 36 | echo >&2 ' (hint: docker run --device /dev/kvm ...)' 37 | echo >&2 38 | sleep 3 39 | fi 40 | 41 | qemuArgs+=( -smp "${QEMU_CPU:-1}" ) 42 | qemuArgs+=( -m "${QEMU_RAM:-512}" ) 43 | 44 | if [ -n "${QEMU_HDA:-}" ]; then 45 | if [ ! -f "$QEMU_HDA" -o ! -s "$QEMU_HDA" ]; then 46 | ( 47 | set -x 48 | qemu-img create -f qcow2 -o preallocation=off "$QEMU_HDA" "${QEMU_HDA_SIZE:-8G}" 49 | ) 50 | fi 51 | 52 | # http://wiki.qemu.org/download/qemu-doc.html#Invocation 53 | qemuScsiDevice='virtio-scsi-pci' 54 | case "$qemuArch" in 55 | arm | riscv64) qemuScsiDevice='virtio-scsi-device' ;; 56 | esac 57 | 58 | #qemuArgs+=( -hda "$QEMU_HDA" ) 59 | #qemuArgs+=( -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap ) 60 | qemuArgs+=( 61 | -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap,detect-zeroes=unmap,if=none,id=hda 62 | -device "$qemuScsiDevice" 63 | -device scsi-hd,drive=hda 64 | ) 65 | fi 66 | 67 | if [ -n "${QEMU_CDROM:-}" ]; then 68 | qemuArgs+=( -cdrom "$QEMU_CDROM" ) 69 | fi 70 | 71 | if [ -n "${QEMU_BOOT:-}" ]; then 72 | qemuArgs+=( -boot "$QEMU_BOOT" ) 73 | fi 74 | 75 | if [ -z "${QEMU_NO_NET:-}" ]; then 76 | netArg='user' 77 | netArg+=",hostname=$(hostname)" 78 | if [ -n "${QEMU_NET_USER_EXTRA:-}" ]; then 79 | netArg+=",$QEMU_NET_USER_EXTRA" 80 | fi 81 | for port in "${qemuPorts[@]}"; do 82 | netArg+=",hostfwd=tcp::$port-:$port" 83 | netArg+=",hostfwd=udp::$port-:$port" 84 | done 85 | 86 | qemuNetDevice='virtio-net-pci' 87 | case "$qemuArch" in 88 | arm | riscv64) qemuNetDevice='virtio-net-device' ;; 89 | esac 90 | 91 | qemuArgs+=( 92 | -netdev "$netArg,id=net" 93 | -device "$qemuNetDevice,netdev=net" 94 | ) 95 | fi 96 | 97 | if [ -z "${QEMU_NO_SERIAL:-}" ]; then 98 | qemuArgs+=( 99 | -serial stdio 100 | ) 101 | fi 102 | 103 | if [ -z "${QEMU_NO_VNC:-}" ]; then 104 | qemuArgs+=( 105 | -vnc ':0' 106 | ) 107 | fi 108 | 109 | qemuArgs+=( "$@" ) 110 | 111 | set -x 112 | exec "$qemu" "${qemuArgs[@]}" 113 | -------------------------------------------------------------------------------- /7.2/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM debian:trixie-slim 8 | 9 | RUN set -eux; \ 10 | # add backports for (potentially) newer QEMU firmware packages 11 | if grep backports /etc/apt/sources.list.d/debian.sources; then exit 1; fi; \ 12 | sed -ri -e 's/([[:space:]])([^[:space:]]+)-updates($|[[:space:]])/\0\1\2-backports\3/' /etc/apt/sources.list.d/debian.sources; \ 13 | grep backports /etc/apt/sources.list.d/debian.sources; \ 14 | # and add APT pinning to ensure we don't accidentally get QEMU from Debian 15 | { \ 16 | echo 'Package: src:edk2'; \ 17 | echo 'Pin: release a=*-backports'; \ 18 | echo 'Pin-Priority: 600'; \ 19 | echo; \ 20 | echo 'Package: src:qemu'; \ 21 | echo 'Pin: version *'; \ 22 | echo 'Pin-Priority: -10'; \ 23 | } > /etc/apt/preferences.d/qemu.pref; \ 24 | apt-get update; \ 25 | # https://github.com/tianon/docker-qemu/issues/30 26 | apt-get install -y --no-install-recommends ca-certificates; \ 27 | # include "swtpm" for TPM emulation -- not automatically launched, but small and useful for running a TPM sidecar container (https://qemu-project.gitlab.io/qemu/specs/tpm.html#the-qemu-tpm-emulator-device) 28 | apt-get install -y --no-install-recommends swtpm; \ 29 | # install "firmware" packages (easier UEFI, etc) 30 | apt-get install -y --no-install-recommends \ 31 | # amd64 32 | ovmf \ 33 | # arm64 34 | qemu-efi-aarch64 \ 35 | # armel | armhf 36 | qemu-efi-arm \ 37 | # i386 38 | ovmf-ia32 \ 39 | # riscv64 40 | opensbi u-boot-qemu \ 41 | ; \ 42 | apt-get dist-clean 43 | 44 | COPY *.patch /qemu-patches/ 45 | 46 | # https://wiki.qemu.org/SecurityProcess 47 | ENV QEMU_KEYS \ 48 | # Michael Roth 49 | CEACC9E15534EBABB82D3FA03353C9CEF108B584 50 | # https://wiki.qemu.org/Planning/ReleaseProcess#Sign_the_resulting_tarball_with_GPG: (they get signed by whoever is making the release) 51 | 52 | # https://www.qemu.org/download/#source 53 | # https://download.qemu.org/?C=M;O=D 54 | ENV QEMU_VERSION 7.2.21 55 | ENV QEMU_URL https://download.qemu.org/qemu-7.2.21.tar.xz 56 | 57 | RUN set -eux; \ 58 | \ 59 | savedAptMark="$(apt-mark showmanual)"; \ 60 | \ 61 | apt-get install --update -y --no-install-recommends \ 62 | gnupg \ 63 | wget \ 64 | xz-utils \ 65 | \ 66 | patch \ 67 | \ 68 | bzip2 \ 69 | gcc \ 70 | gnutls-dev \ 71 | libaio-dev \ 72 | libbz2-dev \ 73 | libc-dev \ 74 | libcap-dev \ 75 | libcap-ng-dev \ 76 | libcurl4-gnutls-dev \ 77 | libglib2.0-dev \ 78 | libiscsi-dev \ 79 | libjpeg-dev \ 80 | libncursesw5-dev \ 81 | libnfs-dev \ 82 | libnuma-dev \ 83 | libpixman-1-dev \ 84 | libpng-dev \ 85 | librbd-dev \ 86 | libseccomp-dev \ 87 | libssh-dev \ 88 | libusb-1.0-0-dev \ 89 | libusbredirparser-dev \ 90 | libxen-dev \ 91 | make \ 92 | pkg-config \ 93 | python3 \ 94 | zlib1g-dev \ 95 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 96 | ninja-build \ 97 | python3-setuptools \ 98 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 99 | libfuse3-dev \ 100 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 101 | libslirp-dev \ 102 | ; \ 103 | \ 104 | tarball="$(basename "$QEMU_URL")"; \ 105 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 106 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 107 | \ 108 | export GNUPGHOME="$(mktemp -d)"; \ 109 | for key in $QEMU_KEYS; do \ 110 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 111 | done; \ 112 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 113 | gpgconf --kill all; \ 114 | rm -rf "$GNUPGHOME"; \ 115 | \ 116 | mkdir /usr/src/qemu; \ 117 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 118 | rm "$tarball" "$tarball.sig"; \ 119 | \ 120 | cd /usr/src/qemu; \ 121 | \ 122 | for p in /qemu-patches/*.patch; do \ 123 | patch --strip 1 --input "$p"; \ 124 | done; \ 125 | rm -rf /qemu-patches; \ 126 | \ 127 | ./configure --help; \ 128 | ./configure \ 129 | # let's add a link to our source code in the output of "--version" in case our users end up filing bugs against the QEMU project O:) 130 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 131 | --target-list=' \ 132 | # system targets 133 | # (https://sources.debian.org/src/qemu/buster/debian/rules/#L59-L63, slimmed) 134 | i386-softmmu x86_64-softmmu aarch64-softmmu arm-softmmu m68k-softmmu \ 135 | mips64-softmmu mips64el-softmmu ppc64-softmmu riscv64-softmmu \ 136 | sparc64-softmmu s390x-softmmu \ 137 | ' \ 138 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 139 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 140 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 141 | --disable-docs \ 142 | --disable-gtk --disable-vte \ 143 | --disable-sdl \ 144 | --enable-attr \ 145 | --enable-bzip2 \ 146 | --enable-cap-ng \ 147 | --enable-curl \ 148 | --enable-curses \ 149 | --enable-fdt \ 150 | --enable-gnutls \ 151 | --enable-kvm \ 152 | --enable-libiscsi \ 153 | --enable-libnfs \ 154 | --enable-libssh \ 155 | --enable-libusb \ 156 | --enable-linux-aio \ 157 | --enable-modules \ 158 | --enable-numa \ 159 | --enable-rbd \ 160 | --enable-seccomp \ 161 | --enable-strip \ 162 | --enable-tools \ 163 | --enable-usb-redir \ 164 | --enable-vhost-net \ 165 | --enable-vhost-user \ 166 | --enable-vhost-vdpa \ 167 | --enable-virtfs \ 168 | --enable-vnc \ 169 | --enable-vnc-jpeg \ 170 | --enable-xen \ 171 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 172 | # --enable-vde \ 173 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 174 | --enable-fuse \ 175 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 176 | --enable-slirp \ 177 | ; \ 178 | make -j "$(nproc)"; \ 179 | make install; \ 180 | \ 181 | cd /; \ 182 | rm -rf /usr/src/qemu; \ 183 | \ 184 | apt-mark auto '.*' > /dev/null; \ 185 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 186 | find /usr/local \ 187 | -type f \ 188 | \( -executable -o -name '*.so' \) \ 189 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 190 | -not -name 'block-rbd.so' \ 191 | -exec ldd '{}' ';' \ 192 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 193 | | sort -u \ 194 | | xargs -r dpkg-query --search \ 195 | | cut -d: -f1 \ 196 | | sort -u \ 197 | | xargs -r apt-mark manual \ 198 | ; \ 199 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 200 | apt-get dist-clean; \ 201 | \ 202 | # basic smoke test 203 | qemu-img --version 204 | 205 | STOPSIGNAL SIGHUP 206 | 207 | EXPOSE 22 208 | EXPOSE 5900 209 | 210 | COPY start-qemu /usr/local/bin/ 211 | CMD ["start-qemu"] 212 | -------------------------------------------------------------------------------- /7.2/Dockerfile.native: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM debian:trixie-slim 8 | 9 | RUN set -eux; \ 10 | # add backports for (potentially) newer QEMU firmware packages 11 | if grep backports /etc/apt/sources.list.d/debian.sources; then exit 1; fi; \ 12 | sed -ri -e 's/([[:space:]])([^[:space:]]+)-updates($|[[:space:]])/\0\1\2-backports\3/' /etc/apt/sources.list.d/debian.sources; \ 13 | grep backports /etc/apt/sources.list.d/debian.sources; \ 14 | # and add APT pinning to ensure we don't accidentally get QEMU from Debian 15 | { \ 16 | echo 'Package: src:edk2'; \ 17 | echo 'Pin: release a=*-backports'; \ 18 | echo 'Pin-Priority: 600'; \ 19 | echo; \ 20 | echo 'Package: src:qemu'; \ 21 | echo 'Pin: version *'; \ 22 | echo 'Pin-Priority: -10'; \ 23 | } > /etc/apt/preferences.d/qemu.pref; \ 24 | apt-get update; \ 25 | # https://github.com/tianon/docker-qemu/issues/30 26 | apt-get install -y --no-install-recommends ca-certificates; \ 27 | # include "swtpm" for TPM emulation -- not automatically launched, but small and useful for running a TPM sidecar container (https://qemu-project.gitlab.io/qemu/specs/tpm.html#the-qemu-tpm-emulator-device) 28 | apt-get install -y --no-install-recommends swtpm; \ 29 | # install "firmware" packages (easier UEFI, etc) 30 | arch="$(dpkg --print-architecture)"; \ 31 | case "$arch" in \ 32 | amd64) apt-get install -y --no-install-recommends ovmf ;; \ 33 | arm64) apt-get install -y --no-install-recommends qemu-efi-aarch64 ;; \ 34 | armel | armhf) apt-get install -y --no-install-recommends qemu-efi-arm ;; \ 35 | i386) apt-get install -y --no-install-recommends ovmf-ia32 ;; \ 36 | riscv64) apt-get install -y --no-install-recommends opensbi u-boot-qemu ;; \ 37 | *) echo >&2 "warning: architecture '$arch' unknown 😅 (is there a 'QEMU firmware' package that should be installed here? likely candidates: https://packages.debian.org/source/$suite/edk2)" ;; \ 38 | esac; \ 39 | apt-get dist-clean 40 | 41 | COPY *.patch /qemu-patches/ 42 | 43 | # https://wiki.qemu.org/SecurityProcess 44 | ENV QEMU_KEYS \ 45 | # Michael Roth 46 | CEACC9E15534EBABB82D3FA03353C9CEF108B584 47 | # https://wiki.qemu.org/Planning/ReleaseProcess#Sign_the_resulting_tarball_with_GPG: (they get signed by whoever is making the release) 48 | 49 | # https://www.qemu.org/download/#source 50 | # https://download.qemu.org/?C=M;O=D 51 | ENV QEMU_VERSION 7.2.21 52 | ENV QEMU_URL https://download.qemu.org/qemu-7.2.21.tar.xz 53 | 54 | RUN set -eux; \ 55 | \ 56 | savedAptMark="$(apt-mark showmanual)"; \ 57 | \ 58 | apt-get install --update -y --no-install-recommends \ 59 | gnupg \ 60 | wget \ 61 | xz-utils \ 62 | \ 63 | patch \ 64 | \ 65 | bzip2 \ 66 | gcc \ 67 | gnutls-dev \ 68 | libaio-dev \ 69 | libbz2-dev \ 70 | libc-dev \ 71 | libcap-dev \ 72 | libcap-ng-dev \ 73 | libcurl4-gnutls-dev \ 74 | libglib2.0-dev \ 75 | libiscsi-dev \ 76 | libjpeg-dev \ 77 | libncursesw5-dev \ 78 | libnfs-dev \ 79 | libnuma-dev \ 80 | libpixman-1-dev \ 81 | libpng-dev \ 82 | librbd-dev \ 83 | libseccomp-dev \ 84 | libssh-dev \ 85 | libusb-1.0-0-dev \ 86 | libusbredirparser-dev \ 87 | libxen-dev \ 88 | make \ 89 | pkg-config \ 90 | python3 \ 91 | zlib1g-dev \ 92 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 93 | ninja-build \ 94 | python3-setuptools \ 95 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 96 | libfuse3-dev \ 97 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 98 | libslirp-dev \ 99 | ; \ 100 | \ 101 | tarball="$(basename "$QEMU_URL")"; \ 102 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 103 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 104 | \ 105 | export GNUPGHOME="$(mktemp -d)"; \ 106 | for key in $QEMU_KEYS; do \ 107 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 108 | done; \ 109 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 110 | gpgconf --kill all; \ 111 | rm -rf "$GNUPGHOME"; \ 112 | \ 113 | mkdir /usr/src/qemu; \ 114 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 115 | rm "$tarball" "$tarball.sig"; \ 116 | \ 117 | cd /usr/src/qemu; \ 118 | \ 119 | for p in /qemu-patches/*.patch; do \ 120 | patch --strip 1 --input "$p"; \ 121 | done; \ 122 | rm -rf /qemu-patches; \ 123 | \ 124 | arch="$(dpkg --print-architecture)"; \ 125 | case "$arch" in \ 126 | amd64) targetList='x86_64-softmmu' ;; \ 127 | arm64) targetList='aarch64-softmmu' ;; \ 128 | armel | armhf) targetList='arm-softmmu' ;; \ 129 | i386) targetList='i386-softmmu' ;; \ 130 | mips64el) targetList='mips64el-softmmu' ;; \ 131 | ppc64el) targetList='ppc64-softmmu' ;; \ 132 | s390x) targetList='s390x-softmmu' ;; \ 133 | *) echo >&2 "error: architecture '$arch' unimplemented 😅"; exit 1 ;; \ 134 | esac; \ 135 | \ 136 | ./configure --help; \ 137 | ./configure \ 138 | # let's add a link to our source code in the output of "--version" in case our users end up filing bugs against the QEMU project O:) 139 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 140 | --target-list="$targetList" \ 141 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 142 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 143 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 144 | --disable-docs \ 145 | --disable-gtk --disable-vte \ 146 | --disable-sdl \ 147 | --enable-attr \ 148 | --enable-bzip2 \ 149 | --enable-cap-ng \ 150 | --enable-curl \ 151 | --enable-curses \ 152 | --enable-fdt \ 153 | --enable-gnutls \ 154 | --enable-kvm \ 155 | --enable-libiscsi \ 156 | --enable-libnfs \ 157 | --enable-libssh \ 158 | --enable-libusb \ 159 | --enable-linux-aio \ 160 | --enable-modules \ 161 | --enable-numa \ 162 | --enable-rbd \ 163 | --enable-seccomp \ 164 | --enable-strip \ 165 | --enable-tools \ 166 | --enable-usb-redir \ 167 | --enable-vhost-net \ 168 | --enable-vhost-user \ 169 | --enable-vhost-vdpa \ 170 | --enable-virtfs \ 171 | --enable-vnc \ 172 | --enable-vnc-jpeg \ 173 | --enable-xen \ 174 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 175 | # --enable-vde \ 176 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 177 | --enable-fuse \ 178 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 179 | --enable-slirp \ 180 | ; \ 181 | make -j "$(nproc)"; \ 182 | make install; \ 183 | \ 184 | cd /; \ 185 | rm -rf /usr/src/qemu; \ 186 | \ 187 | apt-mark auto '.*' > /dev/null; \ 188 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 189 | find /usr/local \ 190 | -type f \ 191 | \( -executable -o -name '*.so' \) \ 192 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 193 | -not -name 'block-rbd.so' \ 194 | -exec ldd '{}' ';' \ 195 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 196 | | sort -u \ 197 | | xargs -r dpkg-query --search \ 198 | | cut -d: -f1 \ 199 | | sort -u \ 200 | | xargs -r apt-mark manual \ 201 | ; \ 202 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 203 | apt-get dist-clean; \ 204 | \ 205 | # basic smoke test 206 | qemu-img --version 207 | 208 | STOPSIGNAL SIGHUP 209 | 210 | EXPOSE 22 211 | EXPOSE 5900 212 | 213 | COPY start-qemu /usr/local/bin/ 214 | CMD ["start-qemu"] 215 | -------------------------------------------------------------------------------- /7.2/qemu-signals.patch: -------------------------------------------------------------------------------- 1 | Origin: https://bugs.launchpad.net/qemu/+bug/1217339/comments/2 2 | Origin: https://lists.nongnu.org/archive/html/qemu-devel/2017-03/msg03039.html 3 | 4 | diff --git a/softmmu/runstate.c b/softmmu/runstate.c 5 | index 3dd83d5e5d..2d3552aa67 100644 6 | --- a/softmmu/runstate.c 7 | +++ b/softmmu/runstate.c 8 | @@ -621,7 +621,11 @@ void qemu_system_killed(int signal, pid_t pid) 9 | /* Cannot call qemu_system_shutdown_request directly because 10 | * we are in a signal handler. 11 | */ 12 | + if (signal == SIGHUP) { 13 | + powerdown_requested = 1; 14 | + } else { // indentation of the following is "wrong" on purpose so the patch diff is smaller (and the relation to the original code more obvious) 15 | shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 16 | + } 17 | qemu_notify_event(); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /7.2/start-qemu: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # main available options: 5 | # QEMU_CPU=n (cores) 6 | # QEMU_RAM=nnn (megabytes) 7 | # QEMU_HDA (filename) 8 | # QEMU_HDA_SIZE (bytes, suffixes like "G" allowed) 9 | # QEMU_CDROM (filename) 10 | # QEMU_BOOT (-boot) 11 | # QEMU_PORTS="xxx[ xxx ...]" (space separated port numbers) 12 | # QEMU_NET_USER_EXTRA="net=192.168.76.0/24,dhcpstart=192.168.76.9" (extra raw args for "-net user,...") 13 | # QEMU_NO_NET=1 (suppress ALL -netdev - thus no port forwards, etc) 14 | # QEMU_NO_SSH=1 (suppress automatic port 22 forwarding) 15 | # QEMU_NO_SERIAL=1 (suppress automatic "-serial stdio") 16 | # QEMU_NO_VNC=1 (suppress automatic "-vnc ':0'") 17 | 18 | hostArch="$(uname -m)" 19 | qemuArch="${QEMU_ARCH:-$hostArch}" 20 | qemu="${QEMU_BIN:-qemu-system-$qemuArch}" 21 | qemuArgs=() 22 | 23 | qemuPorts=() 24 | if [ -z "${QEMU_NO_SSH:-}" ]; then 25 | qemuPorts+=( 22 ) 26 | fi 27 | qemuPorts+=( ${QEMU_PORTS:-} ) 28 | 29 | if [ -e /dev/kvm ] && sh -c 'echo -n > /dev/kvm' &> /dev/null; then 30 | # https://github.com/tianon/docker-qemu/issues/4 31 | qemuArgs+=( -enable-kvm ) 32 | elif [ "$hostArch" = "$qemuArch" ]; then 33 | echo >&2 34 | echo >&2 'warning: /dev/kvm not found' 35 | echo >&2 ' PERFORMANCE WILL SUFFER' 36 | echo >&2 ' (hint: docker run --device /dev/kvm ...)' 37 | echo >&2 38 | sleep 3 39 | fi 40 | 41 | qemuArgs+=( -smp "${QEMU_CPU:-1}" ) 42 | qemuArgs+=( -m "${QEMU_RAM:-512}" ) 43 | 44 | if [ -n "${QEMU_HDA:-}" ]; then 45 | if [ ! -f "$QEMU_HDA" -o ! -s "$QEMU_HDA" ]; then 46 | ( 47 | set -x 48 | qemu-img create -f qcow2 -o preallocation=off "$QEMU_HDA" "${QEMU_HDA_SIZE:-8G}" 49 | ) 50 | fi 51 | 52 | # http://wiki.qemu.org/download/qemu-doc.html#Invocation 53 | qemuScsiDevice='virtio-scsi-pci' 54 | case "$qemuArch" in 55 | arm | riscv64) qemuScsiDevice='virtio-scsi-device' ;; 56 | esac 57 | 58 | #qemuArgs+=( -hda "$QEMU_HDA" ) 59 | #qemuArgs+=( -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap ) 60 | qemuArgs+=( 61 | -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap,detect-zeroes=unmap,if=none,id=hda 62 | -device "$qemuScsiDevice" 63 | -device scsi-hd,drive=hda 64 | ) 65 | fi 66 | 67 | if [ -n "${QEMU_CDROM:-}" ]; then 68 | qemuArgs+=( -cdrom "$QEMU_CDROM" ) 69 | fi 70 | 71 | if [ -n "${QEMU_BOOT:-}" ]; then 72 | qemuArgs+=( -boot "$QEMU_BOOT" ) 73 | fi 74 | 75 | if [ -z "${QEMU_NO_NET:-}" ]; then 76 | netArg='user' 77 | netArg+=",hostname=$(hostname)" 78 | if [ -n "${QEMU_NET_USER_EXTRA:-}" ]; then 79 | netArg+=",$QEMU_NET_USER_EXTRA" 80 | fi 81 | for port in "${qemuPorts[@]}"; do 82 | netArg+=",hostfwd=tcp::$port-:$port" 83 | netArg+=",hostfwd=udp::$port-:$port" 84 | done 85 | 86 | qemuNetDevice='virtio-net-pci' 87 | case "$qemuArch" in 88 | arm | riscv64) qemuNetDevice='virtio-net-device' ;; 89 | esac 90 | 91 | qemuArgs+=( 92 | -netdev "$netArg,id=net" 93 | -device "$qemuNetDevice,netdev=net" 94 | ) 95 | fi 96 | 97 | if [ -z "${QEMU_NO_SERIAL:-}" ]; then 98 | qemuArgs+=( 99 | -serial stdio 100 | ) 101 | fi 102 | 103 | if [ -z "${QEMU_NO_VNC:-}" ]; then 104 | qemuArgs+=( 105 | -vnc ':0' 106 | ) 107 | fi 108 | 109 | qemuArgs+=( "$@" ) 110 | 111 | set -x 112 | exec "$qemu" "${qemuArgs[@]}" 113 | -------------------------------------------------------------------------------- /9.1/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM debian:trixie-slim 8 | 9 | RUN set -eux; \ 10 | # add backports for (potentially) newer QEMU firmware packages 11 | if grep backports /etc/apt/sources.list.d/debian.sources; then exit 1; fi; \ 12 | sed -ri -e 's/([[:space:]])([^[:space:]]+)-updates($|[[:space:]])/\0\1\2-backports\3/' /etc/apt/sources.list.d/debian.sources; \ 13 | grep backports /etc/apt/sources.list.d/debian.sources; \ 14 | # and add APT pinning to ensure we don't accidentally get QEMU from Debian 15 | { \ 16 | echo 'Package: src:edk2'; \ 17 | echo 'Pin: release a=*-backports'; \ 18 | echo 'Pin-Priority: 600'; \ 19 | echo; \ 20 | echo 'Package: src:qemu'; \ 21 | echo 'Pin: version *'; \ 22 | echo 'Pin-Priority: -10'; \ 23 | } > /etc/apt/preferences.d/qemu.pref; \ 24 | apt-get update; \ 25 | # https://github.com/tianon/docker-qemu/issues/30 26 | apt-get install -y --no-install-recommends ca-certificates; \ 27 | # include "swtpm" for TPM emulation -- not automatically launched, but small and useful for running a TPM sidecar container (https://qemu-project.gitlab.io/qemu/specs/tpm.html#the-qemu-tpm-emulator-device) 28 | apt-get install -y --no-install-recommends swtpm; \ 29 | # install "firmware" packages (easier UEFI, etc) 30 | apt-get install -y --no-install-recommends \ 31 | # amd64 32 | ovmf \ 33 | # arm64 34 | qemu-efi-aarch64 \ 35 | # armel | armhf 36 | qemu-efi-arm \ 37 | # i386 38 | ovmf-ia32 \ 39 | # riscv64 40 | opensbi u-boot-qemu \ 41 | ; \ 42 | apt-get dist-clean 43 | 44 | COPY *.patch /qemu-patches/ 45 | 46 | # https://wiki.qemu.org/SecurityProcess 47 | ENV QEMU_KEYS \ 48 | # Michael Roth 49 | CEACC9E15534EBABB82D3FA03353C9CEF108B584 50 | # https://wiki.qemu.org/Planning/ReleaseProcess#Sign_the_resulting_tarball_with_GPG: (they get signed by whoever is making the release) 51 | 52 | # https://www.qemu.org/download/#source 53 | # https://download.qemu.org/?C=M;O=D 54 | ENV QEMU_VERSION 9.1.3 55 | ENV QEMU_URL https://download.qemu.org/qemu-9.1.3.tar.xz 56 | 57 | RUN set -eux; \ 58 | \ 59 | savedAptMark="$(apt-mark showmanual)"; \ 60 | \ 61 | apt-get install --update -y --no-install-recommends \ 62 | gnupg \ 63 | wget \ 64 | xz-utils \ 65 | \ 66 | patch \ 67 | \ 68 | bzip2 \ 69 | gcc \ 70 | gnutls-dev \ 71 | libaio-dev \ 72 | libbz2-dev \ 73 | libc-dev \ 74 | libcap-dev \ 75 | libcap-ng-dev \ 76 | libcurl4-gnutls-dev \ 77 | libglib2.0-dev \ 78 | libiscsi-dev \ 79 | libjpeg-dev \ 80 | libncursesw5-dev \ 81 | libnfs-dev \ 82 | libnuma-dev \ 83 | libpixman-1-dev \ 84 | libpng-dev \ 85 | librbd-dev \ 86 | libseccomp-dev \ 87 | libssh-dev \ 88 | libusb-1.0-0-dev \ 89 | libusbredirparser-dev \ 90 | libxen-dev \ 91 | make \ 92 | pkg-config \ 93 | python3 \ 94 | zlib1g-dev \ 95 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 96 | ninja-build \ 97 | python3-setuptools \ 98 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 99 | libfuse3-dev \ 100 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 101 | libslirp-dev \ 102 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 103 | python3-venv \ 104 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 105 | git \ 106 | ; \ 107 | \ 108 | tarball="$(basename "$QEMU_URL")"; \ 109 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 110 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 111 | \ 112 | export GNUPGHOME="$(mktemp -d)"; \ 113 | for key in $QEMU_KEYS; do \ 114 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 115 | done; \ 116 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 117 | gpgconf --kill all; \ 118 | rm -rf "$GNUPGHOME"; \ 119 | \ 120 | mkdir /usr/src/qemu; \ 121 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 122 | rm "$tarball" "$tarball.sig"; \ 123 | \ 124 | cd /usr/src/qemu; \ 125 | \ 126 | for p in /qemu-patches/*.patch; do \ 127 | patch --strip 1 --input "$p"; \ 128 | done; \ 129 | rm -rf /qemu-patches; \ 130 | \ 131 | ./configure --help; \ 132 | ./configure \ 133 | # let's add a link to our source code in the output of "--version" in case our users end up filing bugs against the QEMU project O:) 134 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 135 | --target-list=' \ 136 | # system targets 137 | # (https://sources.debian.org/src/qemu/buster/debian/rules/#L59-L63, slimmed) 138 | i386-softmmu x86_64-softmmu aarch64-softmmu arm-softmmu m68k-softmmu \ 139 | mips64-softmmu mips64el-softmmu ppc64-softmmu riscv64-softmmu \ 140 | sparc64-softmmu s390x-softmmu \ 141 | ' \ 142 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 143 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 144 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 145 | --disable-docs \ 146 | --disable-gtk --disable-vte \ 147 | --disable-sdl \ 148 | --enable-attr \ 149 | --enable-bzip2 \ 150 | --enable-cap-ng \ 151 | --enable-curl \ 152 | --enable-curses \ 153 | --enable-fdt \ 154 | --enable-gnutls \ 155 | --enable-kvm \ 156 | --enable-libiscsi \ 157 | --enable-libnfs \ 158 | --enable-libssh \ 159 | --enable-libusb \ 160 | --enable-linux-aio \ 161 | --enable-modules \ 162 | --enable-numa \ 163 | --enable-rbd \ 164 | --enable-seccomp \ 165 | --enable-strip \ 166 | --enable-tools \ 167 | --enable-usb-redir \ 168 | --enable-vhost-net \ 169 | --enable-vhost-user \ 170 | --enable-vhost-vdpa \ 171 | --enable-virtfs \ 172 | --enable-vnc \ 173 | --enable-vnc-jpeg \ 174 | --enable-xen \ 175 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 176 | # --enable-vde \ 177 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 178 | --enable-fuse \ 179 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 180 | --enable-slirp \ 181 | ; \ 182 | make -j "$(nproc)"; \ 183 | make install; \ 184 | \ 185 | cd /; \ 186 | rm -rf /usr/src/qemu; \ 187 | \ 188 | apt-mark auto '.*' > /dev/null; \ 189 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 190 | find /usr/local \ 191 | -type f \ 192 | \( -executable -o -name '*.so' \) \ 193 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 194 | -not -name 'block-rbd.so' \ 195 | -exec ldd '{}' ';' \ 196 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 197 | | sort -u \ 198 | | xargs -r dpkg-query --search \ 199 | | cut -d: -f1 \ 200 | | sort -u \ 201 | | xargs -r apt-mark manual \ 202 | ; \ 203 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 204 | apt-get dist-clean; \ 205 | \ 206 | # basic smoke test 207 | qemu-img --version 208 | 209 | STOPSIGNAL SIGHUP 210 | 211 | EXPOSE 22 212 | EXPOSE 5900 213 | 214 | COPY start-qemu /usr/local/bin/ 215 | CMD ["start-qemu"] 216 | -------------------------------------------------------------------------------- /9.1/Dockerfile.native: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM debian:trixie-slim 8 | 9 | RUN set -eux; \ 10 | # add backports for (potentially) newer QEMU firmware packages 11 | if grep backports /etc/apt/sources.list.d/debian.sources; then exit 1; fi; \ 12 | sed -ri -e 's/([[:space:]])([^[:space:]]+)-updates($|[[:space:]])/\0\1\2-backports\3/' /etc/apt/sources.list.d/debian.sources; \ 13 | grep backports /etc/apt/sources.list.d/debian.sources; \ 14 | # and add APT pinning to ensure we don't accidentally get QEMU from Debian 15 | { \ 16 | echo 'Package: src:edk2'; \ 17 | echo 'Pin: release a=*-backports'; \ 18 | echo 'Pin-Priority: 600'; \ 19 | echo; \ 20 | echo 'Package: src:qemu'; \ 21 | echo 'Pin: version *'; \ 22 | echo 'Pin-Priority: -10'; \ 23 | } > /etc/apt/preferences.d/qemu.pref; \ 24 | apt-get update; \ 25 | # https://github.com/tianon/docker-qemu/issues/30 26 | apt-get install -y --no-install-recommends ca-certificates; \ 27 | # include "swtpm" for TPM emulation -- not automatically launched, but small and useful for running a TPM sidecar container (https://qemu-project.gitlab.io/qemu/specs/tpm.html#the-qemu-tpm-emulator-device) 28 | apt-get install -y --no-install-recommends swtpm; \ 29 | # install "firmware" packages (easier UEFI, etc) 30 | arch="$(dpkg --print-architecture)"; \ 31 | case "$arch" in \ 32 | amd64) apt-get install -y --no-install-recommends ovmf ;; \ 33 | arm64) apt-get install -y --no-install-recommends qemu-efi-aarch64 ;; \ 34 | armel | armhf) apt-get install -y --no-install-recommends qemu-efi-arm ;; \ 35 | i386) apt-get install -y --no-install-recommends ovmf-ia32 ;; \ 36 | riscv64) apt-get install -y --no-install-recommends opensbi u-boot-qemu ;; \ 37 | *) echo >&2 "warning: architecture '$arch' unknown 😅 (is there a 'QEMU firmware' package that should be installed here? likely candidates: https://packages.debian.org/source/$suite/edk2)" ;; \ 38 | esac; \ 39 | apt-get dist-clean 40 | 41 | COPY *.patch /qemu-patches/ 42 | 43 | # https://wiki.qemu.org/SecurityProcess 44 | ENV QEMU_KEYS \ 45 | # Michael Roth 46 | CEACC9E15534EBABB82D3FA03353C9CEF108B584 47 | # https://wiki.qemu.org/Planning/ReleaseProcess#Sign_the_resulting_tarball_with_GPG: (they get signed by whoever is making the release) 48 | 49 | # https://www.qemu.org/download/#source 50 | # https://download.qemu.org/?C=M;O=D 51 | ENV QEMU_VERSION 9.1.3 52 | ENV QEMU_URL https://download.qemu.org/qemu-9.1.3.tar.xz 53 | 54 | RUN set -eux; \ 55 | \ 56 | savedAptMark="$(apt-mark showmanual)"; \ 57 | \ 58 | apt-get install --update -y --no-install-recommends \ 59 | gnupg \ 60 | wget \ 61 | xz-utils \ 62 | \ 63 | patch \ 64 | \ 65 | bzip2 \ 66 | gcc \ 67 | gnutls-dev \ 68 | libaio-dev \ 69 | libbz2-dev \ 70 | libc-dev \ 71 | libcap-dev \ 72 | libcap-ng-dev \ 73 | libcurl4-gnutls-dev \ 74 | libglib2.0-dev \ 75 | libiscsi-dev \ 76 | libjpeg-dev \ 77 | libncursesw5-dev \ 78 | libnfs-dev \ 79 | libnuma-dev \ 80 | libpixman-1-dev \ 81 | libpng-dev \ 82 | librbd-dev \ 83 | libseccomp-dev \ 84 | libssh-dev \ 85 | libusb-1.0-0-dev \ 86 | libusbredirparser-dev \ 87 | libxen-dev \ 88 | make \ 89 | pkg-config \ 90 | python3 \ 91 | zlib1g-dev \ 92 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 93 | ninja-build \ 94 | python3-setuptools \ 95 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 96 | libfuse3-dev \ 97 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 98 | libslirp-dev \ 99 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 100 | python3-venv \ 101 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 102 | git \ 103 | ; \ 104 | \ 105 | tarball="$(basename "$QEMU_URL")"; \ 106 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 107 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 108 | \ 109 | export GNUPGHOME="$(mktemp -d)"; \ 110 | for key in $QEMU_KEYS; do \ 111 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 112 | done; \ 113 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 114 | gpgconf --kill all; \ 115 | rm -rf "$GNUPGHOME"; \ 116 | \ 117 | mkdir /usr/src/qemu; \ 118 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 119 | rm "$tarball" "$tarball.sig"; \ 120 | \ 121 | cd /usr/src/qemu; \ 122 | \ 123 | for p in /qemu-patches/*.patch; do \ 124 | patch --strip 1 --input "$p"; \ 125 | done; \ 126 | rm -rf /qemu-patches; \ 127 | \ 128 | arch="$(dpkg --print-architecture)"; \ 129 | case "$arch" in \ 130 | amd64) targetList='x86_64-softmmu' ;; \ 131 | arm64) targetList='aarch64-softmmu' ;; \ 132 | armel | armhf) targetList='arm-softmmu' ;; \ 133 | i386) targetList='i386-softmmu' ;; \ 134 | mips64el) targetList='mips64el-softmmu' ;; \ 135 | ppc64el) targetList='ppc64-softmmu' ;; \ 136 | s390x) targetList='s390x-softmmu' ;; \ 137 | *) echo >&2 "error: architecture '$arch' unimplemented 😅"; exit 1 ;; \ 138 | esac; \ 139 | \ 140 | ./configure --help; \ 141 | ./configure \ 142 | # let's add a link to our source code in the output of "--version" in case our users end up filing bugs against the QEMU project O:) 143 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 144 | --target-list="$targetList" \ 145 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 146 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 147 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 148 | --disable-docs \ 149 | --disable-gtk --disable-vte \ 150 | --disable-sdl \ 151 | --enable-attr \ 152 | --enable-bzip2 \ 153 | --enable-cap-ng \ 154 | --enable-curl \ 155 | --enable-curses \ 156 | --enable-fdt \ 157 | --enable-gnutls \ 158 | --enable-kvm \ 159 | --enable-libiscsi \ 160 | --enable-libnfs \ 161 | --enable-libssh \ 162 | --enable-libusb \ 163 | --enable-linux-aio \ 164 | --enable-modules \ 165 | --enable-numa \ 166 | --enable-rbd \ 167 | --enable-seccomp \ 168 | --enable-strip \ 169 | --enable-tools \ 170 | --enable-usb-redir \ 171 | --enable-vhost-net \ 172 | --enable-vhost-user \ 173 | --enable-vhost-vdpa \ 174 | --enable-virtfs \ 175 | --enable-vnc \ 176 | --enable-vnc-jpeg \ 177 | --enable-xen \ 178 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 179 | # --enable-vde \ 180 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 181 | --enable-fuse \ 182 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 183 | --enable-slirp \ 184 | ; \ 185 | make -j "$(nproc)"; \ 186 | make install; \ 187 | \ 188 | cd /; \ 189 | rm -rf /usr/src/qemu; \ 190 | \ 191 | apt-mark auto '.*' > /dev/null; \ 192 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 193 | find /usr/local \ 194 | -type f \ 195 | \( -executable -o -name '*.so' \) \ 196 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 197 | -not -name 'block-rbd.so' \ 198 | -exec ldd '{}' ';' \ 199 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 200 | | sort -u \ 201 | | xargs -r dpkg-query --search \ 202 | | cut -d: -f1 \ 203 | | sort -u \ 204 | | xargs -r apt-mark manual \ 205 | ; \ 206 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 207 | apt-get dist-clean; \ 208 | \ 209 | # basic smoke test 210 | qemu-img --version 211 | 212 | STOPSIGNAL SIGHUP 213 | 214 | EXPOSE 22 215 | EXPOSE 5900 216 | 217 | COPY start-qemu /usr/local/bin/ 218 | CMD ["start-qemu"] 219 | -------------------------------------------------------------------------------- /9.1/qemu-signals.patch: -------------------------------------------------------------------------------- 1 | Origin: https://bugs.launchpad.net/qemu/+bug/1217339/comments/2 2 | Origin: https://lists.nongnu.org/archive/html/qemu-devel/2017-03/msg03039.html 3 | 4 | diff --git a/system/runstate.c b/system/runstate.c 5 | index 272801d307..3270467799 100644 6 | --- a/system/runstate.c 7 | +++ b/system/runstate.c 8 | @@ -714,7 +714,11 @@ void qemu_system_killed(int signal, pid_t pid) 9 | /* Cannot call qemu_system_shutdown_request directly because 10 | * we are in a signal handler. 11 | */ 12 | + if (signal == SIGHUP) { 13 | + powerdown_requested = 1; 14 | + } else { // indentation of the following is "wrong" on purpose so the patch diff is smaller (and the relation to the original code more obvious) 15 | shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 16 | + } 17 | qemu_notify_event(); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /9.1/start-qemu: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # main available options: 5 | # QEMU_CPU=n (cores) 6 | # QEMU_RAM=nnn (megabytes) 7 | # QEMU_HDA (filename) 8 | # QEMU_HDA_SIZE (bytes, suffixes like "G" allowed) 9 | # QEMU_CDROM (filename) 10 | # QEMU_BOOT (-boot) 11 | # QEMU_PORTS="xxx[ xxx ...]" (space separated port numbers) 12 | # QEMU_NET_USER_EXTRA="net=192.168.76.0/24,dhcpstart=192.168.76.9" (extra raw args for "-net user,...") 13 | # QEMU_NO_NET=1 (suppress ALL -netdev - thus no port forwards, etc) 14 | # QEMU_NO_SSH=1 (suppress automatic port 22 forwarding) 15 | # QEMU_NO_SERIAL=1 (suppress automatic "-serial stdio") 16 | # QEMU_NO_VNC=1 (suppress automatic "-vnc ':0'") 17 | 18 | hostArch="$(uname -m)" 19 | qemuArch="${QEMU_ARCH:-$hostArch}" 20 | qemu="${QEMU_BIN:-qemu-system-$qemuArch}" 21 | qemuArgs=() 22 | 23 | qemuPorts=() 24 | if [ -z "${QEMU_NO_SSH:-}" ]; then 25 | qemuPorts+=( 22 ) 26 | fi 27 | qemuPorts+=( ${QEMU_PORTS:-} ) 28 | 29 | if [ -e /dev/kvm ] && sh -c 'echo -n > /dev/kvm' &> /dev/null; then 30 | # https://github.com/tianon/docker-qemu/issues/4 31 | qemuArgs+=( -enable-kvm ) 32 | elif [ "$hostArch" = "$qemuArch" ]; then 33 | echo >&2 34 | echo >&2 'warning: /dev/kvm not found' 35 | echo >&2 ' PERFORMANCE WILL SUFFER' 36 | echo >&2 ' (hint: docker run --device /dev/kvm ...)' 37 | echo >&2 38 | sleep 3 39 | fi 40 | 41 | qemuArgs+=( -smp "${QEMU_CPU:-1}" ) 42 | qemuArgs+=( -m "${QEMU_RAM:-512}" ) 43 | 44 | if [ -n "${QEMU_HDA:-}" ]; then 45 | if [ ! -f "$QEMU_HDA" -o ! -s "$QEMU_HDA" ]; then 46 | ( 47 | set -x 48 | qemu-img create -f qcow2 -o preallocation=off "$QEMU_HDA" "${QEMU_HDA_SIZE:-8G}" 49 | ) 50 | fi 51 | 52 | # http://wiki.qemu.org/download/qemu-doc.html#Invocation 53 | qemuScsiDevice='virtio-scsi-pci' 54 | case "$qemuArch" in 55 | arm | riscv64) qemuScsiDevice='virtio-scsi-device' ;; 56 | esac 57 | 58 | #qemuArgs+=( -hda "$QEMU_HDA" ) 59 | #qemuArgs+=( -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap ) 60 | qemuArgs+=( 61 | -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap,detect-zeroes=unmap,if=none,id=hda 62 | -device "$qemuScsiDevice" 63 | -device scsi-hd,drive=hda 64 | ) 65 | fi 66 | 67 | if [ -n "${QEMU_CDROM:-}" ]; then 68 | qemuArgs+=( -cdrom "$QEMU_CDROM" ) 69 | fi 70 | 71 | if [ -n "${QEMU_BOOT:-}" ]; then 72 | qemuArgs+=( -boot "$QEMU_BOOT" ) 73 | fi 74 | 75 | if [ -z "${QEMU_NO_NET:-}" ]; then 76 | netArg='user' 77 | netArg+=",hostname=$(hostname)" 78 | if [ -n "${QEMU_NET_USER_EXTRA:-}" ]; then 79 | netArg+=",$QEMU_NET_USER_EXTRA" 80 | fi 81 | for port in "${qemuPorts[@]}"; do 82 | netArg+=",hostfwd=tcp::$port-:$port" 83 | netArg+=",hostfwd=udp::$port-:$port" 84 | done 85 | 86 | qemuNetDevice='virtio-net-pci' 87 | case "$qemuArch" in 88 | arm | riscv64) qemuNetDevice='virtio-net-device' ;; 89 | esac 90 | 91 | qemuArgs+=( 92 | -netdev "$netArg,id=net" 93 | -device "$qemuNetDevice,netdev=net" 94 | ) 95 | fi 96 | 97 | if [ -z "${QEMU_NO_SERIAL:-}" ]; then 98 | qemuArgs+=( 99 | -serial stdio 100 | ) 101 | fi 102 | 103 | if [ -z "${QEMU_NO_VNC:-}" ]; then 104 | qemuArgs+=( 105 | -vnc ':0' 106 | ) 107 | fi 108 | 109 | qemuArgs+=( "$@" ) 110 | 111 | set -x 112 | exec "$qemu" "${qemuArgs[@]}" 113 | -------------------------------------------------------------------------------- /9.2/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM debian:trixie-slim 8 | 9 | RUN set -eux; \ 10 | # add backports for (potentially) newer QEMU firmware packages 11 | if grep backports /etc/apt/sources.list.d/debian.sources; then exit 1; fi; \ 12 | sed -ri -e 's/([[:space:]])([^[:space:]]+)-updates($|[[:space:]])/\0\1\2-backports\3/' /etc/apt/sources.list.d/debian.sources; \ 13 | grep backports /etc/apt/sources.list.d/debian.sources; \ 14 | # and add APT pinning to ensure we don't accidentally get QEMU from Debian 15 | { \ 16 | echo 'Package: src:edk2'; \ 17 | echo 'Pin: release a=*-backports'; \ 18 | echo 'Pin-Priority: 600'; \ 19 | echo; \ 20 | echo 'Package: src:qemu'; \ 21 | echo 'Pin: version *'; \ 22 | echo 'Pin-Priority: -10'; \ 23 | } > /etc/apt/preferences.d/qemu.pref; \ 24 | apt-get update; \ 25 | # https://github.com/tianon/docker-qemu/issues/30 26 | apt-get install -y --no-install-recommends ca-certificates; \ 27 | # include "swtpm" for TPM emulation -- not automatically launched, but small and useful for running a TPM sidecar container (https://qemu-project.gitlab.io/qemu/specs/tpm.html#the-qemu-tpm-emulator-device) 28 | apt-get install -y --no-install-recommends swtpm; \ 29 | # install "firmware" packages (easier UEFI, etc) 30 | apt-get install -y --no-install-recommends \ 31 | # amd64 32 | ovmf \ 33 | # arm64 34 | qemu-efi-aarch64 \ 35 | # armel | armhf 36 | qemu-efi-arm \ 37 | # i386 38 | ovmf-ia32 \ 39 | # riscv64 40 | opensbi u-boot-qemu \ 41 | ; \ 42 | apt-get dist-clean 43 | 44 | COPY *.patch /qemu-patches/ 45 | 46 | # https://wiki.qemu.org/SecurityProcess 47 | ENV QEMU_KEYS \ 48 | # Michael Roth 49 | CEACC9E15534EBABB82D3FA03353C9CEF108B584 50 | # https://wiki.qemu.org/Planning/ReleaseProcess#Sign_the_resulting_tarball_with_GPG: (they get signed by whoever is making the release) 51 | 52 | # https://www.qemu.org/download/#source 53 | # https://download.qemu.org/?C=M;O=D 54 | ENV QEMU_VERSION 9.2.4 55 | ENV QEMU_URL https://download.qemu.org/qemu-9.2.4.tar.xz 56 | 57 | RUN set -eux; \ 58 | \ 59 | savedAptMark="$(apt-mark showmanual)"; \ 60 | \ 61 | apt-get install --update -y --no-install-recommends \ 62 | gnupg \ 63 | wget \ 64 | xz-utils \ 65 | \ 66 | patch \ 67 | \ 68 | bzip2 \ 69 | gcc \ 70 | gnutls-dev \ 71 | libaio-dev \ 72 | libbz2-dev \ 73 | libc-dev \ 74 | libcap-dev \ 75 | libcap-ng-dev \ 76 | libcurl4-gnutls-dev \ 77 | libglib2.0-dev \ 78 | libiscsi-dev \ 79 | libjpeg-dev \ 80 | libncursesw5-dev \ 81 | libnfs-dev \ 82 | libnuma-dev \ 83 | libpixman-1-dev \ 84 | libpng-dev \ 85 | librbd-dev \ 86 | libseccomp-dev \ 87 | libssh-dev \ 88 | libusb-1.0-0-dev \ 89 | libusbredirparser-dev \ 90 | libxen-dev \ 91 | make \ 92 | pkg-config \ 93 | python3 \ 94 | zlib1g-dev \ 95 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 96 | ninja-build \ 97 | python3-setuptools \ 98 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 99 | libfuse3-dev \ 100 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 101 | libslirp-dev \ 102 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 103 | python3-venv \ 104 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 105 | git \ 106 | ; \ 107 | \ 108 | tarball="$(basename "$QEMU_URL")"; \ 109 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 110 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 111 | \ 112 | export GNUPGHOME="$(mktemp -d)"; \ 113 | for key in $QEMU_KEYS; do \ 114 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 115 | done; \ 116 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 117 | gpgconf --kill all; \ 118 | rm -rf "$GNUPGHOME"; \ 119 | \ 120 | mkdir /usr/src/qemu; \ 121 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 122 | rm "$tarball" "$tarball.sig"; \ 123 | \ 124 | cd /usr/src/qemu; \ 125 | \ 126 | for p in /qemu-patches/*.patch; do \ 127 | patch --strip 1 --input "$p"; \ 128 | done; \ 129 | rm -rf /qemu-patches; \ 130 | \ 131 | ./configure --help; \ 132 | ./configure \ 133 | # let's add a link to our source code in the output of "--version" in case our users end up filing bugs against the QEMU project O:) 134 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 135 | --target-list=' \ 136 | # system targets 137 | # (https://sources.debian.org/src/qemu/buster/debian/rules/#L59-L63, slimmed) 138 | i386-softmmu x86_64-softmmu aarch64-softmmu arm-softmmu m68k-softmmu \ 139 | mips64-softmmu mips64el-softmmu ppc64-softmmu riscv64-softmmu \ 140 | sparc64-softmmu s390x-softmmu \ 141 | ' \ 142 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 143 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 144 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 145 | --disable-docs \ 146 | --disable-gtk --disable-vte \ 147 | --disable-sdl \ 148 | --enable-attr \ 149 | --enable-bzip2 \ 150 | --enable-cap-ng \ 151 | --enable-curl \ 152 | --enable-curses \ 153 | --enable-fdt \ 154 | --enable-gnutls \ 155 | --enable-kvm \ 156 | --enable-libiscsi \ 157 | --enable-libnfs \ 158 | --enable-libssh \ 159 | --enable-libusb \ 160 | --enable-linux-aio \ 161 | --enable-modules \ 162 | --enable-numa \ 163 | --enable-rbd \ 164 | --enable-seccomp \ 165 | --enable-strip \ 166 | --enable-tools \ 167 | --enable-usb-redir \ 168 | --enable-vhost-net \ 169 | --enable-vhost-user \ 170 | --enable-vhost-vdpa \ 171 | --enable-virtfs \ 172 | --enable-vnc \ 173 | --enable-vnc-jpeg \ 174 | --enable-xen \ 175 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 176 | # --enable-vde \ 177 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 178 | --enable-fuse \ 179 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 180 | --enable-slirp \ 181 | ; \ 182 | make -j "$(nproc)"; \ 183 | make install; \ 184 | \ 185 | cd /; \ 186 | rm -rf /usr/src/qemu; \ 187 | \ 188 | apt-mark auto '.*' > /dev/null; \ 189 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 190 | find /usr/local \ 191 | -type f \ 192 | \( -executable -o -name '*.so' \) \ 193 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 194 | -not -name 'block-rbd.so' \ 195 | -exec ldd '{}' ';' \ 196 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 197 | | sort -u \ 198 | | xargs -r dpkg-query --search \ 199 | | cut -d: -f1 \ 200 | | sort -u \ 201 | | xargs -r apt-mark manual \ 202 | ; \ 203 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 204 | apt-get dist-clean; \ 205 | \ 206 | # basic smoke test 207 | qemu-img --version 208 | 209 | STOPSIGNAL SIGHUP 210 | 211 | EXPOSE 22 212 | EXPOSE 5900 213 | 214 | COPY start-qemu /usr/local/bin/ 215 | CMD ["start-qemu"] 216 | -------------------------------------------------------------------------------- /9.2/Dockerfile.native: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM debian:trixie-slim 8 | 9 | RUN set -eux; \ 10 | # add backports for (potentially) newer QEMU firmware packages 11 | if grep backports /etc/apt/sources.list.d/debian.sources; then exit 1; fi; \ 12 | sed -ri -e 's/([[:space:]])([^[:space:]]+)-updates($|[[:space:]])/\0\1\2-backports\3/' /etc/apt/sources.list.d/debian.sources; \ 13 | grep backports /etc/apt/sources.list.d/debian.sources; \ 14 | # and add APT pinning to ensure we don't accidentally get QEMU from Debian 15 | { \ 16 | echo 'Package: src:edk2'; \ 17 | echo 'Pin: release a=*-backports'; \ 18 | echo 'Pin-Priority: 600'; \ 19 | echo; \ 20 | echo 'Package: src:qemu'; \ 21 | echo 'Pin: version *'; \ 22 | echo 'Pin-Priority: -10'; \ 23 | } > /etc/apt/preferences.d/qemu.pref; \ 24 | apt-get update; \ 25 | # https://github.com/tianon/docker-qemu/issues/30 26 | apt-get install -y --no-install-recommends ca-certificates; \ 27 | # include "swtpm" for TPM emulation -- not automatically launched, but small and useful for running a TPM sidecar container (https://qemu-project.gitlab.io/qemu/specs/tpm.html#the-qemu-tpm-emulator-device) 28 | apt-get install -y --no-install-recommends swtpm; \ 29 | # install "firmware" packages (easier UEFI, etc) 30 | arch="$(dpkg --print-architecture)"; \ 31 | case "$arch" in \ 32 | amd64) apt-get install -y --no-install-recommends ovmf ;; \ 33 | arm64) apt-get install -y --no-install-recommends qemu-efi-aarch64 ;; \ 34 | armel | armhf) apt-get install -y --no-install-recommends qemu-efi-arm ;; \ 35 | i386) apt-get install -y --no-install-recommends ovmf-ia32 ;; \ 36 | riscv64) apt-get install -y --no-install-recommends opensbi u-boot-qemu ;; \ 37 | *) echo >&2 "warning: architecture '$arch' unknown 😅 (is there a 'QEMU firmware' package that should be installed here? likely candidates: https://packages.debian.org/source/$suite/edk2)" ;; \ 38 | esac; \ 39 | apt-get dist-clean 40 | 41 | COPY *.patch /qemu-patches/ 42 | 43 | # https://wiki.qemu.org/SecurityProcess 44 | ENV QEMU_KEYS \ 45 | # Michael Roth 46 | CEACC9E15534EBABB82D3FA03353C9CEF108B584 47 | # https://wiki.qemu.org/Planning/ReleaseProcess#Sign_the_resulting_tarball_with_GPG: (they get signed by whoever is making the release) 48 | 49 | # https://www.qemu.org/download/#source 50 | # https://download.qemu.org/?C=M;O=D 51 | ENV QEMU_VERSION 9.2.4 52 | ENV QEMU_URL https://download.qemu.org/qemu-9.2.4.tar.xz 53 | 54 | RUN set -eux; \ 55 | \ 56 | savedAptMark="$(apt-mark showmanual)"; \ 57 | \ 58 | apt-get install --update -y --no-install-recommends \ 59 | gnupg \ 60 | wget \ 61 | xz-utils \ 62 | \ 63 | patch \ 64 | \ 65 | bzip2 \ 66 | gcc \ 67 | gnutls-dev \ 68 | libaio-dev \ 69 | libbz2-dev \ 70 | libc-dev \ 71 | libcap-dev \ 72 | libcap-ng-dev \ 73 | libcurl4-gnutls-dev \ 74 | libglib2.0-dev \ 75 | libiscsi-dev \ 76 | libjpeg-dev \ 77 | libncursesw5-dev \ 78 | libnfs-dev \ 79 | libnuma-dev \ 80 | libpixman-1-dev \ 81 | libpng-dev \ 82 | librbd-dev \ 83 | libseccomp-dev \ 84 | libssh-dev \ 85 | libusb-1.0-0-dev \ 86 | libusbredirparser-dev \ 87 | libxen-dev \ 88 | make \ 89 | pkg-config \ 90 | python3 \ 91 | zlib1g-dev \ 92 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 93 | ninja-build \ 94 | python3-setuptools \ 95 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 96 | libfuse3-dev \ 97 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 98 | libslirp-dev \ 99 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 100 | python3-venv \ 101 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 102 | git \ 103 | ; \ 104 | \ 105 | tarball="$(basename "$QEMU_URL")"; \ 106 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 107 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 108 | \ 109 | export GNUPGHOME="$(mktemp -d)"; \ 110 | for key in $QEMU_KEYS; do \ 111 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 112 | done; \ 113 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 114 | gpgconf --kill all; \ 115 | rm -rf "$GNUPGHOME"; \ 116 | \ 117 | mkdir /usr/src/qemu; \ 118 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 119 | rm "$tarball" "$tarball.sig"; \ 120 | \ 121 | cd /usr/src/qemu; \ 122 | \ 123 | for p in /qemu-patches/*.patch; do \ 124 | patch --strip 1 --input "$p"; \ 125 | done; \ 126 | rm -rf /qemu-patches; \ 127 | \ 128 | arch="$(dpkg --print-architecture)"; \ 129 | case "$arch" in \ 130 | amd64) targetList='x86_64-softmmu' ;; \ 131 | arm64) targetList='aarch64-softmmu' ;; \ 132 | armel | armhf) targetList='arm-softmmu' ;; \ 133 | i386) targetList='i386-softmmu' ;; \ 134 | mips64el) targetList='mips64el-softmmu' ;; \ 135 | ppc64el) targetList='ppc64-softmmu' ;; \ 136 | s390x) targetList='s390x-softmmu' ;; \ 137 | *) echo >&2 "error: architecture '$arch' unimplemented 😅"; exit 1 ;; \ 138 | esac; \ 139 | \ 140 | ./configure --help; \ 141 | ./configure \ 142 | # let's add a link to our source code in the output of "--version" in case our users end up filing bugs against the QEMU project O:) 143 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 144 | --target-list="$targetList" \ 145 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 146 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 147 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 148 | --disable-docs \ 149 | --disable-gtk --disable-vte \ 150 | --disable-sdl \ 151 | --enable-attr \ 152 | --enable-bzip2 \ 153 | --enable-cap-ng \ 154 | --enable-curl \ 155 | --enable-curses \ 156 | --enable-fdt \ 157 | --enable-gnutls \ 158 | --enable-kvm \ 159 | --enable-libiscsi \ 160 | --enable-libnfs \ 161 | --enable-libssh \ 162 | --enable-libusb \ 163 | --enable-linux-aio \ 164 | --enable-modules \ 165 | --enable-numa \ 166 | --enable-rbd \ 167 | --enable-seccomp \ 168 | --enable-strip \ 169 | --enable-tools \ 170 | --enable-usb-redir \ 171 | --enable-vhost-net \ 172 | --enable-vhost-user \ 173 | --enable-vhost-vdpa \ 174 | --enable-virtfs \ 175 | --enable-vnc \ 176 | --enable-vnc-jpeg \ 177 | --enable-xen \ 178 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 179 | # --enable-vde \ 180 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 181 | --enable-fuse \ 182 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 183 | --enable-slirp \ 184 | ; \ 185 | make -j "$(nproc)"; \ 186 | make install; \ 187 | \ 188 | cd /; \ 189 | rm -rf /usr/src/qemu; \ 190 | \ 191 | apt-mark auto '.*' > /dev/null; \ 192 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 193 | find /usr/local \ 194 | -type f \ 195 | \( -executable -o -name '*.so' \) \ 196 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 197 | -not -name 'block-rbd.so' \ 198 | -exec ldd '{}' ';' \ 199 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 200 | | sort -u \ 201 | | xargs -r dpkg-query --search \ 202 | | cut -d: -f1 \ 203 | | sort -u \ 204 | | xargs -r apt-mark manual \ 205 | ; \ 206 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 207 | apt-get dist-clean; \ 208 | \ 209 | # basic smoke test 210 | qemu-img --version 211 | 212 | STOPSIGNAL SIGHUP 213 | 214 | EXPOSE 22 215 | EXPOSE 5900 216 | 217 | COPY start-qemu /usr/local/bin/ 218 | CMD ["start-qemu"] 219 | -------------------------------------------------------------------------------- /9.2/qemu-signals.patch: -------------------------------------------------------------------------------- 1 | Origin: https://bugs.launchpad.net/qemu/+bug/1217339/comments/2 2 | Origin: https://lists.nongnu.org/archive/html/qemu-devel/2017-03/msg03039.html 3 | 4 | diff --git a/system/runstate.c b/system/runstate.c 5 | index 272801d307..3270467799 100644 6 | --- a/system/runstate.c 7 | +++ b/system/runstate.c 8 | @@ -714,7 +714,11 @@ void qemu_system_killed(int signal, pid_t pid) 9 | /* Cannot call qemu_system_shutdown_request directly because 10 | * we are in a signal handler. 11 | */ 12 | + if (signal == SIGHUP) { 13 | + powerdown_requested = 1; 14 | + } else { // indentation of the following is "wrong" on purpose so the patch diff is smaller (and the relation to the original code more obvious) 15 | shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 16 | + } 17 | qemu_notify_event(); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /9.2/start-qemu: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # main available options: 5 | # QEMU_CPU=n (cores) 6 | # QEMU_RAM=nnn (megabytes) 7 | # QEMU_HDA (filename) 8 | # QEMU_HDA_SIZE (bytes, suffixes like "G" allowed) 9 | # QEMU_CDROM (filename) 10 | # QEMU_BOOT (-boot) 11 | # QEMU_PORTS="xxx[ xxx ...]" (space separated port numbers) 12 | # QEMU_NET_USER_EXTRA="net=192.168.76.0/24,dhcpstart=192.168.76.9" (extra raw args for "-net user,...") 13 | # QEMU_NO_NET=1 (suppress ALL -netdev - thus no port forwards, etc) 14 | # QEMU_NO_SSH=1 (suppress automatic port 22 forwarding) 15 | # QEMU_NO_SERIAL=1 (suppress automatic "-serial stdio") 16 | # QEMU_NO_VNC=1 (suppress automatic "-vnc ':0'") 17 | 18 | hostArch="$(uname -m)" 19 | qemuArch="${QEMU_ARCH:-$hostArch}" 20 | qemu="${QEMU_BIN:-qemu-system-$qemuArch}" 21 | qemuArgs=() 22 | 23 | qemuPorts=() 24 | if [ -z "${QEMU_NO_SSH:-}" ]; then 25 | qemuPorts+=( 22 ) 26 | fi 27 | qemuPorts+=( ${QEMU_PORTS:-} ) 28 | 29 | if [ -e /dev/kvm ] && sh -c 'echo -n > /dev/kvm' &> /dev/null; then 30 | # https://github.com/tianon/docker-qemu/issues/4 31 | qemuArgs+=( -enable-kvm ) 32 | elif [ "$hostArch" = "$qemuArch" ]; then 33 | echo >&2 34 | echo >&2 'warning: /dev/kvm not found' 35 | echo >&2 ' PERFORMANCE WILL SUFFER' 36 | echo >&2 ' (hint: docker run --device /dev/kvm ...)' 37 | echo >&2 38 | sleep 3 39 | fi 40 | 41 | qemuArgs+=( -smp "${QEMU_CPU:-1}" ) 42 | qemuArgs+=( -m "${QEMU_RAM:-512}" ) 43 | 44 | if [ -n "${QEMU_HDA:-}" ]; then 45 | if [ ! -f "$QEMU_HDA" -o ! -s "$QEMU_HDA" ]; then 46 | ( 47 | set -x 48 | qemu-img create -f qcow2 -o preallocation=off "$QEMU_HDA" "${QEMU_HDA_SIZE:-8G}" 49 | ) 50 | fi 51 | 52 | # http://wiki.qemu.org/download/qemu-doc.html#Invocation 53 | qemuScsiDevice='virtio-scsi-pci' 54 | case "$qemuArch" in 55 | arm | riscv64) qemuScsiDevice='virtio-scsi-device' ;; 56 | esac 57 | 58 | #qemuArgs+=( -hda "$QEMU_HDA" ) 59 | #qemuArgs+=( -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap ) 60 | qemuArgs+=( 61 | -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap,detect-zeroes=unmap,if=none,id=hda 62 | -device "$qemuScsiDevice" 63 | -device scsi-hd,drive=hda 64 | ) 65 | fi 66 | 67 | if [ -n "${QEMU_CDROM:-}" ]; then 68 | qemuArgs+=( -cdrom "$QEMU_CDROM" ) 69 | fi 70 | 71 | if [ -n "${QEMU_BOOT:-}" ]; then 72 | qemuArgs+=( -boot "$QEMU_BOOT" ) 73 | fi 74 | 75 | if [ -z "${QEMU_NO_NET:-}" ]; then 76 | netArg='user' 77 | netArg+=",hostname=$(hostname)" 78 | if [ -n "${QEMU_NET_USER_EXTRA:-}" ]; then 79 | netArg+=",$QEMU_NET_USER_EXTRA" 80 | fi 81 | for port in "${qemuPorts[@]}"; do 82 | netArg+=",hostfwd=tcp::$port-:$port" 83 | netArg+=",hostfwd=udp::$port-:$port" 84 | done 85 | 86 | qemuNetDevice='virtio-net-pci' 87 | case "$qemuArch" in 88 | arm | riscv64) qemuNetDevice='virtio-net-device' ;; 89 | esac 90 | 91 | qemuArgs+=( 92 | -netdev "$netArg,id=net" 93 | -device "$qemuNetDevice,netdev=net" 94 | ) 95 | fi 96 | 97 | if [ -z "${QEMU_NO_SERIAL:-}" ]; then 98 | qemuArgs+=( 99 | -serial stdio 100 | ) 101 | fi 102 | 103 | if [ -z "${QEMU_NO_VNC:-}" ]; then 104 | qemuArgs+=( 105 | -vnc ':0' 106 | ) 107 | fi 108 | 109 | qemuArgs+=( "$@" ) 110 | 111 | set -x 112 | exec "$qemu" "${qemuArgs[@]}" 113 | -------------------------------------------------------------------------------- /Dockerfile.template: -------------------------------------------------------------------------------- 1 | FROM debian:trixie-slim 2 | 3 | RUN set -eux; \ 4 | # add backports for (potentially) newer QEMU firmware packages 5 | if grep backports /etc/apt/sources.list.d/debian.sources; then exit 1; fi; \ 6 | sed -ri -e 's/([[:space:]])([^[:space:]]+)-updates($|[[:space:]])/\0\1\2-backports\3/' /etc/apt/sources.list.d/debian.sources; \ 7 | grep backports /etc/apt/sources.list.d/debian.sources; \ 8 | # and add APT pinning to ensure we don't accidentally get QEMU from Debian 9 | { \ 10 | echo 'Package: src:edk2'; \ 11 | echo 'Pin: release a=*-backports'; \ 12 | echo 'Pin-Priority: 600'; \ 13 | echo; \ 14 | echo 'Package: src:qemu'; \ 15 | echo 'Pin: version *'; \ 16 | echo 'Pin-Priority: -10'; \ 17 | } > /etc/apt/preferences.d/qemu.pref; \ 18 | apt-get update; \ 19 | # https://github.com/tianon/docker-qemu/issues/30 20 | apt-get install -y --no-install-recommends ca-certificates; \ 21 | {{ def firmware_packages: { 22 | amd64: "ovmf", 23 | arm64: "qemu-efi-aarch64", 24 | "armel | armhf": "qemu-efi-arm", 25 | i386: "ovmf-ia32", 26 | riscv64: "opensbi u-boot-qemu", 27 | # TODO add u-boot-qemu to more arches? https://packages.debian.org/bookworm/u-boot-qemu 28 | } -}} 29 | # include "swtpm" for TPM emulation -- not automatically launched, but small and useful for running a TPM sidecar container (https://qemu-project.gitlab.io/qemu/specs/tpm.html#the-qemu-tpm-emulator-device) 30 | apt-get install -y --no-install-recommends swtpm; \ 31 | # install "firmware" packages (easier UEFI, etc) 32 | {{ if env.variant == "native" then ( -}} 33 | arch="$(dpkg --print-architecture)"; \ 34 | case "$arch" in \ 35 | {{ 36 | [ 37 | firmware_packages 38 | | to_entries[] 39 | | ( 40 | -}} 41 | {{ .key }}) apt-get install -y --no-install-recommends {{ .value }} ;; \ 42 | {{ 43 | ) 44 | ] | add 45 | -}} 46 | *) echo >&2 "warning: architecture '$arch' unknown 😅 (is there a 'QEMU firmware' package that should be installed here? likely candidates: https://packages.debian.org/source/$suite/edk2)" ;; \ 47 | esac; \ 48 | {{ ) else ( -}} 49 | apt-get install -y --no-install-recommends \ 50 | {{ 51 | [ 52 | firmware_packages 53 | | to_entries[] 54 | | ( 55 | -}} 56 | # {{ .key }} 57 | {{ .value }} \ 58 | {{ 59 | ) 60 | ] | add 61 | -}} 62 | ; \ 63 | {{ ) end -}} 64 | apt-get dist-clean 65 | 66 | COPY *.patch /qemu-patches/ 67 | 68 | # https://wiki.qemu.org/SecurityProcess 69 | ENV QEMU_KEYS \ 70 | # Michael Roth 71 | CEACC9E15534EBABB82D3FA03353C9CEF108B584 72 | # https://wiki.qemu.org/Planning/ReleaseProcess#Sign_the_resulting_tarball_with_GPG: (they get signed by whoever is making the release) 73 | 74 | # https://www.qemu.org/download/#source 75 | # https://download.qemu.org/?C=M;O=D 76 | ENV QEMU_VERSION {{ .version }} 77 | ENV QEMU_URL {{ .url }} 78 | 79 | RUN set -eux; \ 80 | \ 81 | savedAptMark="$(apt-mark showmanual)"; \ 82 | \ 83 | apt-get install --update -y --no-install-recommends \ 84 | gnupg \ 85 | wget \ 86 | xz-utils \ 87 | \ 88 | patch \ 89 | \ 90 | bzip2 \ 91 | gcc \ 92 | gnutls-dev \ 93 | libaio-dev \ 94 | libbz2-dev \ 95 | libc-dev \ 96 | libcap-dev \ 97 | libcap-ng-dev \ 98 | libcurl4-gnutls-dev \ 99 | libglib2.0-dev \ 100 | libiscsi-dev \ 101 | libjpeg-dev \ 102 | libncursesw5-dev \ 103 | libnfs-dev \ 104 | libnuma-dev \ 105 | libpixman-1-dev \ 106 | libpng-dev \ 107 | librbd-dev \ 108 | libseccomp-dev \ 109 | libssh-dev \ 110 | libusb-1.0-0-dev \ 111 | libusbredirparser-dev \ 112 | libxen-dev \ 113 | make \ 114 | pkg-config \ 115 | python3 \ 116 | zlib1g-dev \ 117 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 118 | ninja-build \ 119 | python3-setuptools \ 120 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 121 | libfuse3-dev \ 122 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 123 | libslirp-dev \ 124 | {{ if env.version | IN("7.2", "8.0") then "" else ( -}} 125 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 126 | python3-venv \ 127 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 128 | git \ 129 | {{ ) end -}} 130 | ; \ 131 | \ 132 | tarball="$(basename "$QEMU_URL")"; \ 133 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 134 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 135 | \ 136 | export GNUPGHOME="$(mktemp -d)"; \ 137 | for key in $QEMU_KEYS; do \ 138 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 139 | done; \ 140 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 141 | gpgconf --kill all; \ 142 | rm -rf "$GNUPGHOME"; \ 143 | \ 144 | mkdir /usr/src/qemu; \ 145 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 146 | rm "$tarball" "$tarball.sig"; \ 147 | \ 148 | cd /usr/src/qemu; \ 149 | \ 150 | for p in /qemu-patches/*.patch; do \ 151 | patch --strip 1 --input "$p"; \ 152 | done; \ 153 | rm -rf /qemu-patches; \ 154 | {{ if env.variant == "native" then ( -}} 155 | \ 156 | arch="$(dpkg --print-architecture)"; \ 157 | case "$arch" in \ 158 | amd64) targetList='x86_64-softmmu' ;; \ 159 | arm64) targetList='aarch64-softmmu' ;; \ 160 | armel | armhf) targetList='arm-softmmu' ;; \ 161 | i386) targetList='i386-softmmu' ;; \ 162 | mips64el) targetList='mips64el-softmmu' ;; \ 163 | ppc64el) targetList='ppc64-softmmu' ;; \ 164 | s390x) targetList='s390x-softmmu' ;; \ 165 | *) echo >&2 "error: architecture '$arch' unimplemented 😅"; exit 1 ;; \ 166 | esac; \ 167 | {{ ) else "" end -}} 168 | \ 169 | ./configure --help; \ 170 | ./configure \ 171 | # let's add a link to our source code in the output of "--version" in case our users end up filing bugs against the QEMU project O:) 172 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 173 | {{ if env.variant == "native" then ( -}} 174 | --target-list="$targetList" \ 175 | {{ ) else ( -}} 176 | --target-list=' \ 177 | # system targets 178 | # (https://sources.debian.org/src/qemu/buster/debian/rules/#L59-L63, slimmed) 179 | i386-softmmu x86_64-softmmu aarch64-softmmu arm-softmmu m68k-softmmu \ 180 | mips64-softmmu mips64el-softmmu ppc64-softmmu riscv64-softmmu \ 181 | sparc64-softmmu s390x-softmmu \ 182 | ' \ 183 | {{ ) end -}} 184 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 185 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 186 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 187 | --disable-docs \ 188 | --disable-gtk --disable-vte \ 189 | --disable-sdl \ 190 | --enable-attr \ 191 | --enable-bzip2 \ 192 | --enable-cap-ng \ 193 | --enable-curl \ 194 | --enable-curses \ 195 | --enable-fdt \ 196 | --enable-gnutls \ 197 | --enable-kvm \ 198 | --enable-libiscsi \ 199 | --enable-libnfs \ 200 | --enable-libssh \ 201 | --enable-libusb \ 202 | --enable-linux-aio \ 203 | --enable-modules \ 204 | --enable-numa \ 205 | --enable-rbd \ 206 | --enable-seccomp \ 207 | --enable-strip \ 208 | --enable-tools \ 209 | --enable-usb-redir \ 210 | --enable-vhost-net \ 211 | --enable-vhost-user \ 212 | --enable-vhost-vdpa \ 213 | --enable-virtfs \ 214 | --enable-vnc \ 215 | --enable-vnc-jpeg \ 216 | --enable-xen \ 217 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 218 | # --enable-vde \ 219 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 220 | --enable-fuse \ 221 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 222 | --enable-slirp \ 223 | ; \ 224 | make -j "$(nproc)"; \ 225 | make install; \ 226 | \ 227 | cd /; \ 228 | rm -rf /usr/src/qemu; \ 229 | \ 230 | apt-mark auto '.*' > /dev/null; \ 231 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 232 | find /usr/local \ 233 | -type f \ 234 | \( -executable -o -name '*.so' \) \ 235 | # rbd support is enabled, but "librbd1" is not included since it adds ~60MB and is version-sensitive (https://github.com/tianon/docker-qemu/pull/11#issuecomment-689816553) 236 | -not -name 'block-rbd.so' \ 237 | -exec ldd '{}' ';' \ 238 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 239 | | sort -u \ 240 | | xargs -r dpkg-query --search \ 241 | | cut -d: -f1 \ 242 | | sort -u \ 243 | | xargs -r apt-mark manual \ 244 | ; \ 245 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 246 | apt-get dist-clean; \ 247 | \ 248 | # basic smoke test 249 | qemu-img --version 250 | 251 | STOPSIGNAL SIGHUP 252 | 253 | EXPOSE 22 254 | EXPOSE 5900 255 | 256 | COPY start-qemu /usr/local/bin/ 257 | CMD ["start-qemu"] 258 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tianon/qemu 2 | 3 | ```console 4 | $ touch /home/jsmith/hda.qcow2 5 | $ docker run -it --rm \ 6 | --device /dev/kvm \ 7 | --name qemu-container \ 8 | -v /home/jsmith/hda.qcow2:/tmp/hda.qcow2 \ 9 | -e QEMU_HDA=/tmp/hda.qcow2 \ 10 | -e QEMU_HDA_SIZE=100G \ 11 | -e QEMU_CPU=4 \ 12 | -e QEMU_RAM=4096 \ 13 | -v /home/jsmith/downloads/debian.iso:/tmp/debian.iso:ro \ 14 | -e QEMU_CDROM=/tmp/debian.iso \ 15 | -e QEMU_BOOT='order=d' \ 16 | -e QEMU_PORTS='2375 2376' \ 17 | tianon/qemu:native 18 | ``` 19 | 20 | Note: port 22 will always be mapped (regardless of the contents of `QEMU_PORTS`). 21 | 22 | For supplying additional arguments, use a command of `start-qemu `. For example, to use `-curses`, one would `docker run ... tianon/qemu start-qemu -curses`. 23 | 24 | For UEFI support, [the `ovmf` package](https://packages.debian.org/sid/ovmf) is installed, which can be utilized most easily by supplying `--bios /usr/share/ovmf/OVMF.fd`. 25 | 26 | By default, this image will use [QEMU's user-mode networking stack](https://wiki.qemu.org/Documentation/Networking#User_Networking_.28SLIRP.29), which means if you want ping/ICMP working, you'll likely need to also include something like `--sysctl net.ipv4.ping_group_range='0 2147483647'` in your container runtime settings. 27 | 28 | The `native` variants for `amd64` only contain `qemu-system-x86_64` -- the non-`native` variants contain QEMU compiled for a variety of target CPUs. 29 | -------------------------------------------------------------------------------- /apply-templates.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -Eeuo pipefail 3 | 4 | [ -f versions.json ] # run "versions.sh" first 5 | 6 | jqt='.jq-template.awk' 7 | if [ -n "${BASHBREW_SCRIPTS:-}" ]; then 8 | jqt="$BASHBREW_SCRIPTS/jq-template.awk" 9 | elif [ "$BASH_SOURCE" -nt "$jqt" ]; then 10 | # https://github.com/docker-library/bashbrew/blob/master/scripts/jq-template.awk 11 | wget -qO "$jqt" 'https://github.com/docker-library/bashbrew/raw/9f6a35772ac863a0241f147c820354e4008edf38/scripts/jq-template.awk' 12 | fi 13 | 14 | if [ "$#" -eq 0 ]; then 15 | versions="$(jq -r 'keys | map(@sh) | join(" ")' versions.json)" 16 | eval "set -- $versions" 17 | fi 18 | 19 | generated_warning() { 20 | cat <<-EOH 21 | # 22 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 23 | # 24 | # PLEASE DO NOT EDIT IT DIRECTLY. 25 | # 26 | 27 | EOH 28 | } 29 | 30 | for version; do 31 | cp -a start-qemu "$version/" 32 | for variant in '' native; do 33 | export version variant 34 | 35 | echo "processing $version${variant:+ ($variant)} ..." 36 | 37 | { 38 | generated_warning 39 | gawk -f "$jqt" Dockerfile.template 40 | } > "$version/Dockerfile${variant:+.$variant}" 41 | done 42 | done 43 | -------------------------------------------------------------------------------- /generate-stackbrew-library.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -Eeuo pipefail 3 | 4 | declare -A aliases=( 5 | [10.1]='10 latest' 6 | [9.2]='9' 7 | [7.2]='7' 8 | ) 9 | 10 | self="$(basename "$BASH_SOURCE")" 11 | cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" 12 | 13 | if [ "$#" -eq 0 ]; then 14 | versions="$(jq -r 'keys | map(@sh) | join(" ")' versions.json)" 15 | eval "set -- $versions" 16 | fi 17 | 18 | # sort version numbers with highest first 19 | IFS=$'\n'; versions=( $(echo "${versions[*]}" | sort -rV) ); unset IFS 20 | 21 | # get the most recent commit which modified any of "$@" 22 | fileCommit() { 23 | git log -1 --format='format:%H' HEAD -- "$@" 24 | } 25 | 26 | # get the most recent commit which modified "$1/Dockerfile" or any file COPY'd from "$1/Dockerfile" 27 | dirCommit() { 28 | local dir="$1"; shift 29 | ( 30 | cd "$dir" 31 | files="$( 32 | git show HEAD:./Dockerfile HEAD:./Dockerfile.native | awk ' 33 | toupper($1) == "COPY" { 34 | for (i = 2; i < NF; i++) { 35 | if ($i ~ /^--from=/) { 36 | next 37 | } 38 | print $i 39 | } 40 | } 41 | ' 42 | )" 43 | fileCommit Dockerfile Dockerfile.native $files 44 | ) 45 | } 46 | 47 | getArches() { 48 | local officialImagesUrl='https://github.com/docker-library/official-images/raw/master/library/' 49 | 50 | eval "declare -g -A parentRepoToArches=( $( 51 | find -name 'Dockerfile*' -exec awk ' 52 | toupper($1) == "FROM" && $2 !~ /^(scratch|.*\/.*)(:|$)/ { 53 | print "'"$officialImagesUrl"'" $2 54 | } 55 | ' '{}' + \ 56 | | sort -u \ 57 | | xargs bashbrew cat --format '[{{ .RepoName }}:{{ .TagName }}]="{{ join " " .TagEntry.Architectures }}"' 58 | ) )" 59 | } 60 | getArches 61 | 62 | cat <<-EOH 63 | # this file is generated via https://github.com/tianon/docker-qemu/blob/$(fileCommit "$self")/$self 64 | 65 | Maintainers: Tianon Gravi (@tianon) 66 | GitRepo: https://github.com/tianon/docker-qemu.git 67 | EOH 68 | 69 | # prints "$2$1$3$1...$N" 70 | join() { 71 | local sep="$1"; shift 72 | local out; printf -v out "${sep//%/%%}%s" "$@" 73 | echo "${out#$sep}" 74 | } 75 | 76 | for version; do 77 | fullVersion="$(jq -r --arg version "$version" '.[$version].version' versions.json)" 78 | 79 | rcVersion="${version%-rc}" 80 | 81 | versionAliases=() 82 | while [ "$fullVersion" != "$rcVersion" -a "${fullVersion%[.]*}" != "$fullVersion" ]; do 83 | versionAliases+=( $fullVersion ) 84 | fullVersion="${fullVersion%[.]*}" 85 | done 86 | versionAliases+=( 87 | $version 88 | ${aliases[$version]:-} 89 | ) 90 | 91 | commit="$(dirCommit "$version")" 92 | 93 | for variant in '' native; do 94 | variantAliases=( "${versionAliases[@]}" ) 95 | if [ -n "$variant" ]; then 96 | variantAliases=( "${variantAliases[@]/%/-$variant}" ) 97 | variantAliases=( "${variantAliases[@]//latest-/}" ) 98 | fi 99 | 100 | variantParent="$(awk 'toupper($1) == "FROM" { print $2 }' "$version/Dockerfile${variant:+.$variant}")" 101 | 102 | suite="${variantParent#*:}" # "buster-slim", "buster" 103 | suite="${suite%-slim}" # "buster" 104 | suiteAliases=( "${variantAliases[@]/%/-$suite}" ) 105 | suiteAliases=( "${suiteAliases[@]//latest-/}" ) 106 | variantAliases+=( "${suiteAliases[@]}" ) 107 | 108 | case "$variant" in 109 | '') variantArches='amd64' ;; # only make the "fat" variant on amd64 110 | *) variantArches="${parentRepoToArches[$variantParent]}" ;; 111 | esac 112 | 113 | # skip i386 (missing many packages, like libxen-dev; not something I actually care to target) 114 | variantArches="$(sed -e 's/ i386 / /g' <<<" $variantArches ")" 115 | 116 | # architectures I don't think make sense to or I don't care to support 117 | variantArches="$(sed -e 's/ arm32v5 / /g' <<<" $variantArches ")" 118 | variantArches="$(sed -e 's/ mips64le / /g' <<<" $variantArches ")" 119 | variantArches="$(sed -e 's/ ppc64le / /g' <<<" $variantArches ")" 120 | variantArches="$(sed -e 's/ s390x / /g' <<<" $variantArches ")" 121 | 122 | echo 123 | cat <<-EOE 124 | Tags: $(join ', ' "${variantAliases[@]}") 125 | Architectures: $(join ', ' $variantArches) 126 | GitCommit: $commit 127 | Directory: $version 128 | EOE 129 | if [ -n "$variant" ]; then 130 | echo "File: Dockerfile.$variant" 131 | fi 132 | done 133 | done 134 | -------------------------------------------------------------------------------- /start-qemu: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # main available options: 5 | # QEMU_CPU=n (cores) 6 | # QEMU_RAM=nnn (megabytes) 7 | # QEMU_HDA (filename) 8 | # QEMU_HDA_SIZE (bytes, suffixes like "G" allowed) 9 | # QEMU_CDROM (filename) 10 | # QEMU_BOOT (-boot) 11 | # QEMU_PORTS="xxx[ xxx ...]" (space separated port numbers) 12 | # QEMU_NET_USER_EXTRA="net=192.168.76.0/24,dhcpstart=192.168.76.9" (extra raw args for "-net user,...") 13 | # QEMU_NO_NET=1 (suppress ALL -netdev - thus no port forwards, etc) 14 | # QEMU_NO_SSH=1 (suppress automatic port 22 forwarding) 15 | # QEMU_NO_SERIAL=1 (suppress automatic "-serial stdio") 16 | # QEMU_NO_VNC=1 (suppress automatic "-vnc ':0'") 17 | 18 | hostArch="$(uname -m)" 19 | qemuArch="${QEMU_ARCH:-$hostArch}" 20 | qemu="${QEMU_BIN:-qemu-system-$qemuArch}" 21 | qemuArgs=() 22 | 23 | qemuPorts=() 24 | if [ -z "${QEMU_NO_SSH:-}" ]; then 25 | qemuPorts+=( 22 ) 26 | fi 27 | qemuPorts+=( ${QEMU_PORTS:-} ) 28 | 29 | if [ -e /dev/kvm ] && sh -c 'echo -n > /dev/kvm' &> /dev/null; then 30 | # https://github.com/tianon/docker-qemu/issues/4 31 | qemuArgs+=( -enable-kvm ) 32 | elif [ "$hostArch" = "$qemuArch" ]; then 33 | echo >&2 34 | echo >&2 'warning: /dev/kvm not found' 35 | echo >&2 ' PERFORMANCE WILL SUFFER' 36 | echo >&2 ' (hint: docker run --device /dev/kvm ...)' 37 | echo >&2 38 | sleep 3 39 | fi 40 | 41 | qemuArgs+=( -smp "${QEMU_CPU:-1}" ) 42 | qemuArgs+=( -m "${QEMU_RAM:-512}" ) 43 | 44 | if [ -n "${QEMU_HDA:-}" ]; then 45 | if [ ! -f "$QEMU_HDA" -o ! -s "$QEMU_HDA" ]; then 46 | ( 47 | set -x 48 | qemu-img create -f qcow2 -o preallocation=off "$QEMU_HDA" "${QEMU_HDA_SIZE:-8G}" 49 | ) 50 | fi 51 | 52 | # http://wiki.qemu.org/download/qemu-doc.html#Invocation 53 | qemuScsiDevice='virtio-scsi-pci' 54 | case "$qemuArch" in 55 | arm | riscv64) qemuScsiDevice='virtio-scsi-device' ;; 56 | esac 57 | 58 | #qemuArgs+=( -hda "$QEMU_HDA" ) 59 | #qemuArgs+=( -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap ) 60 | qemuArgs+=( 61 | -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap,detect-zeroes=unmap,if=none,id=hda 62 | -device "$qemuScsiDevice" 63 | -device scsi-hd,drive=hda 64 | ) 65 | fi 66 | 67 | if [ -n "${QEMU_CDROM:-}" ]; then 68 | qemuArgs+=( -cdrom "$QEMU_CDROM" ) 69 | fi 70 | 71 | if [ -n "${QEMU_BOOT:-}" ]; then 72 | qemuArgs+=( -boot "$QEMU_BOOT" ) 73 | fi 74 | 75 | if [ -z "${QEMU_NO_NET:-}" ]; then 76 | netArg='user' 77 | netArg+=",hostname=$(hostname)" 78 | if [ -n "${QEMU_NET_USER_EXTRA:-}" ]; then 79 | netArg+=",$QEMU_NET_USER_EXTRA" 80 | fi 81 | for port in "${qemuPorts[@]}"; do 82 | netArg+=",hostfwd=tcp::$port-:$port" 83 | netArg+=",hostfwd=udp::$port-:$port" 84 | done 85 | 86 | qemuNetDevice='virtio-net-pci' 87 | case "$qemuArch" in 88 | arm | riscv64) qemuNetDevice='virtio-net-device' ;; 89 | esac 90 | 91 | qemuArgs+=( 92 | -netdev "$netArg,id=net" 93 | -device "$qemuNetDevice,netdev=net" 94 | ) 95 | fi 96 | 97 | if [ -z "${QEMU_NO_SERIAL:-}" ]; then 98 | qemuArgs+=( 99 | -serial stdio 100 | ) 101 | fi 102 | 103 | if [ -z "${QEMU_NO_VNC:-}" ]; then 104 | qemuArgs+=( 105 | -vnc ':0' 106 | ) 107 | fi 108 | 109 | qemuArgs+=( "$@" ) 110 | 111 | set -x 112 | exec "$qemu" "${qemuArgs[@]}" 113 | -------------------------------------------------------------------------------- /update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -Eeuo pipefail 3 | 4 | cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" 5 | 6 | ./versions.sh "$@" 7 | ./apply-templates.sh "$@" 8 | -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "10.0": { 3 | "url": "https://download.qemu.org/qemu-10.0.5.tar.xz", 4 | "version": "10.0.5" 5 | }, 6 | "10.1": { 7 | "url": "https://download.qemu.org/qemu-10.1.1.tar.xz", 8 | "version": "10.1.1" 9 | }, 10 | "7.2": { 11 | "url": "https://download.qemu.org/qemu-7.2.21.tar.xz", 12 | "version": "7.2.21" 13 | }, 14 | "9.1": { 15 | "url": "https://download.qemu.org/qemu-9.1.3.tar.xz", 16 | "version": "9.1.3" 17 | }, 18 | "9.2": { 19 | "url": "https://download.qemu.org/qemu-9.2.4.tar.xz", 20 | "version": "9.2.4" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /versions.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -Eeuo pipefail 3 | 4 | cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" 5 | 6 | versions=( "$@" ) 7 | if [ ${#versions[@]} -eq 0 ]; then 8 | versions=( */ ) 9 | json='{}' 10 | else 11 | json="$(< versions.json)" 12 | fi 13 | versions=( "${versions[@]%/}" ) 14 | 15 | # https://gitlab.com/qemu-project/qemu-web/-/commit/4d3bcc3891af7ec73f7c5a1887d7a9f5a5a4b406 16 | # TODO https://gitlab.com/qemu-project/qemu-web/-/blob/master/_data/releases.yml ? 17 | # https://gitlab.com/qemu-project/qemu-web/-/blob/master/_includes/releases.html ("limit: 5" reflects the number of currently "supported" versions from the data file) 18 | 19 | # https://download.qemu.org/?C=M;O=D 20 | urls="$( 21 | wget -qO- 'https://www.qemu.org/download/' \ 22 | | grep -oE 'https://download[.]qemu[.]org/qemu-([^"]+)[.]tar[.]xz' \ 23 | | sort -ruV 24 | )" 25 | 26 | for version in "${versions[@]}"; do 27 | rcGrepV='-v' 28 | rcVersion="${version%-rc}" 29 | if [ "$rcVersion" != "$version" ]; then 30 | rcGrepV= 31 | fi 32 | 33 | url="$( 34 | grep -E "qemu-$rcVersion([.-])" <<<"$urls" \ 35 | | grep $rcGrepV -E -- '-rc' \ 36 | | head -1 37 | )" 38 | fullVersion="${url##*/qemu-}" 39 | fullVersion="${fullVersion%%.tar.*}" 40 | 41 | echo "$version: $fullVersion" 42 | 43 | export version fullVersion url 44 | json="$(jq <<<"$json" ' 45 | .[env.version] = { 46 | version: env.fullVersion, 47 | url: env.url, 48 | } 49 | ')" 50 | done 51 | 52 | jq <<<"$json" -S . > versions.json 53 | --------------------------------------------------------------------------------