├── .gitattributes ├── .github └── workflows │ ├── ci.yml │ └── verify-templating.yml ├── .gitignore ├── 10.0 ├── Dockerfile ├── Dockerfile.native ├── qemu-signals.patch └── start-qemu ├── 7.2 ├── Dockerfile ├── Dockerfile.native ├── qemu-signals.patch └── start-qemu ├── 8.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:bookworm-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 | rm -rf /var/lib/apt/lists/* 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.2 55 | ENV QEMU_URL https://download.qemu.org/qemu-10.0.2.tar.xz 56 | 57 | RUN set -eux; \ 58 | \ 59 | savedAptMark="$(apt-mark showmanual)"; \ 60 | \ 61 | apt-get update; \ 62 | apt-get install -y --no-install-recommends \ 63 | gnupg \ 64 | wget \ 65 | xz-utils \ 66 | \ 67 | patch \ 68 | \ 69 | bzip2 \ 70 | gcc \ 71 | gnutls-dev \ 72 | libaio-dev \ 73 | libbz2-dev \ 74 | libc-dev \ 75 | libcap-dev \ 76 | libcap-ng-dev \ 77 | libcurl4-gnutls-dev \ 78 | libglib2.0-dev \ 79 | libiscsi-dev \ 80 | libjpeg-dev \ 81 | libncursesw5-dev \ 82 | libnfs-dev \ 83 | libnuma-dev \ 84 | libpixman-1-dev \ 85 | libpng-dev \ 86 | librbd-dev \ 87 | libseccomp-dev \ 88 | libssh-dev \ 89 | libusb-1.0-0-dev \ 90 | libusbredirparser-dev \ 91 | libxen-dev \ 92 | make \ 93 | pkg-config \ 94 | python3 \ 95 | zlib1g-dev \ 96 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 97 | ninja-build \ 98 | python3-setuptools \ 99 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 100 | libfuse3-dev \ 101 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 102 | libslirp-dev \ 103 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 104 | python3-venv \ 105 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 106 | git \ 107 | ; \ 108 | rm -rf /var/lib/apt/lists/*; \ 109 | \ 110 | tarball="$(basename "$QEMU_URL")"; \ 111 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 112 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 113 | \ 114 | export GNUPGHOME="$(mktemp -d)"; \ 115 | for key in $QEMU_KEYS; do \ 116 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 117 | done; \ 118 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 119 | gpgconf --kill all; \ 120 | rm -rf "$GNUPGHOME"; \ 121 | \ 122 | mkdir /usr/src/qemu; \ 123 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 124 | rm "$tarball" "$tarball.sig"; \ 125 | \ 126 | cd /usr/src/qemu; \ 127 | \ 128 | for p in /qemu-patches/*.patch; do \ 129 | patch --strip 1 --input "$p"; \ 130 | done; \ 131 | rm -rf /qemu-patches; \ 132 | \ 133 | ./configure --help; \ 134 | ./configure \ 135 | # 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:) 136 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 137 | --target-list=' \ 138 | # system targets 139 | # (https://sources.debian.org/src/qemu/buster/debian/rules/#L59-L63, slimmed) 140 | i386-softmmu x86_64-softmmu aarch64-softmmu arm-softmmu m68k-softmmu \ 141 | mips64-softmmu mips64el-softmmu ppc64-softmmu riscv64-softmmu \ 142 | sparc64-softmmu s390x-softmmu \ 143 | ' \ 144 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 145 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 146 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 147 | --disable-docs \ 148 | --disable-gtk --disable-vte \ 149 | --disable-sdl \ 150 | --enable-attr \ 151 | --enable-bzip2 \ 152 | --enable-cap-ng \ 153 | --enable-curl \ 154 | --enable-curses \ 155 | --enable-fdt \ 156 | --enable-gnutls \ 157 | --enable-kvm \ 158 | --enable-libiscsi \ 159 | --enable-libnfs \ 160 | --enable-libssh \ 161 | --enable-libusb \ 162 | --enable-linux-aio \ 163 | --enable-modules \ 164 | --enable-numa \ 165 | --enable-rbd \ 166 | --enable-seccomp \ 167 | --enable-strip \ 168 | --enable-tools \ 169 | --enable-usb-redir \ 170 | --enable-vhost-net \ 171 | --enable-vhost-user \ 172 | --enable-vhost-vdpa \ 173 | --enable-virtfs \ 174 | --enable-vnc \ 175 | --enable-vnc-jpeg \ 176 | --enable-xen \ 177 | # 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) 178 | # --enable-vde \ 179 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 180 | --enable-fuse \ 181 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 182 | --enable-slirp \ 183 | ; \ 184 | make -j "$(nproc)"; \ 185 | make install; \ 186 | \ 187 | cd /; \ 188 | rm -rf /usr/src/qemu; \ 189 | \ 190 | apt-mark auto '.*' > /dev/null; \ 191 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 192 | find /usr/local \ 193 | -type f \ 194 | \( -executable -o -name '*.so' \) \ 195 | # 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) 196 | -not -name 'block-rbd.so' \ 197 | -exec ldd '{}' ';' \ 198 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 199 | | sort -u \ 200 | | xargs -r dpkg-query --search \ 201 | | cut -d: -f1 \ 202 | | sort -u \ 203 | | xargs -r apt-mark manual \ 204 | ; \ 205 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 206 | \ 207 | # basic smoke test 208 | qemu-img --version 209 | 210 | STOPSIGNAL SIGHUP 211 | 212 | EXPOSE 22 213 | EXPOSE 5900 214 | 215 | COPY start-qemu /usr/local/bin/ 216 | CMD ["start-qemu"] 217 | -------------------------------------------------------------------------------- /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:bookworm-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 | rm -rf /var/lib/apt/lists/* 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.2 52 | ENV QEMU_URL https://download.qemu.org/qemu-10.0.2.tar.xz 53 | 54 | RUN set -eux; \ 55 | \ 56 | savedAptMark="$(apt-mark showmanual)"; \ 57 | \ 58 | apt-get update; \ 59 | apt-get install -y --no-install-recommends \ 60 | gnupg \ 61 | wget \ 62 | xz-utils \ 63 | \ 64 | patch \ 65 | \ 66 | bzip2 \ 67 | gcc \ 68 | gnutls-dev \ 69 | libaio-dev \ 70 | libbz2-dev \ 71 | libc-dev \ 72 | libcap-dev \ 73 | libcap-ng-dev \ 74 | libcurl4-gnutls-dev \ 75 | libglib2.0-dev \ 76 | libiscsi-dev \ 77 | libjpeg-dev \ 78 | libncursesw5-dev \ 79 | libnfs-dev \ 80 | libnuma-dev \ 81 | libpixman-1-dev \ 82 | libpng-dev \ 83 | librbd-dev \ 84 | libseccomp-dev \ 85 | libssh-dev \ 86 | libusb-1.0-0-dev \ 87 | libusbredirparser-dev \ 88 | libxen-dev \ 89 | make \ 90 | pkg-config \ 91 | python3 \ 92 | zlib1g-dev \ 93 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 94 | ninja-build \ 95 | python3-setuptools \ 96 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 97 | libfuse3-dev \ 98 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 99 | libslirp-dev \ 100 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 101 | python3-venv \ 102 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 103 | git \ 104 | ; \ 105 | rm -rf /var/lib/apt/lists/*; \ 106 | \ 107 | tarball="$(basename "$QEMU_URL")"; \ 108 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 109 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 110 | \ 111 | export GNUPGHOME="$(mktemp -d)"; \ 112 | for key in $QEMU_KEYS; do \ 113 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 114 | done; \ 115 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 116 | gpgconf --kill all; \ 117 | rm -rf "$GNUPGHOME"; \ 118 | \ 119 | mkdir /usr/src/qemu; \ 120 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 121 | rm "$tarball" "$tarball.sig"; \ 122 | \ 123 | cd /usr/src/qemu; \ 124 | \ 125 | for p in /qemu-patches/*.patch; do \ 126 | patch --strip 1 --input "$p"; \ 127 | done; \ 128 | rm -rf /qemu-patches; \ 129 | \ 130 | arch="$(dpkg --print-architecture)"; \ 131 | case "$arch" in \ 132 | amd64) targetList='x86_64-softmmu' ;; \ 133 | arm64) targetList='aarch64-softmmu' ;; \ 134 | armel | armhf) targetList='arm-softmmu' ;; \ 135 | i386) targetList='i386-softmmu' ;; \ 136 | mips64el) targetList='mips64el-softmmu' ;; \ 137 | ppc64el) targetList='ppc64-softmmu' ;; \ 138 | s390x) targetList='s390x-softmmu' ;; \ 139 | *) echo >&2 "error: architecture '$arch' unimplemented 😅"; exit 1 ;; \ 140 | esac; \ 141 | \ 142 | ./configure --help; \ 143 | ./configure \ 144 | # 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:) 145 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 146 | --target-list="$targetList" \ 147 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 148 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 149 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 150 | --disable-docs \ 151 | --disable-gtk --disable-vte \ 152 | --disable-sdl \ 153 | --enable-attr \ 154 | --enable-bzip2 \ 155 | --enable-cap-ng \ 156 | --enable-curl \ 157 | --enable-curses \ 158 | --enable-fdt \ 159 | --enable-gnutls \ 160 | --enable-kvm \ 161 | --enable-libiscsi \ 162 | --enable-libnfs \ 163 | --enable-libssh \ 164 | --enable-libusb \ 165 | --enable-linux-aio \ 166 | --enable-modules \ 167 | --enable-numa \ 168 | --enable-rbd \ 169 | --enable-seccomp \ 170 | --enable-strip \ 171 | --enable-tools \ 172 | --enable-usb-redir \ 173 | --enable-vhost-net \ 174 | --enable-vhost-user \ 175 | --enable-vhost-vdpa \ 176 | --enable-virtfs \ 177 | --enable-vnc \ 178 | --enable-vnc-jpeg \ 179 | --enable-xen \ 180 | # 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) 181 | # --enable-vde \ 182 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 183 | --enable-fuse \ 184 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 185 | --enable-slirp \ 186 | ; \ 187 | make -j "$(nproc)"; \ 188 | make install; \ 189 | \ 190 | cd /; \ 191 | rm -rf /usr/src/qemu; \ 192 | \ 193 | apt-mark auto '.*' > /dev/null; \ 194 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 195 | find /usr/local \ 196 | -type f \ 197 | \( -executable -o -name '*.so' \) \ 198 | # 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) 199 | -not -name 'block-rbd.so' \ 200 | -exec ldd '{}' ';' \ 201 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 202 | | sort -u \ 203 | | xargs -r dpkg-query --search \ 204 | | cut -d: -f1 \ 205 | | sort -u \ 206 | | xargs -r apt-mark manual \ 207 | ; \ 208 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 209 | \ 210 | # basic smoke test 211 | qemu-img --version 212 | 213 | STOPSIGNAL SIGHUP 214 | 215 | EXPOSE 22 216 | EXPOSE 5900 217 | 218 | COPY start-qemu /usr/local/bin/ 219 | CMD ["start-qemu"] 220 | -------------------------------------------------------------------------------- /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 ce8977c6a2..392e4c88be 100644 6 | --- a/system/runstate.c 7 | +++ b/system/runstate.c 8 | @@ -613,7 +613,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 | - shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 13 | + if (signal == SIGHUP) { 14 | + powerdown_requested = 1; 15 | + } else { 16 | + shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 17 | + } 18 | qemu_notify_event(); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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:bookworm-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 | rm -rf /var/lib/apt/lists/* 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.18 55 | ENV QEMU_URL https://download.qemu.org/qemu-7.2.18.tar.xz 56 | 57 | RUN set -eux; \ 58 | \ 59 | savedAptMark="$(apt-mark showmanual)"; \ 60 | \ 61 | apt-get update; \ 62 | apt-get install -y --no-install-recommends \ 63 | gnupg \ 64 | wget \ 65 | xz-utils \ 66 | \ 67 | patch \ 68 | \ 69 | bzip2 \ 70 | gcc \ 71 | gnutls-dev \ 72 | libaio-dev \ 73 | libbz2-dev \ 74 | libc-dev \ 75 | libcap-dev \ 76 | libcap-ng-dev \ 77 | libcurl4-gnutls-dev \ 78 | libglib2.0-dev \ 79 | libiscsi-dev \ 80 | libjpeg-dev \ 81 | libncursesw5-dev \ 82 | libnfs-dev \ 83 | libnuma-dev \ 84 | libpixman-1-dev \ 85 | libpng-dev \ 86 | librbd-dev \ 87 | libseccomp-dev \ 88 | libssh-dev \ 89 | libusb-1.0-0-dev \ 90 | libusbredirparser-dev \ 91 | libxen-dev \ 92 | make \ 93 | pkg-config \ 94 | python3 \ 95 | zlib1g-dev \ 96 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 97 | ninja-build \ 98 | python3-setuptools \ 99 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 100 | libfuse3-dev \ 101 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 102 | libslirp-dev \ 103 | ; \ 104 | rm -rf /var/lib/apt/lists/*; \ 105 | \ 106 | tarball="$(basename "$QEMU_URL")"; \ 107 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 108 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 109 | \ 110 | export GNUPGHOME="$(mktemp -d)"; \ 111 | for key in $QEMU_KEYS; do \ 112 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 113 | done; \ 114 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 115 | gpgconf --kill all; \ 116 | rm -rf "$GNUPGHOME"; \ 117 | \ 118 | mkdir /usr/src/qemu; \ 119 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 120 | rm "$tarball" "$tarball.sig"; \ 121 | \ 122 | cd /usr/src/qemu; \ 123 | \ 124 | for p in /qemu-patches/*.patch; do \ 125 | patch --strip 1 --input "$p"; \ 126 | done; \ 127 | rm -rf /qemu-patches; \ 128 | \ 129 | ./configure --help; \ 130 | ./configure \ 131 | # 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:) 132 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 133 | --target-list=' \ 134 | # system targets 135 | # (https://sources.debian.org/src/qemu/buster/debian/rules/#L59-L63, slimmed) 136 | i386-softmmu x86_64-softmmu aarch64-softmmu arm-softmmu m68k-softmmu \ 137 | mips64-softmmu mips64el-softmmu ppc64-softmmu riscv64-softmmu \ 138 | sparc64-softmmu s390x-softmmu \ 139 | ' \ 140 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 141 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 142 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 143 | --disable-docs \ 144 | --disable-gtk --disable-vte \ 145 | --disable-sdl \ 146 | --enable-attr \ 147 | --enable-bzip2 \ 148 | --enable-cap-ng \ 149 | --enable-curl \ 150 | --enable-curses \ 151 | --enable-fdt \ 152 | --enable-gnutls \ 153 | --enable-kvm \ 154 | --enable-libiscsi \ 155 | --enable-libnfs \ 156 | --enable-libssh \ 157 | --enable-libusb \ 158 | --enable-linux-aio \ 159 | --enable-modules \ 160 | --enable-numa \ 161 | --enable-rbd \ 162 | --enable-seccomp \ 163 | --enable-strip \ 164 | --enable-tools \ 165 | --enable-usb-redir \ 166 | --enable-vhost-net \ 167 | --enable-vhost-user \ 168 | --enable-vhost-vdpa \ 169 | --enable-virtfs \ 170 | --enable-vnc \ 171 | --enable-vnc-jpeg \ 172 | --enable-xen \ 173 | # 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) 174 | # --enable-vde \ 175 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 176 | --enable-fuse \ 177 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 178 | --enable-slirp \ 179 | ; \ 180 | make -j "$(nproc)"; \ 181 | make install; \ 182 | \ 183 | cd /; \ 184 | rm -rf /usr/src/qemu; \ 185 | \ 186 | apt-mark auto '.*' > /dev/null; \ 187 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 188 | find /usr/local \ 189 | -type f \ 190 | \( -executable -o -name '*.so' \) \ 191 | # 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) 192 | -not -name 'block-rbd.so' \ 193 | -exec ldd '{}' ';' \ 194 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 195 | | sort -u \ 196 | | xargs -r dpkg-query --search \ 197 | | cut -d: -f1 \ 198 | | sort -u \ 199 | | xargs -r apt-mark manual \ 200 | ; \ 201 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 202 | \ 203 | # basic smoke test 204 | qemu-img --version 205 | 206 | STOPSIGNAL SIGHUP 207 | 208 | EXPOSE 22 209 | EXPOSE 5900 210 | 211 | COPY start-qemu /usr/local/bin/ 212 | CMD ["start-qemu"] 213 | -------------------------------------------------------------------------------- /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:bookworm-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 | rm -rf /var/lib/apt/lists/* 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.18 52 | ENV QEMU_URL https://download.qemu.org/qemu-7.2.18.tar.xz 53 | 54 | RUN set -eux; \ 55 | \ 56 | savedAptMark="$(apt-mark showmanual)"; \ 57 | \ 58 | apt-get update; \ 59 | apt-get install -y --no-install-recommends \ 60 | gnupg \ 61 | wget \ 62 | xz-utils \ 63 | \ 64 | patch \ 65 | \ 66 | bzip2 \ 67 | gcc \ 68 | gnutls-dev \ 69 | libaio-dev \ 70 | libbz2-dev \ 71 | libc-dev \ 72 | libcap-dev \ 73 | libcap-ng-dev \ 74 | libcurl4-gnutls-dev \ 75 | libglib2.0-dev \ 76 | libiscsi-dev \ 77 | libjpeg-dev \ 78 | libncursesw5-dev \ 79 | libnfs-dev \ 80 | libnuma-dev \ 81 | libpixman-1-dev \ 82 | libpng-dev \ 83 | librbd-dev \ 84 | libseccomp-dev \ 85 | libssh-dev \ 86 | libusb-1.0-0-dev \ 87 | libusbredirparser-dev \ 88 | libxen-dev \ 89 | make \ 90 | pkg-config \ 91 | python3 \ 92 | zlib1g-dev \ 93 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 94 | ninja-build \ 95 | python3-setuptools \ 96 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 97 | libfuse3-dev \ 98 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 99 | libslirp-dev \ 100 | ; \ 101 | rm -rf /var/lib/apt/lists/*; \ 102 | \ 103 | tarball="$(basename "$QEMU_URL")"; \ 104 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 105 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 106 | \ 107 | export GNUPGHOME="$(mktemp -d)"; \ 108 | for key in $QEMU_KEYS; do \ 109 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 110 | done; \ 111 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 112 | gpgconf --kill all; \ 113 | rm -rf "$GNUPGHOME"; \ 114 | \ 115 | mkdir /usr/src/qemu; \ 116 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 117 | rm "$tarball" "$tarball.sig"; \ 118 | \ 119 | cd /usr/src/qemu; \ 120 | \ 121 | for p in /qemu-patches/*.patch; do \ 122 | patch --strip 1 --input "$p"; \ 123 | done; \ 124 | rm -rf /qemu-patches; \ 125 | \ 126 | arch="$(dpkg --print-architecture)"; \ 127 | case "$arch" in \ 128 | amd64) targetList='x86_64-softmmu' ;; \ 129 | arm64) targetList='aarch64-softmmu' ;; \ 130 | armel | armhf) targetList='arm-softmmu' ;; \ 131 | i386) targetList='i386-softmmu' ;; \ 132 | mips64el) targetList='mips64el-softmmu' ;; \ 133 | ppc64el) targetList='ppc64-softmmu' ;; \ 134 | s390x) targetList='s390x-softmmu' ;; \ 135 | *) echo >&2 "error: architecture '$arch' unimplemented 😅"; exit 1 ;; \ 136 | esac; \ 137 | \ 138 | ./configure --help; \ 139 | ./configure \ 140 | # 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:) 141 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 142 | --target-list="$targetList" \ 143 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 144 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 145 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 146 | --disable-docs \ 147 | --disable-gtk --disable-vte \ 148 | --disable-sdl \ 149 | --enable-attr \ 150 | --enable-bzip2 \ 151 | --enable-cap-ng \ 152 | --enable-curl \ 153 | --enable-curses \ 154 | --enable-fdt \ 155 | --enable-gnutls \ 156 | --enable-kvm \ 157 | --enable-libiscsi \ 158 | --enable-libnfs \ 159 | --enable-libssh \ 160 | --enable-libusb \ 161 | --enable-linux-aio \ 162 | --enable-modules \ 163 | --enable-numa \ 164 | --enable-rbd \ 165 | --enable-seccomp \ 166 | --enable-strip \ 167 | --enable-tools \ 168 | --enable-usb-redir \ 169 | --enable-vhost-net \ 170 | --enable-vhost-user \ 171 | --enable-vhost-vdpa \ 172 | --enable-virtfs \ 173 | --enable-vnc \ 174 | --enable-vnc-jpeg \ 175 | --enable-xen \ 176 | # 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) 177 | # --enable-vde \ 178 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 179 | --enable-fuse \ 180 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 181 | --enable-slirp \ 182 | ; \ 183 | make -j "$(nproc)"; \ 184 | make install; \ 185 | \ 186 | cd /; \ 187 | rm -rf /usr/src/qemu; \ 188 | \ 189 | apt-mark auto '.*' > /dev/null; \ 190 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 191 | find /usr/local \ 192 | -type f \ 193 | \( -executable -o -name '*.so' \) \ 194 | # 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) 195 | -not -name 'block-rbd.so' \ 196 | -exec ldd '{}' ';' \ 197 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 198 | | sort -u \ 199 | | xargs -r dpkg-query --search \ 200 | | cut -d: -f1 \ 201 | | sort -u \ 202 | | xargs -r apt-mark manual \ 203 | ; \ 204 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 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 | -------------------------------------------------------------------------------- /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 ce8977c6a2..392e4c88be 100644 6 | --- a/softmmu/runstate.c 7 | +++ b/softmmu/runstate.c 8 | @@ -613,7 +613,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 | - shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 13 | + if (signal == SIGHUP) { 14 | + powerdown_requested = 1; 15 | + } else { 16 | + shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 17 | + } 18 | qemu_notify_event(); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /8.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:bookworm-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 | rm -rf /var/lib/apt/lists/* 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 8.2.10 55 | ENV QEMU_URL https://download.qemu.org/qemu-8.2.10.tar.xz 56 | 57 | RUN set -eux; \ 58 | \ 59 | savedAptMark="$(apt-mark showmanual)"; \ 60 | \ 61 | apt-get update; \ 62 | apt-get install -y --no-install-recommends \ 63 | gnupg \ 64 | wget \ 65 | xz-utils \ 66 | \ 67 | patch \ 68 | \ 69 | bzip2 \ 70 | gcc \ 71 | gnutls-dev \ 72 | libaio-dev \ 73 | libbz2-dev \ 74 | libc-dev \ 75 | libcap-dev \ 76 | libcap-ng-dev \ 77 | libcurl4-gnutls-dev \ 78 | libglib2.0-dev \ 79 | libiscsi-dev \ 80 | libjpeg-dev \ 81 | libncursesw5-dev \ 82 | libnfs-dev \ 83 | libnuma-dev \ 84 | libpixman-1-dev \ 85 | libpng-dev \ 86 | librbd-dev \ 87 | libseccomp-dev \ 88 | libssh-dev \ 89 | libusb-1.0-0-dev \ 90 | libusbredirparser-dev \ 91 | libxen-dev \ 92 | make \ 93 | pkg-config \ 94 | python3 \ 95 | zlib1g-dev \ 96 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 97 | ninja-build \ 98 | python3-setuptools \ 99 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 100 | libfuse3-dev \ 101 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 102 | libslirp-dev \ 103 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 104 | python3-venv \ 105 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 106 | git \ 107 | ; \ 108 | rm -rf /var/lib/apt/lists/*; \ 109 | \ 110 | tarball="$(basename "$QEMU_URL")"; \ 111 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 112 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 113 | \ 114 | export GNUPGHOME="$(mktemp -d)"; \ 115 | for key in $QEMU_KEYS; do \ 116 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 117 | done; \ 118 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 119 | gpgconf --kill all; \ 120 | rm -rf "$GNUPGHOME"; \ 121 | \ 122 | mkdir /usr/src/qemu; \ 123 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 124 | rm "$tarball" "$tarball.sig"; \ 125 | \ 126 | cd /usr/src/qemu; \ 127 | \ 128 | for p in /qemu-patches/*.patch; do \ 129 | patch --strip 1 --input "$p"; \ 130 | done; \ 131 | rm -rf /qemu-patches; \ 132 | \ 133 | ./configure --help; \ 134 | ./configure \ 135 | # 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:) 136 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 137 | --target-list=' \ 138 | # system targets 139 | # (https://sources.debian.org/src/qemu/buster/debian/rules/#L59-L63, slimmed) 140 | i386-softmmu x86_64-softmmu aarch64-softmmu arm-softmmu m68k-softmmu \ 141 | mips64-softmmu mips64el-softmmu ppc64-softmmu riscv64-softmmu \ 142 | sparc64-softmmu s390x-softmmu \ 143 | ' \ 144 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 145 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 146 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 147 | --disable-docs \ 148 | --disable-gtk --disable-vte \ 149 | --disable-sdl \ 150 | --enable-attr \ 151 | --enable-bzip2 \ 152 | --enable-cap-ng \ 153 | --enable-curl \ 154 | --enable-curses \ 155 | --enable-fdt \ 156 | --enable-gnutls \ 157 | --enable-kvm \ 158 | --enable-libiscsi \ 159 | --enable-libnfs \ 160 | --enable-libssh \ 161 | --enable-libusb \ 162 | --enable-linux-aio \ 163 | --enable-modules \ 164 | --enable-numa \ 165 | --enable-rbd \ 166 | --enable-seccomp \ 167 | --enable-strip \ 168 | --enable-tools \ 169 | --enable-usb-redir \ 170 | --enable-vhost-net \ 171 | --enable-vhost-user \ 172 | --enable-vhost-vdpa \ 173 | --enable-virtfs \ 174 | --enable-vnc \ 175 | --enable-vnc-jpeg \ 176 | --enable-xen \ 177 | # 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) 178 | # --enable-vde \ 179 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 180 | --enable-fuse \ 181 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 182 | --enable-slirp \ 183 | ; \ 184 | make -j "$(nproc)"; \ 185 | make install; \ 186 | \ 187 | cd /; \ 188 | rm -rf /usr/src/qemu; \ 189 | \ 190 | apt-mark auto '.*' > /dev/null; \ 191 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 192 | find /usr/local \ 193 | -type f \ 194 | \( -executable -o -name '*.so' \) \ 195 | # 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) 196 | -not -name 'block-rbd.so' \ 197 | -exec ldd '{}' ';' \ 198 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 199 | | sort -u \ 200 | | xargs -r dpkg-query --search \ 201 | | cut -d: -f1 \ 202 | | sort -u \ 203 | | xargs -r apt-mark manual \ 204 | ; \ 205 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 206 | \ 207 | # basic smoke test 208 | qemu-img --version 209 | 210 | STOPSIGNAL SIGHUP 211 | 212 | EXPOSE 22 213 | EXPOSE 5900 214 | 215 | COPY start-qemu /usr/local/bin/ 216 | CMD ["start-qemu"] 217 | -------------------------------------------------------------------------------- /8.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:bookworm-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 | rm -rf /var/lib/apt/lists/* 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 8.2.10 52 | ENV QEMU_URL https://download.qemu.org/qemu-8.2.10.tar.xz 53 | 54 | RUN set -eux; \ 55 | \ 56 | savedAptMark="$(apt-mark showmanual)"; \ 57 | \ 58 | apt-get update; \ 59 | apt-get install -y --no-install-recommends \ 60 | gnupg \ 61 | wget \ 62 | xz-utils \ 63 | \ 64 | patch \ 65 | \ 66 | bzip2 \ 67 | gcc \ 68 | gnutls-dev \ 69 | libaio-dev \ 70 | libbz2-dev \ 71 | libc-dev \ 72 | libcap-dev \ 73 | libcap-ng-dev \ 74 | libcurl4-gnutls-dev \ 75 | libglib2.0-dev \ 76 | libiscsi-dev \ 77 | libjpeg-dev \ 78 | libncursesw5-dev \ 79 | libnfs-dev \ 80 | libnuma-dev \ 81 | libpixman-1-dev \ 82 | libpng-dev \ 83 | librbd-dev \ 84 | libseccomp-dev \ 85 | libssh-dev \ 86 | libusb-1.0-0-dev \ 87 | libusbredirparser-dev \ 88 | libxen-dev \ 89 | make \ 90 | pkg-config \ 91 | python3 \ 92 | zlib1g-dev \ 93 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 94 | ninja-build \ 95 | python3-setuptools \ 96 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 97 | libfuse3-dev \ 98 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 99 | libslirp-dev \ 100 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 101 | python3-venv \ 102 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 103 | git \ 104 | ; \ 105 | rm -rf /var/lib/apt/lists/*; \ 106 | \ 107 | tarball="$(basename "$QEMU_URL")"; \ 108 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 109 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 110 | \ 111 | export GNUPGHOME="$(mktemp -d)"; \ 112 | for key in $QEMU_KEYS; do \ 113 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 114 | done; \ 115 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 116 | gpgconf --kill all; \ 117 | rm -rf "$GNUPGHOME"; \ 118 | \ 119 | mkdir /usr/src/qemu; \ 120 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 121 | rm "$tarball" "$tarball.sig"; \ 122 | \ 123 | cd /usr/src/qemu; \ 124 | \ 125 | for p in /qemu-patches/*.patch; do \ 126 | patch --strip 1 --input "$p"; \ 127 | done; \ 128 | rm -rf /qemu-patches; \ 129 | \ 130 | arch="$(dpkg --print-architecture)"; \ 131 | case "$arch" in \ 132 | amd64) targetList='x86_64-softmmu' ;; \ 133 | arm64) targetList='aarch64-softmmu' ;; \ 134 | armel | armhf) targetList='arm-softmmu' ;; \ 135 | i386) targetList='i386-softmmu' ;; \ 136 | mips64el) targetList='mips64el-softmmu' ;; \ 137 | ppc64el) targetList='ppc64-softmmu' ;; \ 138 | s390x) targetList='s390x-softmmu' ;; \ 139 | *) echo >&2 "error: architecture '$arch' unimplemented 😅"; exit 1 ;; \ 140 | esac; \ 141 | \ 142 | ./configure --help; \ 143 | ./configure \ 144 | # 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:) 145 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 146 | --target-list="$targetList" \ 147 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 148 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 149 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 150 | --disable-docs \ 151 | --disable-gtk --disable-vte \ 152 | --disable-sdl \ 153 | --enable-attr \ 154 | --enable-bzip2 \ 155 | --enable-cap-ng \ 156 | --enable-curl \ 157 | --enable-curses \ 158 | --enable-fdt \ 159 | --enable-gnutls \ 160 | --enable-kvm \ 161 | --enable-libiscsi \ 162 | --enable-libnfs \ 163 | --enable-libssh \ 164 | --enable-libusb \ 165 | --enable-linux-aio \ 166 | --enable-modules \ 167 | --enable-numa \ 168 | --enable-rbd \ 169 | --enable-seccomp \ 170 | --enable-strip \ 171 | --enable-tools \ 172 | --enable-usb-redir \ 173 | --enable-vhost-net \ 174 | --enable-vhost-user \ 175 | --enable-vhost-vdpa \ 176 | --enable-virtfs \ 177 | --enable-vnc \ 178 | --enable-vnc-jpeg \ 179 | --enable-xen \ 180 | # 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) 181 | # --enable-vde \ 182 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 183 | --enable-fuse \ 184 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 185 | --enable-slirp \ 186 | ; \ 187 | make -j "$(nproc)"; \ 188 | make install; \ 189 | \ 190 | cd /; \ 191 | rm -rf /usr/src/qemu; \ 192 | \ 193 | apt-mark auto '.*' > /dev/null; \ 194 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 195 | find /usr/local \ 196 | -type f \ 197 | \( -executable -o -name '*.so' \) \ 198 | # 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) 199 | -not -name 'block-rbd.so' \ 200 | -exec ldd '{}' ';' \ 201 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 202 | | sort -u \ 203 | | xargs -r dpkg-query --search \ 204 | | cut -d: -f1 \ 205 | | sort -u \ 206 | | xargs -r apt-mark manual \ 207 | ; \ 208 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 209 | \ 210 | # basic smoke test 211 | qemu-img --version 212 | 213 | STOPSIGNAL SIGHUP 214 | 215 | EXPOSE 22 216 | EXPOSE 5900 217 | 218 | COPY start-qemu /usr/local/bin/ 219 | CMD ["start-qemu"] 220 | -------------------------------------------------------------------------------- /8.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 ce8977c6a2..392e4c88be 100644 6 | --- a/system/runstate.c 7 | +++ b/system/runstate.c 8 | @@ -613,7 +613,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 | - shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 13 | + if (signal == SIGHUP) { 14 | + powerdown_requested = 1; 15 | + } else { 16 | + shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 17 | + } 18 | qemu_notify_event(); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /8.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:bookworm-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 | rm -rf /var/lib/apt/lists/* 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 update; \ 62 | apt-get install -y --no-install-recommends \ 63 | gnupg \ 64 | wget \ 65 | xz-utils \ 66 | \ 67 | patch \ 68 | \ 69 | bzip2 \ 70 | gcc \ 71 | gnutls-dev \ 72 | libaio-dev \ 73 | libbz2-dev \ 74 | libc-dev \ 75 | libcap-dev \ 76 | libcap-ng-dev \ 77 | libcurl4-gnutls-dev \ 78 | libglib2.0-dev \ 79 | libiscsi-dev \ 80 | libjpeg-dev \ 81 | libncursesw5-dev \ 82 | libnfs-dev \ 83 | libnuma-dev \ 84 | libpixman-1-dev \ 85 | libpng-dev \ 86 | librbd-dev \ 87 | libseccomp-dev \ 88 | libssh-dev \ 89 | libusb-1.0-0-dev \ 90 | libusbredirparser-dev \ 91 | libxen-dev \ 92 | make \ 93 | pkg-config \ 94 | python3 \ 95 | zlib1g-dev \ 96 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 97 | ninja-build \ 98 | python3-setuptools \ 99 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 100 | libfuse3-dev \ 101 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 102 | libslirp-dev \ 103 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 104 | python3-venv \ 105 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 106 | git \ 107 | ; \ 108 | rm -rf /var/lib/apt/lists/*; \ 109 | \ 110 | tarball="$(basename "$QEMU_URL")"; \ 111 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 112 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 113 | \ 114 | export GNUPGHOME="$(mktemp -d)"; \ 115 | for key in $QEMU_KEYS; do \ 116 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 117 | done; \ 118 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 119 | gpgconf --kill all; \ 120 | rm -rf "$GNUPGHOME"; \ 121 | \ 122 | mkdir /usr/src/qemu; \ 123 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 124 | rm "$tarball" "$tarball.sig"; \ 125 | \ 126 | cd /usr/src/qemu; \ 127 | \ 128 | for p in /qemu-patches/*.patch; do \ 129 | patch --strip 1 --input "$p"; \ 130 | done; \ 131 | rm -rf /qemu-patches; \ 132 | \ 133 | ./configure --help; \ 134 | ./configure \ 135 | # 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:) 136 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 137 | --target-list=' \ 138 | # system targets 139 | # (https://sources.debian.org/src/qemu/buster/debian/rules/#L59-L63, slimmed) 140 | i386-softmmu x86_64-softmmu aarch64-softmmu arm-softmmu m68k-softmmu \ 141 | mips64-softmmu mips64el-softmmu ppc64-softmmu riscv64-softmmu \ 142 | sparc64-softmmu s390x-softmmu \ 143 | ' \ 144 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 145 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 146 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 147 | --disable-docs \ 148 | --disable-gtk --disable-vte \ 149 | --disable-sdl \ 150 | --enable-attr \ 151 | --enable-bzip2 \ 152 | --enable-cap-ng \ 153 | --enable-curl \ 154 | --enable-curses \ 155 | --enable-fdt \ 156 | --enable-gnutls \ 157 | --enable-kvm \ 158 | --enable-libiscsi \ 159 | --enable-libnfs \ 160 | --enable-libssh \ 161 | --enable-libusb \ 162 | --enable-linux-aio \ 163 | --enable-modules \ 164 | --enable-numa \ 165 | --enable-rbd \ 166 | --enable-seccomp \ 167 | --enable-strip \ 168 | --enable-tools \ 169 | --enable-usb-redir \ 170 | --enable-vhost-net \ 171 | --enable-vhost-user \ 172 | --enable-vhost-vdpa \ 173 | --enable-virtfs \ 174 | --enable-vnc \ 175 | --enable-vnc-jpeg \ 176 | --enable-xen \ 177 | # 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) 178 | # --enable-vde \ 179 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 180 | --enable-fuse \ 181 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 182 | --enable-slirp \ 183 | ; \ 184 | make -j "$(nproc)"; \ 185 | make install; \ 186 | \ 187 | cd /; \ 188 | rm -rf /usr/src/qemu; \ 189 | \ 190 | apt-mark auto '.*' > /dev/null; \ 191 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 192 | find /usr/local \ 193 | -type f \ 194 | \( -executable -o -name '*.so' \) \ 195 | # 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) 196 | -not -name 'block-rbd.so' \ 197 | -exec ldd '{}' ';' \ 198 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 199 | | sort -u \ 200 | | xargs -r dpkg-query --search \ 201 | | cut -d: -f1 \ 202 | | sort -u \ 203 | | xargs -r apt-mark manual \ 204 | ; \ 205 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 206 | \ 207 | # basic smoke test 208 | qemu-img --version 209 | 210 | STOPSIGNAL SIGHUP 211 | 212 | EXPOSE 22 213 | EXPOSE 5900 214 | 215 | COPY start-qemu /usr/local/bin/ 216 | CMD ["start-qemu"] 217 | -------------------------------------------------------------------------------- /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:bookworm-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 | rm -rf /var/lib/apt/lists/* 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 update; \ 59 | apt-get install -y --no-install-recommends \ 60 | gnupg \ 61 | wget \ 62 | xz-utils \ 63 | \ 64 | patch \ 65 | \ 66 | bzip2 \ 67 | gcc \ 68 | gnutls-dev \ 69 | libaio-dev \ 70 | libbz2-dev \ 71 | libc-dev \ 72 | libcap-dev \ 73 | libcap-ng-dev \ 74 | libcurl4-gnutls-dev \ 75 | libglib2.0-dev \ 76 | libiscsi-dev \ 77 | libjpeg-dev \ 78 | libncursesw5-dev \ 79 | libnfs-dev \ 80 | libnuma-dev \ 81 | libpixman-1-dev \ 82 | libpng-dev \ 83 | librbd-dev \ 84 | libseccomp-dev \ 85 | libssh-dev \ 86 | libusb-1.0-0-dev \ 87 | libusbredirparser-dev \ 88 | libxen-dev \ 89 | make \ 90 | pkg-config \ 91 | python3 \ 92 | zlib1g-dev \ 93 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 94 | ninja-build \ 95 | python3-setuptools \ 96 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 97 | libfuse3-dev \ 98 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 99 | libslirp-dev \ 100 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 101 | python3-venv \ 102 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 103 | git \ 104 | ; \ 105 | rm -rf /var/lib/apt/lists/*; \ 106 | \ 107 | tarball="$(basename "$QEMU_URL")"; \ 108 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 109 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 110 | \ 111 | export GNUPGHOME="$(mktemp -d)"; \ 112 | for key in $QEMU_KEYS; do \ 113 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 114 | done; \ 115 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 116 | gpgconf --kill all; \ 117 | rm -rf "$GNUPGHOME"; \ 118 | \ 119 | mkdir /usr/src/qemu; \ 120 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 121 | rm "$tarball" "$tarball.sig"; \ 122 | \ 123 | cd /usr/src/qemu; \ 124 | \ 125 | for p in /qemu-patches/*.patch; do \ 126 | patch --strip 1 --input "$p"; \ 127 | done; \ 128 | rm -rf /qemu-patches; \ 129 | \ 130 | arch="$(dpkg --print-architecture)"; \ 131 | case "$arch" in \ 132 | amd64) targetList='x86_64-softmmu' ;; \ 133 | arm64) targetList='aarch64-softmmu' ;; \ 134 | armel | armhf) targetList='arm-softmmu' ;; \ 135 | i386) targetList='i386-softmmu' ;; \ 136 | mips64el) targetList='mips64el-softmmu' ;; \ 137 | ppc64el) targetList='ppc64-softmmu' ;; \ 138 | s390x) targetList='s390x-softmmu' ;; \ 139 | *) echo >&2 "error: architecture '$arch' unimplemented 😅"; exit 1 ;; \ 140 | esac; \ 141 | \ 142 | ./configure --help; \ 143 | ./configure \ 144 | # 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:) 145 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 146 | --target-list="$targetList" \ 147 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 148 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 149 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 150 | --disable-docs \ 151 | --disable-gtk --disable-vte \ 152 | --disable-sdl \ 153 | --enable-attr \ 154 | --enable-bzip2 \ 155 | --enable-cap-ng \ 156 | --enable-curl \ 157 | --enable-curses \ 158 | --enable-fdt \ 159 | --enable-gnutls \ 160 | --enable-kvm \ 161 | --enable-libiscsi \ 162 | --enable-libnfs \ 163 | --enable-libssh \ 164 | --enable-libusb \ 165 | --enable-linux-aio \ 166 | --enable-modules \ 167 | --enable-numa \ 168 | --enable-rbd \ 169 | --enable-seccomp \ 170 | --enable-strip \ 171 | --enable-tools \ 172 | --enable-usb-redir \ 173 | --enable-vhost-net \ 174 | --enable-vhost-user \ 175 | --enable-vhost-vdpa \ 176 | --enable-virtfs \ 177 | --enable-vnc \ 178 | --enable-vnc-jpeg \ 179 | --enable-xen \ 180 | # 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) 181 | # --enable-vde \ 182 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 183 | --enable-fuse \ 184 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 185 | --enable-slirp \ 186 | ; \ 187 | make -j "$(nproc)"; \ 188 | make install; \ 189 | \ 190 | cd /; \ 191 | rm -rf /usr/src/qemu; \ 192 | \ 193 | apt-mark auto '.*' > /dev/null; \ 194 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 195 | find /usr/local \ 196 | -type f \ 197 | \( -executable -o -name '*.so' \) \ 198 | # 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) 199 | -not -name 'block-rbd.so' \ 200 | -exec ldd '{}' ';' \ 201 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 202 | | sort -u \ 203 | | xargs -r dpkg-query --search \ 204 | | cut -d: -f1 \ 205 | | sort -u \ 206 | | xargs -r apt-mark manual \ 207 | ; \ 208 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 209 | \ 210 | # basic smoke test 211 | qemu-img --version 212 | 213 | STOPSIGNAL SIGHUP 214 | 215 | EXPOSE 22 216 | EXPOSE 5900 217 | 218 | COPY start-qemu /usr/local/bin/ 219 | CMD ["start-qemu"] 220 | -------------------------------------------------------------------------------- /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 ce8977c6a2..392e4c88be 100644 6 | --- a/system/runstate.c 7 | +++ b/system/runstate.c 8 | @@ -613,7 +613,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 | - shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 13 | + if (signal == SIGHUP) { 14 | + powerdown_requested = 1; 15 | + } else { 16 | + shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 17 | + } 18 | qemu_notify_event(); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /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:bookworm-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 | rm -rf /var/lib/apt/lists/* 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 update; \ 62 | apt-get install -y --no-install-recommends \ 63 | gnupg \ 64 | wget \ 65 | xz-utils \ 66 | \ 67 | patch \ 68 | \ 69 | bzip2 \ 70 | gcc \ 71 | gnutls-dev \ 72 | libaio-dev \ 73 | libbz2-dev \ 74 | libc-dev \ 75 | libcap-dev \ 76 | libcap-ng-dev \ 77 | libcurl4-gnutls-dev \ 78 | libglib2.0-dev \ 79 | libiscsi-dev \ 80 | libjpeg-dev \ 81 | libncursesw5-dev \ 82 | libnfs-dev \ 83 | libnuma-dev \ 84 | libpixman-1-dev \ 85 | libpng-dev \ 86 | librbd-dev \ 87 | libseccomp-dev \ 88 | libssh-dev \ 89 | libusb-1.0-0-dev \ 90 | libusbredirparser-dev \ 91 | libxen-dev \ 92 | make \ 93 | pkg-config \ 94 | python3 \ 95 | zlib1g-dev \ 96 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 97 | ninja-build \ 98 | python3-setuptools \ 99 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 100 | libfuse3-dev \ 101 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 102 | libslirp-dev \ 103 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 104 | python3-venv \ 105 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 106 | git \ 107 | ; \ 108 | rm -rf /var/lib/apt/lists/*; \ 109 | \ 110 | tarball="$(basename "$QEMU_URL")"; \ 111 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 112 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 113 | \ 114 | export GNUPGHOME="$(mktemp -d)"; \ 115 | for key in $QEMU_KEYS; do \ 116 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 117 | done; \ 118 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 119 | gpgconf --kill all; \ 120 | rm -rf "$GNUPGHOME"; \ 121 | \ 122 | mkdir /usr/src/qemu; \ 123 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 124 | rm "$tarball" "$tarball.sig"; \ 125 | \ 126 | cd /usr/src/qemu; \ 127 | \ 128 | for p in /qemu-patches/*.patch; do \ 129 | patch --strip 1 --input "$p"; \ 130 | done; \ 131 | rm -rf /qemu-patches; \ 132 | \ 133 | ./configure --help; \ 134 | ./configure \ 135 | # 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:) 136 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 137 | --target-list=' \ 138 | # system targets 139 | # (https://sources.debian.org/src/qemu/buster/debian/rules/#L59-L63, slimmed) 140 | i386-softmmu x86_64-softmmu aarch64-softmmu arm-softmmu m68k-softmmu \ 141 | mips64-softmmu mips64el-softmmu ppc64-softmmu riscv64-softmmu \ 142 | sparc64-softmmu s390x-softmmu \ 143 | ' \ 144 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 145 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 146 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 147 | --disable-docs \ 148 | --disable-gtk --disable-vte \ 149 | --disable-sdl \ 150 | --enable-attr \ 151 | --enable-bzip2 \ 152 | --enable-cap-ng \ 153 | --enable-curl \ 154 | --enable-curses \ 155 | --enable-fdt \ 156 | --enable-gnutls \ 157 | --enable-kvm \ 158 | --enable-libiscsi \ 159 | --enable-libnfs \ 160 | --enable-libssh \ 161 | --enable-libusb \ 162 | --enable-linux-aio \ 163 | --enable-modules \ 164 | --enable-numa \ 165 | --enable-rbd \ 166 | --enable-seccomp \ 167 | --enable-strip \ 168 | --enable-tools \ 169 | --enable-usb-redir \ 170 | --enable-vhost-net \ 171 | --enable-vhost-user \ 172 | --enable-vhost-vdpa \ 173 | --enable-virtfs \ 174 | --enable-vnc \ 175 | --enable-vnc-jpeg \ 176 | --enable-xen \ 177 | # 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) 178 | # --enable-vde \ 179 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 180 | --enable-fuse \ 181 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 182 | --enable-slirp \ 183 | ; \ 184 | make -j "$(nproc)"; \ 185 | make install; \ 186 | \ 187 | cd /; \ 188 | rm -rf /usr/src/qemu; \ 189 | \ 190 | apt-mark auto '.*' > /dev/null; \ 191 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 192 | find /usr/local \ 193 | -type f \ 194 | \( -executable -o -name '*.so' \) \ 195 | # 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) 196 | -not -name 'block-rbd.so' \ 197 | -exec ldd '{}' ';' \ 198 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 199 | | sort -u \ 200 | | xargs -r dpkg-query --search \ 201 | | cut -d: -f1 \ 202 | | sort -u \ 203 | | xargs -r apt-mark manual \ 204 | ; \ 205 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 206 | \ 207 | # basic smoke test 208 | qemu-img --version 209 | 210 | STOPSIGNAL SIGHUP 211 | 212 | EXPOSE 22 213 | EXPOSE 5900 214 | 215 | COPY start-qemu /usr/local/bin/ 216 | CMD ["start-qemu"] 217 | -------------------------------------------------------------------------------- /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:bookworm-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 | rm -rf /var/lib/apt/lists/* 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 update; \ 59 | apt-get install -y --no-install-recommends \ 60 | gnupg \ 61 | wget \ 62 | xz-utils \ 63 | \ 64 | patch \ 65 | \ 66 | bzip2 \ 67 | gcc \ 68 | gnutls-dev \ 69 | libaio-dev \ 70 | libbz2-dev \ 71 | libc-dev \ 72 | libcap-dev \ 73 | libcap-ng-dev \ 74 | libcurl4-gnutls-dev \ 75 | libglib2.0-dev \ 76 | libiscsi-dev \ 77 | libjpeg-dev \ 78 | libncursesw5-dev \ 79 | libnfs-dev \ 80 | libnuma-dev \ 81 | libpixman-1-dev \ 82 | libpng-dev \ 83 | librbd-dev \ 84 | libseccomp-dev \ 85 | libssh-dev \ 86 | libusb-1.0-0-dev \ 87 | libusbredirparser-dev \ 88 | libxen-dev \ 89 | make \ 90 | pkg-config \ 91 | python3 \ 92 | zlib1g-dev \ 93 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 94 | ninja-build \ 95 | python3-setuptools \ 96 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 97 | libfuse3-dev \ 98 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 99 | libslirp-dev \ 100 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 101 | python3-venv \ 102 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 103 | git \ 104 | ; \ 105 | rm -rf /var/lib/apt/lists/*; \ 106 | \ 107 | tarball="$(basename "$QEMU_URL")"; \ 108 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 109 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 110 | \ 111 | export GNUPGHOME="$(mktemp -d)"; \ 112 | for key in $QEMU_KEYS; do \ 113 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 114 | done; \ 115 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 116 | gpgconf --kill all; \ 117 | rm -rf "$GNUPGHOME"; \ 118 | \ 119 | mkdir /usr/src/qemu; \ 120 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 121 | rm "$tarball" "$tarball.sig"; \ 122 | \ 123 | cd /usr/src/qemu; \ 124 | \ 125 | for p in /qemu-patches/*.patch; do \ 126 | patch --strip 1 --input "$p"; \ 127 | done; \ 128 | rm -rf /qemu-patches; \ 129 | \ 130 | arch="$(dpkg --print-architecture)"; \ 131 | case "$arch" in \ 132 | amd64) targetList='x86_64-softmmu' ;; \ 133 | arm64) targetList='aarch64-softmmu' ;; \ 134 | armel | armhf) targetList='arm-softmmu' ;; \ 135 | i386) targetList='i386-softmmu' ;; \ 136 | mips64el) targetList='mips64el-softmmu' ;; \ 137 | ppc64el) targetList='ppc64-softmmu' ;; \ 138 | s390x) targetList='s390x-softmmu' ;; \ 139 | *) echo >&2 "error: architecture '$arch' unimplemented 😅"; exit 1 ;; \ 140 | esac; \ 141 | \ 142 | ./configure --help; \ 143 | ./configure \ 144 | # 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:) 145 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 146 | --target-list="$targetList" \ 147 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 148 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 149 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 150 | --disable-docs \ 151 | --disable-gtk --disable-vte \ 152 | --disable-sdl \ 153 | --enable-attr \ 154 | --enable-bzip2 \ 155 | --enable-cap-ng \ 156 | --enable-curl \ 157 | --enable-curses \ 158 | --enable-fdt \ 159 | --enable-gnutls \ 160 | --enable-kvm \ 161 | --enable-libiscsi \ 162 | --enable-libnfs \ 163 | --enable-libssh \ 164 | --enable-libusb \ 165 | --enable-linux-aio \ 166 | --enable-modules \ 167 | --enable-numa \ 168 | --enable-rbd \ 169 | --enable-seccomp \ 170 | --enable-strip \ 171 | --enable-tools \ 172 | --enable-usb-redir \ 173 | --enable-vhost-net \ 174 | --enable-vhost-user \ 175 | --enable-vhost-vdpa \ 176 | --enable-virtfs \ 177 | --enable-vnc \ 178 | --enable-vnc-jpeg \ 179 | --enable-xen \ 180 | # 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) 181 | # --enable-vde \ 182 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 183 | --enable-fuse \ 184 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 185 | --enable-slirp \ 186 | ; \ 187 | make -j "$(nproc)"; \ 188 | make install; \ 189 | \ 190 | cd /; \ 191 | rm -rf /usr/src/qemu; \ 192 | \ 193 | apt-mark auto '.*' > /dev/null; \ 194 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 195 | find /usr/local \ 196 | -type f \ 197 | \( -executable -o -name '*.so' \) \ 198 | # 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) 199 | -not -name 'block-rbd.so' \ 200 | -exec ldd '{}' ';' \ 201 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 202 | | sort -u \ 203 | | xargs -r dpkg-query --search \ 204 | | cut -d: -f1 \ 205 | | sort -u \ 206 | | xargs -r apt-mark manual \ 207 | ; \ 208 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 209 | \ 210 | # basic smoke test 211 | qemu-img --version 212 | 213 | STOPSIGNAL SIGHUP 214 | 215 | EXPOSE 22 216 | EXPOSE 5900 217 | 218 | COPY start-qemu /usr/local/bin/ 219 | CMD ["start-qemu"] 220 | -------------------------------------------------------------------------------- /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 ce8977c6a2..392e4c88be 100644 6 | --- a/system/runstate.c 7 | +++ b/system/runstate.c 8 | @@ -613,7 +613,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 | - shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 13 | + if (signal == SIGHUP) { 14 | + powerdown_requested = 1; 15 | + } else { 16 | + shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL; 17 | + } 18 | qemu_notify_event(); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /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:bookworm-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 | rm -rf /var/lib/apt/lists/* 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 update; \ 84 | apt-get install -y --no-install-recommends \ 85 | gnupg \ 86 | wget \ 87 | xz-utils \ 88 | \ 89 | patch \ 90 | \ 91 | bzip2 \ 92 | gcc \ 93 | gnutls-dev \ 94 | libaio-dev \ 95 | libbz2-dev \ 96 | libc-dev \ 97 | libcap-dev \ 98 | libcap-ng-dev \ 99 | libcurl4-gnutls-dev \ 100 | libglib2.0-dev \ 101 | libiscsi-dev \ 102 | libjpeg-dev \ 103 | libncursesw5-dev \ 104 | libnfs-dev \ 105 | libnuma-dev \ 106 | libpixman-1-dev \ 107 | libpng-dev \ 108 | librbd-dev \ 109 | libseccomp-dev \ 110 | libssh-dev \ 111 | libusb-1.0-0-dev \ 112 | libusbredirparser-dev \ 113 | libxen-dev \ 114 | make \ 115 | pkg-config \ 116 | python3 \ 117 | zlib1g-dev \ 118 | # https://wiki.qemu.org/ChangeLog/5.2#Build_Information 119 | ninja-build \ 120 | python3-setuptools \ 121 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 122 | libfuse3-dev \ 123 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 124 | libslirp-dev \ 125 | {{ if env.version | IN("7.2", "8.0") then "" else ( -}} 126 | # https://wiki.qemu.org/ChangeLog/8.1#Build_Dependencies 127 | python3-venv \ 128 | # "../meson.build:3070:18: ERROR: Git program not found, cannot download dtc.wrap via git." 129 | git \ 130 | {{ ) end -}} 131 | ; \ 132 | rm -rf /var/lib/apt/lists/*; \ 133 | \ 134 | tarball="$(basename "$QEMU_URL")"; \ 135 | wget -O "$tarball.sig" "$QEMU_URL.sig"; \ 136 | wget -O "$tarball" "$QEMU_URL" --progress=dot:giga; \ 137 | \ 138 | export GNUPGHOME="$(mktemp -d)"; \ 139 | for key in $QEMU_KEYS; do \ 140 | gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key"; \ 141 | done; \ 142 | gpg --batch --verify "$tarball.sig" "$tarball"; \ 143 | gpgconf --kill all; \ 144 | rm -rf "$GNUPGHOME"; \ 145 | \ 146 | mkdir /usr/src/qemu; \ 147 | tar -xf "$tarball" -C /usr/src/qemu --strip-components=1; \ 148 | rm "$tarball" "$tarball.sig"; \ 149 | \ 150 | cd /usr/src/qemu; \ 151 | \ 152 | for p in /qemu-patches/*.patch; do \ 153 | patch --strip 1 --input "$p"; \ 154 | done; \ 155 | rm -rf /qemu-patches; \ 156 | {{ if env.variant == "native" then ( -}} 157 | \ 158 | arch="$(dpkg --print-architecture)"; \ 159 | case "$arch" in \ 160 | amd64) targetList='x86_64-softmmu' ;; \ 161 | arm64) targetList='aarch64-softmmu' ;; \ 162 | armel | armhf) targetList='arm-softmmu' ;; \ 163 | i386) targetList='i386-softmmu' ;; \ 164 | mips64el) targetList='mips64el-softmmu' ;; \ 165 | ppc64el) targetList='ppc64-softmmu' ;; \ 166 | s390x) targetList='s390x-softmmu' ;; \ 167 | *) echo >&2 "error: architecture '$arch' unimplemented 😅"; exit 1 ;; \ 168 | esac; \ 169 | {{ ) else "" end -}} 170 | \ 171 | ./configure --help; \ 172 | ./configure \ 173 | # 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:) 174 | --with-pkgversion='https://github.com/tianon/docker-qemu' \ 175 | {{ if env.variant == "native" then ( -}} 176 | --target-list="$targetList" \ 177 | {{ ) else ( -}} 178 | --target-list=' \ 179 | # system targets 180 | # (https://sources.debian.org/src/qemu/buster/debian/rules/#L59-L63, slimmed) 181 | i386-softmmu x86_64-softmmu aarch64-softmmu arm-softmmu m68k-softmmu \ 182 | mips64-softmmu mips64el-softmmu ppc64-softmmu riscv64-softmmu \ 183 | sparc64-softmmu s390x-softmmu \ 184 | ' \ 185 | {{ ) end -}} 186 | # let's point "firmware path" to Debian's value so we get access to "OVMF.fd" and friends more easily 187 | --firmwarepath=/usr/share/qemu:/usr/share/seabios:/usr/lib/ipxe/qemu \ 188 | # https://salsa.debian.org/qemu-team/qemu/-/blob/058ab4ec8623766b50055c8c56d0d5448d52fb0a/debian/rules#L38 189 | --disable-docs \ 190 | --disable-gtk --disable-vte \ 191 | --disable-sdl \ 192 | --enable-attr \ 193 | --enable-bzip2 \ 194 | --enable-cap-ng \ 195 | --enable-curl \ 196 | --enable-curses \ 197 | --enable-fdt \ 198 | --enable-gnutls \ 199 | --enable-kvm \ 200 | --enable-libiscsi \ 201 | --enable-libnfs \ 202 | --enable-libssh \ 203 | --enable-libusb \ 204 | --enable-linux-aio \ 205 | --enable-modules \ 206 | --enable-numa \ 207 | --enable-rbd \ 208 | --enable-seccomp \ 209 | --enable-strip \ 210 | --enable-tools \ 211 | --enable-usb-redir \ 212 | --enable-vhost-net \ 213 | --enable-vhost-user \ 214 | --enable-vhost-vdpa \ 215 | --enable-virtfs \ 216 | --enable-vnc \ 217 | --enable-vnc-jpeg \ 218 | --enable-xen \ 219 | # 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) 220 | # --enable-vde \ 221 | # https://www.qemu.org/2021/08/22/fuse-blkexport/ 222 | --enable-fuse \ 223 | # https://wiki.qemu.org/ChangeLog/7.2#Removal_of_the_.22slirp.22_submodule_.28affects_.22-netdev_user.22.29 224 | --enable-slirp \ 225 | ; \ 226 | make -j "$(nproc)"; \ 227 | make install; \ 228 | \ 229 | cd /; \ 230 | rm -rf /usr/src/qemu; \ 231 | \ 232 | apt-mark auto '.*' > /dev/null; \ 233 | [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \ 234 | find /usr/local \ 235 | -type f \ 236 | \( -executable -o -name '*.so' \) \ 237 | # 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) 238 | -not -name 'block-rbd.so' \ 239 | -exec ldd '{}' ';' \ 240 | | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); printf "*%s\n", so }' \ 241 | | sort -u \ 242 | | xargs -r dpkg-query --search \ 243 | | cut -d: -f1 \ 244 | | sort -u \ 245 | | xargs -r apt-mark manual \ 246 | ; \ 247 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 248 | \ 249 | # basic smoke test 250 | qemu-img --version 251 | 252 | STOPSIGNAL SIGHUP 253 | 254 | EXPOSE 22 255 | EXPOSE 5900 256 | 257 | COPY start-qemu /usr/local/bin/ 258 | CMD ["start-qemu"] 259 | -------------------------------------------------------------------------------- /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.0]='10 latest' 6 | [9.2]='9' 7 | [8.2]='8' 8 | [7.2]='7' 9 | ) 10 | 11 | self="$(basename "$BASH_SOURCE")" 12 | cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" 13 | 14 | if [ "$#" -eq 0 ]; then 15 | versions="$(jq -r 'keys | map(@sh) | join(" ")' versions.json)" 16 | eval "set -- $versions" 17 | fi 18 | 19 | # sort version numbers with highest first 20 | IFS=$'\n'; versions=( $(echo "${versions[*]}" | sort -rV) ); unset IFS 21 | 22 | # get the most recent commit which modified any of "$@" 23 | fileCommit() { 24 | git log -1 --format='format:%H' HEAD -- "$@" 25 | } 26 | 27 | # get the most recent commit which modified "$1/Dockerfile" or any file COPY'd from "$1/Dockerfile" 28 | dirCommit() { 29 | local dir="$1"; shift 30 | ( 31 | cd "$dir" 32 | files="$( 33 | git show HEAD:./Dockerfile HEAD:./Dockerfile.native | awk ' 34 | toupper($1) == "COPY" { 35 | for (i = 2; i < NF; i++) { 36 | if ($i ~ /^--from=/) { 37 | next 38 | } 39 | print $i 40 | } 41 | } 42 | ' 43 | )" 44 | fileCommit Dockerfile Dockerfile.native $files 45 | ) 46 | } 47 | 48 | getArches() { 49 | local officialImagesUrl='https://github.com/docker-library/official-images/raw/master/library/' 50 | 51 | eval "declare -g -A parentRepoToArches=( $( 52 | find -name 'Dockerfile*' -exec awk ' 53 | toupper($1) == "FROM" && $2 !~ /^(scratch|.*\/.*)(:|$)/ { 54 | print "'"$officialImagesUrl"'" $2 55 | } 56 | ' '{}' + \ 57 | | sort -u \ 58 | | xargs bashbrew cat --format '[{{ .RepoName }}:{{ .TagName }}]="{{ join " " .TagEntry.Architectures }}"' 59 | ) )" 60 | } 61 | getArches 62 | 63 | cat <<-EOH 64 | # this file is generated via https://github.com/tianon/docker-qemu/blob/$(fileCommit "$self")/$self 65 | 66 | Maintainers: Tianon Gravi (@tianon) 67 | GitRepo: https://github.com/tianon/docker-qemu.git 68 | EOH 69 | 70 | # prints "$2$1$3$1...$N" 71 | join() { 72 | local sep="$1"; shift 73 | local out; printf -v out "${sep//%/%%}%s" "$@" 74 | echo "${out#$sep}" 75 | } 76 | 77 | for version; do 78 | fullVersion="$(jq -r --arg version "$version" '.[$version].version' versions.json)" 79 | 80 | rcVersion="${version%-rc}" 81 | 82 | versionAliases=() 83 | while [ "$fullVersion" != "$rcVersion" -a "${fullVersion%[.]*}" != "$fullVersion" ]; do 84 | versionAliases+=( $fullVersion ) 85 | fullVersion="${fullVersion%[.]*}" 86 | done 87 | versionAliases+=( 88 | $version 89 | ${aliases[$version]:-} 90 | ) 91 | 92 | commit="$(dirCommit "$version")" 93 | 94 | for variant in '' native; do 95 | variantAliases=( "${versionAliases[@]}" ) 96 | if [ -n "$variant" ]; then 97 | variantAliases=( "${variantAliases[@]/%/-$variant}" ) 98 | variantAliases=( "${variantAliases[@]//latest-/}" ) 99 | fi 100 | 101 | variantParent="$(awk 'toupper($1) == "FROM" { print $2 }' "$version/Dockerfile${variant:+.$variant}")" 102 | 103 | suite="${variantParent#*:}" # "buster-slim", "buster" 104 | suite="${suite%-slim}" # "buster" 105 | suiteAliases=( "${variantAliases[@]/%/-$suite}" ) 106 | suiteAliases=( "${suiteAliases[@]//latest-/}" ) 107 | variantAliases+=( "${suiteAliases[@]}" ) 108 | 109 | case "$variant" in 110 | '') variantArches='amd64' ;; # only make the "fat" variant on amd64 111 | *) variantArches="${parentRepoToArches[$variantParent]}" ;; 112 | esac 113 | 114 | # skip i386 (missing many packages, like libxen-dev; not something I actually care to target) 115 | variantArches="$(sed -e 's/ i386 / /g' <<<" $variantArches ")" 116 | 117 | # architectures I don't think make sense to or I don't care to support 118 | variantArches="$(sed -e 's/ arm32v5 / /g' <<<" $variantArches ")" 119 | variantArches="$(sed -e 's/ mips64le / /g' <<<" $variantArches ")" 120 | variantArches="$(sed -e 's/ ppc64le / /g' <<<" $variantArches ")" 121 | variantArches="$(sed -e 's/ s390x / /g' <<<" $variantArches ")" 122 | 123 | echo 124 | cat <<-EOE 125 | Tags: $(join ', ' "${variantAliases[@]}") 126 | Architectures: $(join ', ' $variantArches) 127 | GitCommit: $commit 128 | Directory: $version 129 | EOE 130 | if [ -n "$variant" ]; then 131 | echo "File: Dockerfile.$variant" 132 | fi 133 | done 134 | done 135 | -------------------------------------------------------------------------------- /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.2.tar.xz", 4 | "version": "10.0.2" 5 | }, 6 | "7.2": { 7 | "url": "https://download.qemu.org/qemu-7.2.18.tar.xz", 8 | "version": "7.2.18" 9 | }, 10 | "8.2": { 11 | "url": "https://download.qemu.org/qemu-8.2.10.tar.xz", 12 | "version": "8.2.10" 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 | 18 | # https://download.qemu.org/?C=M;O=D 19 | urls="$( 20 | wget -qO- 'https://www.qemu.org/download/' \ 21 | | grep -oE 'https://download[.]qemu[.]org/qemu-([^"]+)[.]tar[.]xz' \ 22 | | sort -ruV 23 | )" 24 | 25 | for version in "${versions[@]}"; do 26 | rcGrepV='-v' 27 | rcVersion="${version%-rc}" 28 | if [ "$rcVersion" != "$version" ]; then 29 | rcGrepV= 30 | fi 31 | 32 | url="$( 33 | grep -E "qemu-$rcVersion([.-])" <<<"$urls" \ 34 | | grep $rcGrepV -E -- '-rc' \ 35 | | head -1 36 | )" 37 | fullVersion="${url##*/qemu-}" 38 | fullVersion="${fullVersion%%.tar.*}" 39 | 40 | echo "$version: $fullVersion" 41 | 42 | export version fullVersion url 43 | json="$(jq <<<"$json" ' 44 | .[env.version] = { 45 | version: env.fullVersion, 46 | url: env.url, 47 | } 48 | ')" 49 | done 50 | 51 | jq <<<"$json" -S . > versions.json 52 | --------------------------------------------------------------------------------