Compare commits

..

No commits in common. "master" and "4.9.8" have entirely different histories.

20 changed files with 448 additions and 1530 deletions

View File

@ -16,6 +16,6 @@ jobs:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: DeterminateSystems/nix-installer-action@v22 - uses: DeterminateSystems/nix-installer-action@v21
- uses: DeterminateSystems/magic-nix-cache-action@v9 - uses: DeterminateSystems/magic-nix-cache-action@v9
- uses: DeterminateSystems/flake-checker-action@v12 - uses: DeterminateSystems/flake-checker-action@v12

View File

@ -13,7 +13,7 @@ jobs:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: DeterminateSystems/nix-installer-action@v22 - uses: DeterminateSystems/nix-installer-action@v21
- uses: DeterminateSystems/magic-nix-cache-action@v9 - uses: DeterminateSystems/magic-nix-cache-action@v9
- uses: DeterminateSystems/update-flake-lock@v28 - uses: DeterminateSystems/update-flake-lock@v28
with: with:

View File

@ -106,7 +106,7 @@ jobs:
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Import gpg key 🔑" - name: "Import gpg key 🔑"
uses: crazy-max/ghaction-import-gpg@v7 uses: crazy-max/ghaction-import-gpg@v6
with: with:
gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.PPA_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.PPA_GPG_PASSPHRASE }} passphrase: ${{ secrets.PPA_GPG_PASSPHRASE }}

View File

@ -53,7 +53,7 @@ jobs:
- name: "Checkout 🥡" - name: "Checkout 🥡"
uses: "actions/checkout@v6" uses: "actions/checkout@v6"
- name: "Install Nix ❄️" - name: "Install Nix ❄️"
uses: "DeterminateSystems/nix-installer-action@v22" uses: "DeterminateSystems/nix-installer-action@v21"
- name: "Enable Magic Nix Cache 🪄" - name: "Enable Magic Nix Cache 🪄"
uses: "DeterminateSystems/magic-nix-cache-action@v9" uses: "DeterminateSystems/magic-nix-cache-action@v9"
- name: "Build & Test .nix ❄️" - name: "Build & Test .nix ❄️"

View File

@ -50,7 +50,7 @@ jobs:
id: check id: check
run: | run: |
mkdir -p results mkdir -p results
./quickget --check-all-arch "${{ matrix.distro }}" | tee results/check.txt ./quickget --check "${{ matrix.distro }}" | tee results/check.txt
# Count results (use wc -l to avoid grep exit code issues) # Count results (use wc -l to avoid grep exit code issues)
PASSED=$(grep '^PASS' results/check.txt | wc -l | tr -d ' ') PASSED=$(grep '^PASS' results/check.txt | wc -l | tr -d ' ')
@ -83,7 +83,7 @@ jobs:
cat result/result.json cat result/result.json
- name: "Upload result artifact 📤" - name: "Upload result artifact 📤"
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v4
with: with:
name: result-${{ matrix.distro }} name: result-${{ matrix.distro }}
path: result/ path: result/
@ -101,7 +101,7 @@ jobs:
if: always() if: always()
steps: steps:
- name: "Download all result artifacts 📥" - name: "Download all result artifacts 📥"
uses: actions/download-artifact@v8 uses: actions/download-artifact@v4
with: with:
pattern: result-* pattern: result-*
path: results path: results

View File

@ -27,8 +27,6 @@ The devshell patches `quickemu` to use Nix store paths for OVMF and Samba, writi
- Lint scripts: `shellcheck quickemu quickget quickreport chunkcheck` - Lint scripts: `shellcheck quickemu quickget quickreport chunkcheck`
- Test quickget URLs: `./quickget --check <os> [release] [edition]` - Test quickget URLs: `./quickget --check <os> [release] [edition]`
- Test ARM64 downloads: `./quickget --arch arm64 --check <os> [release] [edition]`
- Test all architectures: `./quickget --check-all-arch <os> [release] [edition]`
- List all supported OSes: `./quickget --list` - List all supported OSes: `./quickget --list`
- Run VM: `./quickemu --vm <name>.conf` - Run VM: `./quickemu --vm <name>.conf`
@ -55,8 +53,7 @@ Follow the [guide in the wiki](https://github.com/quickemu-project/quickemu/wiki
1. Entry in `os_info()` case statement 1. Entry in `os_info()` case statement
2. `releases_<os>()` function returning available versions 2. `releases_<os>()` function returning available versions
3. `editions_<os>()` function if multiple editions exist 3. `editions_<os>()` function if multiple editions exist
4. `arch_<os>()` function if ARM64 is supported (defaults to amd64 only if omitted) 4. Download URL construction logic
5. Download URL construction logic
## Commit message format ## Commit message format
@ -99,13 +96,10 @@ fix(quickget): remove Athena OS (no longer getting updates)
## Platform support ## Platform support
- Host: Linux (x86_64, aarch64), macOS (x86_64, aarch64) - Host: Linux (x86_64, aarch64), macOS (x86_64, aarch64)
- Guest: x86_64 (default), aarch64 (set `arch="aarch64"` in VM config)
- ARM64 guests use AAVMF firmware and `virt` machine type
- Cross-arch emulation uses TCG (no KVM acceleration)
- OVMF/UEFI firmware: Linux only - OVMF/UEFI firmware: Linux only
- Bash 4.0+ required (explicit version check at runtime) - Bash 4.0+ required (explicit version check at runtime)
## Key dependencies ## Key dependencies
Runtime: qemu, cdrtools, curl, jq, spice-gtk, swtpm, samba, zsync Runtime: qemu, cdrtools, curl, jq, spice-gtk, swtpm, samba, zsync
Linux-specific: OVMF (x86_64 guests), AAVMF (aarch64 guests), usbutils, mesa-demos Linux-specific: OVMF, usbutils, mesa-demos

View File

@ -41,7 +41,6 @@ required to run the virtual machines.
- **macOS** Sequoia, Sonoma, Ventura, Monterey, Big Sur, Catalina & Mojave - **macOS** Sequoia, Sonoma, Ventura, Monterey, Big Sur, Catalina & Mojave
- **Windows** 10 and 11 including TPM 2.0 - **Windows** 10 and 11 including TPM 2.0
- **Windows Server** 2022 2019 2016 - **Windows Server** 2022 2019 2016
- **ARM64 guest support** for running aarch64 VMs (native on ARM hosts, emulated on x86_64)
- [Ubuntu](https://ubuntu.com/desktop) and all the **[official Ubuntu - [Ubuntu](https://ubuntu.com/desktop) and all the **[official Ubuntu
flavours](https://ubuntu.com/download/flavours)** flavours](https://ubuntu.com/download/flavours)**
- **Nearly 1000 operating system editions are supported!** - **Nearly 1000 operating system editions are supported!**

@ -1 +1 @@
Subproject commit f9582c397c8ac9f1fc6ab2d6882d5ef51dc5efda Subproject commit c5907eae9c0bd9364b4a91a3f449f1d1dbbc58c9

View File

@ -30,7 +30,7 @@ mkShell {
xorg.xrandr xorg.xrandr
zsync zsync
] ]
++ lib.optionals stdenv.hostPlatform.isLinux [ ++ lib.optionals stdenv.isLinux [
mesa-demos mesa-demos
usbutils usbutils
xdg-user-dirs xdg-user-dirs
@ -52,14 +52,10 @@ mkShell {
sed \ sed \
${ ${
lib.optionalString (OVMF != null && OVMFFull != null) '' lib.optionalString (OVMF != null && OVMFFull != null) ''
-e '/OVMF_CODE_4M.secboot.fd/s|ovmfs=(|ovmfs=("${OVMFFull.firmware}","${OVMFFull.variablesMs}" |' \ -e '/OVMF_CODE_4M.secboot.fd/s|ovmfs=(|ovmfs=("${OVMFFull.firmware}","${OVMFFull.variables}" |' \
-e '/OVMF_CODE_4M.fd/s|ovmfs=(|ovmfs=("${OVMF.firmware}","${OVMF.variables}" |' \ -e '/OVMF_CODE_4M.fd/s|ovmfs=(|ovmfs=("${OVMF.firmware}","${OVMF.variables}" |' \
'' ''
}${lib.optionalString stdenv.hostPlatform.isDarwin '' } \
-e 's|ovmfs=("[$][{]SHARE_PATH}/OVMF/OVMF_CODE_4M.secboot.fd"|ovmfs=("${pkgs.qemu_full}/share/qemu/edk2-x86_64-secure-code.fd","${pkgs.qemu_full}/share/qemu/edk2-i386-vars.fd" "''${SHARE_PATH}/OVMF/OVMF_CODE_4M.secboot.fd"|' \
-e 's|ovmfs=("[$][{]SHARE_PATH}/OVMF/OVMF_CODE_4M.fd"|ovmfs=("${pkgs.qemu_full}/share/qemu/edk2-x86_64-code.fd","${pkgs.qemu_full}/share/qemu/edk2-i386-vars.fd" "''${SHARE_PATH}/OVMF/OVMF_CODE_4M.fd"|' \
-e 's|ovmfs=("/usr/share/AAVMF/AAVMF_CODE.fd"|ovmfs=("${pkgs.qemu_full}/share/qemu/edk2-aarch64-code.fd","${pkgs.qemu_full}/share/qemu/edk2-arm-vars.fd" "/usr/share/AAVMF/AAVMF_CODE.fd"|' \
''} \
-e '/cp "''${VARS_IN}" "''${VARS_OUT}"/a chmod +w "''${VARS_OUT}"' \ -e '/cp "''${VARS_IN}" "''${VARS_OUT}"/a chmod +w "''${VARS_OUT}"' \
-e 's,\$(command -v smbd),${pkgs.samba}/bin/smbd,' \ -e 's,\$(command -v smbd),${pkgs.samba}/bin/smbd,' \
quickemu > $PWD/.direnv/bin/quickemu quickemu > $PWD/.direnv/bin/quickemu

View File

@ -1,6 +1,6 @@
.\" Automatically generated by Pandoc 3.8.3 .\" Automatically generated by Pandoc 3.7.0.2
.\" .\"
.TH "QUICKEMU" "1" "February 2, 2026" "quickemu" "Quickemu User Manual" .TH "QUICKEMU" "1" "July 31, 2025" "quickemu" "Quickemu User Manual"
.SH NAME .SH NAME
quickemu \- A quick VM builder and manager quickemu \- A quick VM builder and manager
.SH SYNOPSIS .SH SYNOPSIS
@ -31,8 +31,8 @@ Delete the entire VM and its configuration
.TP .TP
\f[B]\-\-display\f[R] \f[B]\-\-display\f[R]
Select display backend. Select display backend.
\(aqgtk\(aq (default), \(aqsdl\(aq, \(aqcocoa\(aq, \(aqnone\(aq, \(aqsdl\(aq (default), \(aqgtk\(aq, \(aqnone\(aq, \(aqspice\(aq or
\(aqspice\(aq or \(aqspice\-app\(aq \(aqspice\-app\(aq
.TP .TP
\f[B]\-\-fullscreen\f[R] \f[B]\-\-fullscreen\f[R]
Starts VM in full screen mode (Ctl+Alt+f to exit) Starts VM in full screen mode (Ctl+Alt+f to exit)
@ -191,9 +191,6 @@ Mojave
.IP \(bu 2 .IP \(bu 2
\f[B]Windows Server\f[R] 2022 2019 2016 \f[B]Windows Server\f[R] 2022 2019 2016
.IP \(bu 2 .IP \(bu 2
\f[B]ARM64 guest support\f[R] for running aarch64 VMs (native on ARM
hosts, emulated on x86_64)
.IP \(bu 2
\c \c
.UR https://ubuntu.com/desktop .UR https://ubuntu.com/desktop
Ubuntu Ubuntu
@ -573,23 +570,18 @@ wiki
You can also use \f[CR]quickget\f[R] with advanced options : You can also use \f[CR]quickget\f[R] with advanced options :
.IP .IP
.EX .EX
\-\-arch <arch> : Set architecture (arm64, aarch64, amd64, x86_64) \-\-download <os> <release> [edition] : Download image; no VM configuration
\-\-download <os> <release> [edition] : Download image; no VM configuration \-\-create\-config <os> [path/url] [flags] : Create VM config for an OS image
\-\-create\-config <os> [path/url] [flags] : Create VM config for an OS image \-\-open\-homepage <os> : Open homepage for the OS
\-\-open\-homepage <os> : Open homepage for the OS \-\-show [os] : Show OS information
\-\-show [os] : Show OS information \-\-version : Show version
\-\-version : Show version \-\-help : Show this help message
\-\-help : Show this help message \-\-disable\-unattended : Force quickget not to set up an unattended installation
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- Flags \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-url [os] [release] [edition] : Show image URL(s)
\-\-create\-config: \-\-check [os] [release] [edition] : Check image URL(s)
\-\-disable\-unattended : Force quickget not to set up an unattended installation \-\-list : List all supported systems
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- For testing & development \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-list\-csv : List everything in csv format
\-\-url [os] [release] [edition] : Show image URL(s) \-\-list\-json : List everything in json format
\-\-check [os] [release] [edition] : Check image URL(s)
\-\-check\-all\-arch [os] [release] [edition] : Check downloads for all architectures (amd64 and arm64)
\-\-list : List all supported systems
\-\-list\-csv : List everything in csv format
\-\-list\-json : List everything in json format
.EE .EE
.PP .PP
Here are some typical uses Here are some typical uses
@ -630,7 +622,7 @@ wiki
.IP \(bu 2 .IP \(bu 2
\f[CR]artixlinux\f[R] (Artix Linux) \f[CR]artixlinux\f[R] (Artix Linux)
.IP \(bu 2 .IP \(bu 2
\f[CR]azurelinux\f[R] (Azure Linux) \f[CR]athenaos\f[R] (Athena OS)
.IP \(bu 2 .IP \(bu 2
\f[CR]batocera\f[R] (Batocera) \f[CR]batocera\f[R] (Batocera)
.IP \(bu 2 .IP \(bu 2
@ -686,6 +678,8 @@ wiki
.IP \(bu 2 .IP \(bu 2
\f[CR]haiku\f[R] (Haiku) \f[CR]haiku\f[R] (Haiku)
.IP \(bu 2 .IP \(bu 2
\f[CR]holoiso\f[R] (HoloISO)
.IP \(bu 2
\f[CR]kali\f[R] (Kali) \f[CR]kali\f[R] (Kali)
.IP \(bu 2 .IP \(bu 2
\f[CR]kdeneon\f[R] (KDE Neon) \f[CR]kdeneon\f[R] (KDE Neon)
@ -758,15 +752,17 @@ wiki
.IP \(bu 2 .IP \(bu 2
\f[CR]solus\f[R] (Solus) \f[CR]solus\f[R] (Solus)
.IP \(bu 2 .IP \(bu 2
\f[CR]sparkylinux\f[R] (SparkyLinux)
.IP \(bu 2
\f[CR]spirallinux\f[R] (SpiralLinux) \f[CR]spirallinux\f[R] (SpiralLinux)
.IP \(bu 2 .IP \(bu 2
\f[CR]tails\f[R] (Tails) \f[CR]tails\f[R] (Tails)
.IP \(bu 2 .IP \(bu 2
\f[CR]tinycore\f[R] (Tiny Core Linux) \f[CR]tinycore\f[R] (Tiny Core Linux)
.IP \(bu 2 .IP \(bu 2
\f[CR]trisquel\f[R] (Trisquel) \f[CR]trisquel\f[R] (Trisquel\-)
.IP \(bu 2
\f[CR]truenas\-core\f[R] (TrueNAS Core)
.IP \(bu 2
\f[CR]truenas\-scale\f[R] (TrueNAS Scale)
.IP \(bu 2 .IP \(bu 2
\f[CR]tuxedo\-os\f[R] (Tuxedo OS) \f[CR]tuxedo\-os\f[R] (Tuxedo OS)
.IP \(bu 2 .IP \(bu 2
@ -774,6 +770,8 @@ wiki
.IP \(bu 2 .IP \(bu 2
\f[CR]void\f[R] (Void Linux) \f[CR]void\f[R] (Void Linux)
.IP \(bu 2 .IP \(bu 2
\f[CR]vxlinux\f[R] (VX Linux)
.IP \(bu 2
\f[CR]zorin\f[R] (Zorin OS) \f[CR]zorin\f[R] (Zorin OS)
.SS \c .SS \c
.UR https://github.com/quickemu-project/quickemu/wiki/02-Create-Linux-virtual-machines#manually-create-linux-guests .UR https://github.com/quickemu-project/quickemu/wiki/02-Create-Linux-virtual-machines#manually-create-linux-guests
@ -829,17 +827,6 @@ check the Discussions
.PP .PP
\f[CR]quickget\f[R] automatically downloads a macOS recovery image and \f[CR]quickget\f[R] automatically downloads a macOS recovery image and
creates a virtual machine configuration. creates a virtual machine configuration.
.PP
Note: Some VPN users may need to \c
.UR https://github.com/quickemu-project/quickemu/issues/1391#issuecomment-3506845235
turn off their VPN
.UE \c
\ in order to download a recovery image.
Some other users may find \c
.UR https://github.com/quickemu-project/quickemu/issues/1391#issuecomment-2429146013
using a VPN
.UE \c
\ necessary in order to download a recovery image.
.IP .IP
.EX .EX
quickget macos big\-sur quickget macos big\-sur
@ -944,16 +931,16 @@ The default macOS configuration looks like this:
.IP .IP
.EX .EX
guest_os=\(dqmacos\(dq guest_os=\(dqmacos\(dq
img=\(dqmacos\-big\-sur/RecoveryImage.img\(dq img=\(dqmacos\- big\-sur/RecoveryImage.img\(dq
disk_img=\(dqmacos\-big\-sur/disk.qcow2\(dq disk_img=\(dqmacos\- big\-sur/disk.qcow2\(dq
macos_release=\(dqbig\-sur\(dq macos_release=\(dq big\-sur\(dq
.EE .EE
.IP \(bu 2 .IP \(bu 2
\f[CR]guest_os=\(dqmacos\(dq\f[R] instructs Quickemu to optimise for \f[CR]guest_os=\(dqmacos\(dq\f[R] instructs Quickemu to optimise for
macOS. macOS.
.IP \(bu 2 .IP \(bu 2
\f[CR]macos_release=\(dqbig\-sur\(dq\f[R] instructs Quickemu to optimise \f[CR]macos_release=\(dq big\-sur\(dq\f[R] instructs Quickemu to
for a particular macOS release. optimise for a particular macOS release.
.RS 2 .RS 2
.IP \(bu 2 .IP \(bu 2
For example VirtIO Network and Memory Ballooning are available in Big For example VirtIO Network and Memory Ballooning are available in Big
@ -1157,13 +1144,11 @@ Usage
Arguments Arguments
\-\-access : Enable remote spice access support. \(aqlocal\(aq (default), \(aqremote\(aq, \(aqclientipaddress\(aq \-\-access : Enable remote spice access support. \(aqlocal\(aq (default), \(aqremote\(aq, \(aqclientipaddress\(aq
\-\-braille : Enable braille support. Requires SDL. \-\-braille : Enable braille support. Requires SDL.
\-\-cpu\-pinning : Choose which host cores correspond to which guest cores.
\-\-delete\-disk : Delete the disk image and EFI variables \-\-delete\-disk : Delete the disk image and EFI variables
\-\-delete\-vm : Delete the entire VM and its configuration \-\-delete\-vm : Delete the entire VM and its configuration
\-\-display : Select display backend. \(aqgtk\(aq (default), \(aqsdl\(aq, \(aqcocoa\(aq, \(aqnone\(aq, \(aqspice\(aq or \(aqspice\-app\(aq \-\-display : Select display backend. \(aqsdl\(aq (default), \(aqcocoa\(aq, \(aqgtk\(aq, \(aqnone\(aq, \(aqspice\(aq or \(aqspice\-app\(aq
\-\-fullscreen : Starts VM in full screen mode (Ctl+Alt+f to exit) \-\-fullscreen : Starts VM in full screen mode (Ctl+Alt+f to exit)
\-\-ignore\-msrs\-always : Configure KVM to always ignore unhandled machine\-specific registers \-\-ignore\-msrs\-always : Configure KVM to always ignore unhandled machine\-specific registers
\-\-ignore\-tsc\-warning : Skip TSC stability warning for macOS VMs on AMD
\-\-kill : Kill the VM process if it is running \-\-kill : Kill the VM process if it is running
\-\-offline : Override all network settings and start the VM offline \-\-offline : Override all network settings and start the VM offline
\-\-shortcut : Create a desktop shortcut \-\-shortcut : Create a desktop shortcut
@ -1189,7 +1174,7 @@ Arguments
\-\-keyboard_layout <layout> : Set keyboard layout: \(aqen\-us\(aq (default) \-\-keyboard_layout <layout> : Set keyboard layout: \(aqen\-us\(aq (default)
\-\-mouse <type> : Set mouse. \(atOptions: \(aqtablet\(aq (default), \(aqps2\(aq, \(aqusb\(aq, \(aqvirtio\(aq \-\-mouse <type> : Set mouse. \(atOptions: \(aqtablet\(aq (default), \(aqps2\(aq, \(aqusb\(aq, \(aqvirtio\(aq
\-\-usb\-controller <type> : Set usb\-controller. \(atOptions: \(aqehci\(aq (default), \(aqxhci\(aq, \(aqnone\(aq \-\-usb\-controller <type> : Set usb\-controller. \(atOptions: \(aqehci\(aq (default), \(aqxhci\(aq, \(aqnone\(aq
\-\-sound\-card <type> : Set sound card. \(atOptions: \(aqintel\-hda\(aq (default), \(aqac97\(aq, \(aqes1370\(aq, \(aqsb16\(aq, \(aqusb\-audio\(aq, \(aqvirtio\-sound\-pci\(aq, \(aqnone\(aq \-\-sound\-card <type> : Set sound card. \(atOptions: \(aqintel\-hda\(aq (default), \(aqac97\(aq, \(aqes1370\(aq, \(aqsb16\(aq, \(aqusb\-audio\(aq, \(aqnone\(aq
\-\-sound\-duplex <type> : Set sound card duplex. \(atOptions: \(aqhda\-micro\(aq (default: speaker/mic), \(aqhda\-duplex\(aq (line\-in/line\-out), \(aqhda\-output\(aq (output\-only) \-\-sound\-duplex <type> : Set sound card duplex. \(atOptions: \(aqhda\-micro\(aq (default: speaker/mic), \(aqhda\-duplex\(aq (line\-in/line\-out), \(aqhda\-output\(aq (output\-only)
\-\-extra_args <arguments> : Pass additional arguments to qemu \-\-extra_args <arguments> : Pass additional arguments to qemu
\-\-version : Print version \-\-version : Print version

View File

@ -1,6 +1,6 @@
--- ---
author: Martin Wimpress author: Martin Wimpress
date: February 2, 2026 date: July 31, 2025
footer: quickemu footer: quickemu
header: Quickemu User Manual header: Quickemu User Manual
section: 1 section: 1
@ -41,8 +41,8 @@ You can also pass optional parameters
: Delete the entire VM and its configuration : Delete the entire VM and its configuration
**--display** **--display**
: Select display backend. 'gtk' (default), 'sdl', 'cocoa', 'none', : Select display backend. 'sdl' (default), 'gtk', 'none', 'spice' or
'spice' or 'spice-app' 'spice-app'
**--fullscreen** **--fullscreen**
: Starts VM in full screen mode (Ctl+Alt+f to exit) : Starts VM in full screen mode (Ctl+Alt+f to exit)
@ -177,8 +177,6 @@ Haiku, KolibriOS, OpenIndiana, ReactOS, and more.
Mojave Mojave
- **Windows** 10 and 11 including TPM 2.0 - **Windows** 10 and 11 including TPM 2.0
- **Windows Server** 2022 2019 2016 - **Windows Server** 2022 2019 2016
- **ARM64 guest support** for running aarch64 VMs (native on ARM hosts,
emulated on x86_64)
- [Ubuntu](https://ubuntu.com/desktop) and all the **[official Ubuntu - [Ubuntu](https://ubuntu.com/desktop) and all the **[official Ubuntu
flavours](https://ubuntu.com/download/flavours)** flavours](https://ubuntu.com/download/flavours)**
- **Nearly 1000 operating system editions are supported!** - **Nearly 1000 operating system editions are supported!**
@ -399,23 +397,18 @@ may have further information.
You can also use `quickget` with advanced options : You can also use `quickget` with advanced options :
``` text ``` text
--arch <arch> : Set architecture (arm64, aarch64, amd64, x86_64) --download <os> <release> [edition] : Download image; no VM configuration
--download <os> <release> [edition] : Download image; no VM configuration --create-config <os> [path/url] [flags] : Create VM config for an OS image
--create-config <os> [path/url] [flags] : Create VM config for an OS image --open-homepage <os> : Open homepage for the OS
--open-homepage <os> : Open homepage for the OS --show [os] : Show OS information
--show [os] : Show OS information --version : Show version
--version : Show version --help : Show this help message
--help : Show this help message --disable-unattended : Force quickget not to set up an unattended installation
------------------------------------ Flags ------------------------------------- --url [os] [release] [edition] : Show image URL(s)
--create-config: --check [os] [release] [edition] : Check image URL(s)
--disable-unattended : Force quickget not to set up an unattended installation --list : List all supported systems
-------------------------- For testing & development --------------------------- --list-csv : List everything in csv format
--url [os] [release] [edition] : Show image URL(s) --list-json : List everything in json format
--check [os] [release] [edition] : Check image URL(s)
--check-all-arch [os] [release] [edition] : Check downloads for all architectures (amd64 and arm64)
--list : List all supported systems
--list-csv : List everything in csv format
--list-json : List everything in json format
``` ```
Here are some typical uses Here are some typical uses
@ -448,7 +441,7 @@ Further information is available from the project
- `archcraft` (Archcraft) - `archcraft` (Archcraft)
- `archlinux` (Arch Linux) - `archlinux` (Arch Linux)
- `artixlinux` (Artix Linux) - `artixlinux` (Artix Linux)
- `azurelinux` (Azure Linux) - `athenaos` (Athena OS)
- `batocera` (Batocera) - `batocera` (Batocera)
- `bazzite` (Bazzite) - `bazzite` (Bazzite)
- `biglinux` (BigLinux) - `biglinux` (BigLinux)
@ -476,6 +469,7 @@ Further information is available from the project
- `gnomeos` (GNOME OS) - `gnomeos` (GNOME OS)
- `guix` (Guix) - `guix` (Guix)
- `haiku` (Haiku) - `haiku` (Haiku)
- `holoiso` (HoloISO)
- `kali` (Kali) - `kali` (Kali)
- `kdeneon` (KDE Neon) - `kdeneon` (KDE Neon)
- `kolibrios` (KolibriOS) - `kolibrios` (KolibriOS)
@ -512,14 +506,16 @@ Further information is available from the project
- `slint` (Slint) - `slint` (Slint)
- `slitaz` (SliTaz) - `slitaz` (SliTaz)
- `solus` (Solus) - `solus` (Solus)
- `sparkylinux` (SparkyLinux)
- `spirallinux` (SpiralLinux) - `spirallinux` (SpiralLinux)
- `tails` (Tails) - `tails` (Tails)
- `tinycore` (Tiny Core Linux) - `tinycore` (Tiny Core Linux)
- `trisquel` (Trisquel) - `trisquel` (Trisquel-)
- `truenas-core` (TrueNAS Core)
- `truenas-scale` (TrueNAS Scale)
- `tuxedo-os` (Tuxedo OS) - `tuxedo-os` (Tuxedo OS)
- `vanillaos` (Vanilla OS) - `vanillaos` (Vanilla OS)
- `void` (Void Linux) - `void` (Void Linux)
- `vxlinux` (VX Linux)
- `zorin` (Zorin OS) - `zorin` (Zorin OS)
### [Custom Linux guests](https://github.com/quickemu-project/quickemu/wiki/02-Create-Linux-virtual-machines#manually-create-linux-guests) ### [Custom Linux guests](https://github.com/quickemu-project/quickemu/wiki/02-Create-Linux-virtual-machines#manually-create-linux-guests)
@ -565,13 +561,6 @@ for solutions or ask for help there** 🛟
`quickget` automatically downloads a macOS recovery image and creates a `quickget` automatically downloads a macOS recovery image and creates a
virtual machine configuration. virtual machine configuration.
Note: Some VPN users may need to [turn off their
VPN](https://github.com/quickemu-project/quickemu/issues/1391#issuecomment-3506845235)
in order to download a recovery image. Some other users may find [using
a
VPN](https://github.com/quickemu-project/quickemu/issues/1391#issuecomment-2429146013)
necessary in order to download a recovery image.
``` shell ``` shell
quickget macos big-sur quickget macos big-sur
quickemu --vm macos-big-sur.conf quickemu --vm macos-big-sur.conf
@ -646,13 +635,13 @@ The default macOS configuration looks like this:
``` shell ``` shell
guest_os="macos" guest_os="macos"
img="macos-big-sur/RecoveryImage.img" img="macos- big-sur/RecoveryImage.img"
disk_img="macos-big-sur/disk.qcow2" disk_img="macos- big-sur/disk.qcow2"
macos_release="big-sur" macos_release=" big-sur"
``` ```
- `guest_os="macos"` instructs Quickemu to optimise for macOS. - `guest_os="macos"` instructs Quickemu to optimise for macOS.
- `macos_release="big-sur"` instructs Quickemu to optimise for a - `macos_release=" big-sur"` instructs Quickemu to optimise for a
particular macOS release. particular macOS release.
- For example VirtIO Network and Memory Ballooning are available in - For example VirtIO Network and Memory Ballooning are available in
Big Sur and newer, but not previous releases. Big Sur and newer, but not previous releases.
@ -769,13 +758,11 @@ Usage
Arguments Arguments
--access : Enable remote spice access support. 'local' (default), 'remote', 'clientipaddress' --access : Enable remote spice access support. 'local' (default), 'remote', 'clientipaddress'
--braille : Enable braille support. Requires SDL. --braille : Enable braille support. Requires SDL.
--cpu-pinning : Choose which host cores correspond to which guest cores.
--delete-disk : Delete the disk image and EFI variables --delete-disk : Delete the disk image and EFI variables
--delete-vm : Delete the entire VM and its configuration --delete-vm : Delete the entire VM and its configuration
--display : Select display backend. 'gtk' (default), 'sdl', 'cocoa', 'none', 'spice' or 'spice-app' --display : Select display backend. 'sdl' (default), 'cocoa', 'gtk', 'none', 'spice' or 'spice-app'
--fullscreen : Starts VM in full screen mode (Ctl+Alt+f to exit) --fullscreen : Starts VM in full screen mode (Ctl+Alt+f to exit)
--ignore-msrs-always : Configure KVM to always ignore unhandled machine-specific registers --ignore-msrs-always : Configure KVM to always ignore unhandled machine-specific registers
--ignore-tsc-warning : Skip TSC stability warning for macOS VMs on AMD
--kill : Kill the VM process if it is running --kill : Kill the VM process if it is running
--offline : Override all network settings and start the VM offline --offline : Override all network settings and start the VM offline
--shortcut : Create a desktop shortcut --shortcut : Create a desktop shortcut
@ -801,7 +788,7 @@ Arguments
--keyboard_layout <layout> : Set keyboard layout: 'en-us' (default) --keyboard_layout <layout> : Set keyboard layout: 'en-us' (default)
--mouse <type> : Set mouse. @Options: 'tablet' (default), 'ps2', 'usb', 'virtio' --mouse <type> : Set mouse. @Options: 'tablet' (default), 'ps2', 'usb', 'virtio'
--usb-controller <type> : Set usb-controller. @Options: 'ehci' (default), 'xhci', 'none' --usb-controller <type> : Set usb-controller. @Options: 'ehci' (default), 'xhci', 'none'
--sound-card <type> : Set sound card. @Options: 'intel-hda' (default), 'ac97', 'es1370', 'sb16', 'usb-audio', 'virtio-sound-pci', 'none' --sound-card <type> : Set sound card. @Options: 'intel-hda' (default), 'ac97', 'es1370', 'sb16', 'usb-audio', 'none'
--sound-duplex <type> : Set sound card duplex. @Options: 'hda-micro' (default: speaker/mic), 'hda-duplex' (line-in/line-out), 'hda-output' (output-only) --sound-duplex <type> : Set sound card duplex. @Options: 'hda-micro' (default: speaker/mic), 'hda-duplex' (line-in/line-out), 'hda-output' (output-only)
--extra_args <arguments> : Pass additional arguments to qemu --extra_args <arguments> : Pass additional arguments to qemu
--version : Print version --version : Print version

View File

@ -1,6 +1,6 @@
.\" Automatically generated by Pandoc 3.8.3 .\" Automatically generated by Pandoc 3.7.0.2
.\" .\"
.TH "QUICKEMU_CONF" "5" "February 2, 2026" "quickemu_conf" "Quickemu Configuration Manual" .TH "QUICKEMU_CONF" "5" "July 31, 2025" "quickemu_conf" "Quickemu Configuration Manual"
.SH NAME .SH NAME
quickemu_conf \- Options and parameters in the quickemu <vm>.conf quickemu_conf \- Options and parameters in the quickemu <vm>.conf
.SH DESCRIPTION .SH DESCRIPTION

View File

@ -1,6 +1,6 @@
--- ---
author: Martin Wimpress author: Martin Wimpress
date: February 2, 2026 date: July 31, 2025
footer: quickemu_conf footer: quickemu_conf
header: Quickemu Configuration Manual header: Quickemu Configuration Manual
section: 5 section: 5

View File

@ -1,6 +1,6 @@
.\" Automatically generated by Pandoc 3.8.3 .\" Automatically generated by Pandoc 3.7.0.2
.\" .\"
.TH "QUICKGET" "1" "February 2, 2026" "quickget" "Quickget User Manual" .TH "QUICKGET" "1" "July 31, 2025" "quickget" "Quickget User Manual"
.SH NAME .SH NAME
quickget \- download and prepare materials for building a quickemu VM quickget \- download and prepare materials for building a quickemu VM
.SH SYNOPSIS .SH SYNOPSIS
@ -128,23 +128,18 @@ wiki
You can also use \f[CR]quickget\f[R] with advanced options : You can also use \f[CR]quickget\f[R] with advanced options :
.IP .IP
.EX .EX
\-\-arch <arch> : Set architecture (arm64, aarch64, amd64, x86_64) \-\-download <os> <release> [edition] : Download image; no VM configuration
\-\-download <os> <release> [edition] : Download image; no VM configuration \-\-create\-config <os> [path/url] [flags] : Create VM config for an OS image
\-\-create\-config <os> [path/url] [flags] : Create VM config for an OS image \-\-open\-homepage <os> : Open homepage for the OS
\-\-open\-homepage <os> : Open homepage for the OS \-\-show [os] : Show OS information
\-\-show [os] : Show OS information \-\-version : Show version
\-\-version : Show version \-\-help : Show this help message
\-\-help : Show this help message \-\-disable\-unattended : Force quickget not to set up an unattended installation
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- Flags \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-url [os] [release] [edition] : Show image URL(s)
\-\-create\-config: \-\-check [os] [release] [edition] : Check image URL(s)
\-\-disable\-unattended : Force quickget not to set up an unattended installation \-\-list : List all supported systems
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- For testing & development \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-list\-csv : List everything in csv format
\-\-url [os] [release] [edition] : Show image URL(s) \-\-list\-json : List everything in json format
\-\-check [os] [release] [edition] : Check image URL(s)
\-\-check\-all\-arch [os] [release] [edition] : Check downloads for all architectures (amd64 and arm64)
\-\-list : List all supported systems
\-\-list\-csv : List everything in csv format
\-\-list\-json : List everything in json format
.EE .EE
.PP .PP
Here are some typical uses Here are some typical uses
@ -185,7 +180,7 @@ wiki
.IP \(bu 2 .IP \(bu 2
\f[CR]artixlinux\f[R] (Artix Linux) \f[CR]artixlinux\f[R] (Artix Linux)
.IP \(bu 2 .IP \(bu 2
\f[CR]azurelinux\f[R] (Azure Linux) \f[CR]athenaos\f[R] (Athena OS)
.IP \(bu 2 .IP \(bu 2
\f[CR]batocera\f[R] (Batocera) \f[CR]batocera\f[R] (Batocera)
.IP \(bu 2 .IP \(bu 2
@ -241,6 +236,8 @@ wiki
.IP \(bu 2 .IP \(bu 2
\f[CR]haiku\f[R] (Haiku) \f[CR]haiku\f[R] (Haiku)
.IP \(bu 2 .IP \(bu 2
\f[CR]holoiso\f[R] (HoloISO)
.IP \(bu 2
\f[CR]kali\f[R] (Kali) \f[CR]kali\f[R] (Kali)
.IP \(bu 2 .IP \(bu 2
\f[CR]kdeneon\f[R] (KDE Neon) \f[CR]kdeneon\f[R] (KDE Neon)
@ -313,15 +310,17 @@ wiki
.IP \(bu 2 .IP \(bu 2
\f[CR]solus\f[R] (Solus) \f[CR]solus\f[R] (Solus)
.IP \(bu 2 .IP \(bu 2
\f[CR]sparkylinux\f[R] (SparkyLinux)
.IP \(bu 2
\f[CR]spirallinux\f[R] (SpiralLinux) \f[CR]spirallinux\f[R] (SpiralLinux)
.IP \(bu 2 .IP \(bu 2
\f[CR]tails\f[R] (Tails) \f[CR]tails\f[R] (Tails)
.IP \(bu 2 .IP \(bu 2
\f[CR]tinycore\f[R] (Tiny Core Linux) \f[CR]tinycore\f[R] (Tiny Core Linux)
.IP \(bu 2 .IP \(bu 2
\f[CR]trisquel\f[R] (Trisquel) \f[CR]trisquel\f[R] (Trisquel\-)
.IP \(bu 2
\f[CR]truenas\-core\f[R] (TrueNAS Core)
.IP \(bu 2
\f[CR]truenas\-scale\f[R] (TrueNAS Scale)
.IP \(bu 2 .IP \(bu 2
\f[CR]tuxedo\-os\f[R] (Tuxedo OS) \f[CR]tuxedo\-os\f[R] (Tuxedo OS)
.IP \(bu 2 .IP \(bu 2
@ -329,6 +328,8 @@ wiki
.IP \(bu 2 .IP \(bu 2
\f[CR]void\f[R] (Void Linux) \f[CR]void\f[R] (Void Linux)
.IP \(bu 2 .IP \(bu 2
\f[CR]vxlinux\f[R] (VX Linux)
.IP \(bu 2
\f[CR]zorin\f[R] (Zorin OS) \f[CR]zorin\f[R] (Zorin OS)
.SS \c .SS \c
.UR https://github.com/quickemu-project/quickemu/wiki/02-Create-Linux-virtual-machines#manually-create-linux-guests .UR https://github.com/quickemu-project/quickemu/wiki/02-Create-Linux-virtual-machines#manually-create-linux-guests
@ -384,17 +385,6 @@ check the Discussions
.PP .PP
\f[CR]quickget\f[R] automatically downloads a macOS recovery image and \f[CR]quickget\f[R] automatically downloads a macOS recovery image and
creates a virtual machine configuration. creates a virtual machine configuration.
.PP
Note: Some VPN users may need to \c
.UR https://github.com/quickemu-project/quickemu/issues/1391#issuecomment-3506845235
turn off their VPN
.UE \c
\ in order to download a recovery image.
Some other users may find \c
.UR https://github.com/quickemu-project/quickemu/issues/1391#issuecomment-2429146013
using a VPN
.UE \c
\ necessary in order to download a recovery image.
.IP .IP
.EX .EX
quickget macos big\-sur quickget macos big\-sur
@ -507,8 +497,8 @@ macos_release=\(dqbig\-sur\(dq
\f[CR]guest_os=\(dqmacos\(dq\f[R] instructs Quickemu to optimise for \f[CR]guest_os=\(dqmacos\(dq\f[R] instructs Quickemu to optimise for
macOS. macOS.
.IP \(bu 2 .IP \(bu 2
\f[CR]macos_release=\(dqbig\-sur\(dq\f[R] instructs Quickemu to optimise \f[CR]macos_release=\(dq big\-sur\(dq\f[R] instructs Quickemu to
for a particular macOS release. optimise for a particular macOS release.
.RS 2 .RS 2
.IP \(bu 2 .IP \(bu 2
For example VirtIO Network and Memory Ballooning are available in Big For example VirtIO Network and Memory Ballooning are available in Big

View File

@ -1,6 +1,6 @@
--- ---
author: Martin Wimpress author: Martin Wimpress
date: February 2, 2026 date: July 31, 2025
footer: quickget footer: quickget
header: Quickget User Manual header: Quickget User Manual
section: 1 section: 1
@ -123,23 +123,18 @@ may have further information.
You can also use `quickget` with advanced options : You can also use `quickget` with advanced options :
``` text ``` text
--arch <arch> : Set architecture (arm64, aarch64, amd64, x86_64) --download <os> <release> [edition] : Download image; no VM configuration
--download <os> <release> [edition] : Download image; no VM configuration --create-config <os> [path/url] [flags] : Create VM config for an OS image
--create-config <os> [path/url] [flags] : Create VM config for an OS image --open-homepage <os> : Open homepage for the OS
--open-homepage <os> : Open homepage for the OS --show [os] : Show OS information
--show [os] : Show OS information --version : Show version
--version : Show version --help : Show this help message
--help : Show this help message --disable-unattended : Force quickget not to set up an unattended installation
------------------------------------ Flags ------------------------------------- --url [os] [release] [edition] : Show image URL(s)
--create-config: --check [os] [release] [edition] : Check image URL(s)
--disable-unattended : Force quickget not to set up an unattended installation --list : List all supported systems
-------------------------- For testing & development --------------------------- --list-csv : List everything in csv format
--url [os] [release] [edition] : Show image URL(s) --list-json : List everything in json format
--check [os] [release] [edition] : Check image URL(s)
--check-all-arch [os] [release] [edition] : Check downloads for all architectures (amd64 and arm64)
--list : List all supported systems
--list-csv : List everything in csv format
--list-json : List everything in json format
``` ```
Here are some typical uses Here are some typical uses
@ -172,7 +167,7 @@ Further information is available from the project
- `archcraft` (Archcraft) - `archcraft` (Archcraft)
- `archlinux` (Arch Linux) - `archlinux` (Arch Linux)
- `artixlinux` (Artix Linux) - `artixlinux` (Artix Linux)
- `azurelinux` (Azure Linux) - `athenaos` (Athena OS)
- `batocera` (Batocera) - `batocera` (Batocera)
- `bazzite` (Bazzite) - `bazzite` (Bazzite)
- `biglinux` (BigLinux) - `biglinux` (BigLinux)
@ -200,6 +195,7 @@ Further information is available from the project
- `gnomeos` (GNOME OS) - `gnomeos` (GNOME OS)
- `guix` (Guix) - `guix` (Guix)
- `haiku` (Haiku) - `haiku` (Haiku)
- `holoiso` (HoloISO)
- `kali` (Kali) - `kali` (Kali)
- `kdeneon` (KDE Neon) - `kdeneon` (KDE Neon)
- `kolibrios` (KolibriOS) - `kolibrios` (KolibriOS)
@ -236,14 +232,16 @@ Further information is available from the project
- `slint` (Slint) - `slint` (Slint)
- `slitaz` (SliTaz) - `slitaz` (SliTaz)
- `solus` (Solus) - `solus` (Solus)
- `sparkylinux` (SparkyLinux)
- `spirallinux` (SpiralLinux) - `spirallinux` (SpiralLinux)
- `tails` (Tails) - `tails` (Tails)
- `tinycore` (Tiny Core Linux) - `tinycore` (Tiny Core Linux)
- `trisquel` (Trisquel) - `trisquel` (Trisquel-)
- `truenas-core` (TrueNAS Core)
- `truenas-scale` (TrueNAS Scale)
- `tuxedo-os` (Tuxedo OS) - `tuxedo-os` (Tuxedo OS)
- `vanillaos` (Vanilla OS) - `vanillaos` (Vanilla OS)
- `void` (Void Linux) - `void` (Void Linux)
- `vxlinux` (VX Linux)
- `zorin` (Zorin OS) - `zorin` (Zorin OS)
### [Custom Linux guests](https://github.com/quickemu-project/quickemu/wiki/02-Create-Linux-virtual-machines#manually-create-linux-guests) ### [Custom Linux guests](https://github.com/quickemu-project/quickemu/wiki/02-Create-Linux-virtual-machines#manually-create-linux-guests)
@ -289,13 +287,6 @@ for solutions or ask for help there** 🛟
`quickget` automatically downloads a macOS recovery image and creates a `quickget` automatically downloads a macOS recovery image and creates a
virtual machine configuration. virtual machine configuration.
Note: Some VPN users may need to [turn off their
VPN](https://github.com/quickemu-project/quickemu/issues/1391#issuecomment-3506845235)
in order to download a recovery image. Some other users may find [using
a
VPN](https://github.com/quickemu-project/quickemu/issues/1391#issuecomment-2429146013)
necessary in order to download a recovery image.
``` shell ``` shell
quickget macos big-sur quickget macos big-sur
quickemu --vm macos-big-sur.conf quickemu --vm macos-big-sur.conf
@ -370,13 +361,13 @@ The default macOS configuration looks like this:
``` shell ``` shell
guest_os="macos" guest_os="macos"
img="macos-big-sur/RecoveryImage.img" img="macos- big-sur/RecoveryImage.img"
disk_img="macos-big-sur/disk.qcow2" disk_img="macos- big-sur/disk.qcow2"
macos_release="big-sur" macos_release=" big-sur"
``` ```
- `guest_os="macos"` instructs Quickemu to optimise for macOS. - `guest_os="macos"` instructs Quickemu to optimise for macOS.
- `macos_release="big-sur"` instructs Quickemu to optimise for a - `macos_release=" big-sur"` instructs Quickemu to optimise for a
particular macOS release. particular macOS release.
- For example VirtIO Network and Memory Ballooning are available in - For example VirtIO Network and Memory Ballooning are available in
Big Sur and newer, but not previous releases. Big Sur and newer, but not previous releases.

View File

@ -2,12 +2,12 @@
"nodes": { "nodes": {
"flake-schemas": { "flake-schemas": {
"locked": { "locked": {
"lastModified": 1775244557, "lastModified": 1761577921,
"narHash": "sha256-iYXRXIX9eafJmwJFAhqT3YxvvpNRuPFSLRCSpvGh8Ic=", "narHash": "sha256-eK3/xbUOrxp9fFlei09XNjqcdiHXxndzrTXp7jFpOk8=",
"rev": "15edbeeaf77e42216dbcba8bfd907fdeabb75a2b", "rev": "47849c7625e223d36766968cc6dc23ba0e135922",
"revCount": 132, "revCount": 107,
"type": "tarball", "type": "tarball",
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/flake-schemas/0.4.2/019d5cf2-ee3c-7313-964e-f3f83c35d509/source.tar.gz" "url": "https://api.flakehub.com/f/pinned/DeterminateSystems/flake-schemas/0.2.0/019a4a84-544d-7c59-b26d-e334e320c932/source.tar.gz"
}, },
"original": { "original": {
"type": "tarball", "type": "tarball",
@ -16,18 +16,16 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1776877367, "lastModified": 1768940263,
"narHash": "sha256-EHq1/OX139R1RvBzOJ0aMRT3xnWyqtHBRUBuO1gFzjI=", "narHash": "sha256-sJERJIYTKPFXkoz/gBaBtRKke82h4DkX3BBSsKbfbvI=",
"owner": "nixos", "rev": "3ceaaa8bc963ced4d830e06ea2d0863b6490ff03",
"repo": "nixpkgs", "revCount": 906247,
"rev": "0726a0ecb6d4e08f6adced58726b95db924cef57", "type": "tarball",
"type": "github" "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.2511.906247%2Brev-3ceaaa8bc963ced4d830e06ea2d0863b6490ff03/019be1ae-9947-752c-81ca-8b8670ae9892/source.tar.gz"
}, },
"original": { "original": {
"owner": "nixos", "type": "tarball",
"ref": "nixos-unstable", "url": "https://flakehub.com/f/NixOS/nixpkgs/%2A.tar.gz"
"repo": "nixpkgs",
"type": "github"
} }
}, },
"root": { "root": {

View File

@ -2,7 +2,7 @@
description = "Quickemu flake"; description = "Quickemu flake";
inputs = { inputs = {
flake-schemas.url = "https://flakehub.com/f/DeterminateSystems/flake-schemas/*.tar.gz"; flake-schemas.url = "https://flakehub.com/f/DeterminateSystems/flake-schemas/*.tar.gz";
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/*.tar.gz";
}; };
outputs = outputs =
@ -41,7 +41,7 @@
let let
# OVMF is only available/needed on Linux # OVMF is only available/needed on Linux
ovmfArgs = ovmfArgs =
if final.stdenv.hostPlatform.isLinux then if final.stdenv.isLinux then
{ } { }
else else
{ {
@ -60,7 +60,7 @@
let let
# OVMF is only available/needed on Linux # OVMF is only available/needed on Linux
ovmfArgs = ovmfArgs =
if pkgs.stdenv.hostPlatform.isLinux then if pkgs.stdenv.isLinux then
{ } { }
else else
{ {
@ -80,7 +80,7 @@
let let
# OVMF is only available/needed on Linux # OVMF is only available/needed on Linux
ovmfArgs = ovmfArgs =
if pkgs.stdenv.hostPlatform.isLinux then if pkgs.stdenv.isLinux then
{ } { }
else else
{ {

View File

@ -28,6 +28,7 @@
zsync, zsync,
OVMF ? null, OVMF ? null,
OVMFFull ? null, OVMFFull ? null,
quickemu,
}: }:
let let
runtimePaths = [ runtimePaths = [
@ -49,35 +50,33 @@ let
xrandr xrandr
zsync zsync
] ]
++ lib.optionals stdenv.hostPlatform.isLinux [ ++ lib.optionals stdenv.isLinux [
mesa-demos mesa-demos
OVMF OVMF
OVMFFull OVMFFull
usbutils usbutils
xdg-user-dirs xdg-user-dirs
]; ];
# Extract version using builtins.split to avoid regex backtracking on large files. versionMatches = builtins.match ''
# builtins.match with .* patterns on multi-kilobyte files can cause stack overflow. .*
versionParts = builtins.split "readonly VERSION=\"([0-9]+\\.[0-9]+\\.[0-9]+)\"" ( readonly[[:blank:]]VERSION="([[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+)"
builtins.readFile ./quickemu .*
); '' (builtins.readFile ./quickemu);
version = builtins.elemAt (builtins.elemAt versionParts 1) 0;
in in
stdenv.mkDerivation (finalAttrs: { stdenv.mkDerivation rec {
pname = "quickemu"; pname = "quickemu";
version = version; version = builtins.concatStringsSep "" versionMatches;
src = lib.cleanSource ./.; src = lib.cleanSource ./.;
postPatch = '' postPatch = ''
sed -i \ sed -i \
${ ${
lib.optionalString (OVMF != null && OVMFFull != null) '' lib.optionalString (OVMF != null && OVMFFull != null) ''
-e '/OVMF_CODE_4M.secboot.fd/s|ovmfs=(|ovmfs=("${OVMFFull.firmware}","${OVMFFull.variablesMs}" |' \ -e '/OVMF_CODE_4M.secboot.fd/s|ovmfs=(|ovmfs=("${OVMFFull.firmware}","${OVMFFull.variables}" |' \
-e '/OVMF_CODE_4M.fd/s|ovmfs=(|ovmfs=("${OVMF.firmware}","${OVMF.variables}" |' \ -e '/OVMF_CODE_4M.fd/s|ovmfs=(|ovmfs=("${OVMF.firmware}","${OVMF.variables}" |' \
'' ''
} \ } \
-e '/cp "''${VARS_IN}" "''${VARS_OUT}"/a chmod +w "''${VARS_OUT}"' \ -e '/cp "''${VARS_IN}" "''${VARS_OUT}"/a chmod +w "''${VARS_OUT}"' \
-e 's/Icon=.*qemu.svg/Icon=qemu/' \
-e 's,\$(command -v smbd),${samba}/bin/smbd,' \ -e 's,\$(command -v smbd),${samba}/bin/smbd,' \
quickemu quickemu
''; '';
@ -104,12 +103,11 @@ stdenv.mkDerivation (finalAttrs: {
runHook postInstall runHook postInstall
''; '';
passthru.tests = testers.testVersion { package = finalAttrs.finalPackage; }; passthru.tests = testers.testVersion { package = quickemu; };
meta = { meta = {
description = "Quickly create and run optimised Windows, macOS and Linux virtual machines"; description = "Quickly create and run optimised Windows, macOS and Linux virtual machines";
homepage = "https://github.com/quickemu-project/quickemu"; homepage = "https://github.com/quickemu-project/quickemu";
changelog = "https://github.com/quickemu-project/quickemu/releases/tag/${finalAttrs.version}";
mainProgram = "quickemu"; mainProgram = "quickemu";
license = lib.licenses.mit; license = lib.licenses.mit;
maintainers = with lib.maintainers; [ maintainers = with lib.maintainers; [
@ -117,4 +115,4 @@ stdenv.mkDerivation (finalAttrs: {
flexiondotorg flexiondotorg
]; ];
}; };
}) }

1076
quickemu

File diff suppressed because it is too large Load Diff

532
quickget
View File

@ -8,20 +8,6 @@ export LC_ALL=C
# Detect host OS for checksum tool compatibility # Detect host OS for checksum tool compatibility
HOST_OS=$(uname -s) HOST_OS=$(uname -s)
# Default architecture based on host
HOST_ARCH=$(uname -m)
case "${HOST_ARCH}" in
aarch64|arm64) ARCH="arm64";;
*) ARCH="amd64";;
esac
function arch_suffix() {
# Return architecture suffix for foreign architectures, empty for native
if [ "${ARCH}" != "${NORMALISED_HOST_ARCH}" ]; then
echo "-${ARCH}"
fi
}
function cleanup() { function cleanup() {
if [ -n "$(jobs -p)" ]; then if [ -n "$(jobs -p)" ]; then
kill "$(jobs -p)" 2>/dev/null kill "$(jobs -p)" 2>/dev/null
@ -41,7 +27,6 @@ function os_info() {
archcraft) INFO="Archcraft|-|https://archcraft.io/|Yet another minimal Linux distribution, based on Arch Linux.";; archcraft) INFO="Archcraft|-|https://archcraft.io/|Yet another minimal Linux distribution, based on Arch Linux.";;
archlinux) INFO="Arch Linux|-|https://archlinux.org/|Lightweight and flexible Linux® distribution that tries to Keep It Simple.";; archlinux) INFO="Arch Linux|-|https://archlinux.org/|Lightweight and flexible Linux® distribution that tries to Keep It Simple.";;
artixlinux) INFO="Artix Linux|-|https://artixlinux.org/|The Art of Linux. Simple. Fast. Systemd-free.";; artixlinux) INFO="Artix Linux|-|https://artixlinux.org/|The Art of Linux. Simple. Fast. Systemd-free.";;
azurelinux) INFO="Azure Linux|-|https://github.com/microsoft/azurelinux|Microsoft's internal Linux distribution for cloud infrastructure and edge.";;
batocera) INFO="Batocera|-|https://batocera.org/|Retro-gaming distribution with the aim of turning any computer/nano computer into a gaming console during a game or permanently.";; batocera) INFO="Batocera|-|https://batocera.org/|Retro-gaming distribution with the aim of turning any computer/nano computer into a gaming console during a game or permanently.";;
bazzite) INFO="Bazzite|-|https://github.com/ublue-os/bazzite/|Container native gaming and a ready-to-game SteamOS like.";; bazzite) INFO="Bazzite|-|https://github.com/ublue-os/bazzite/|Container native gaming and a ready-to-game SteamOS like.";;
biglinux) INFO="BigLinux|-|https://www.biglinux.com.br/|Is the right choice if you want to have an easy and enriching experience with Linux. It has been perfected over more than 19 years, following our motto: 'In search of the perfect system'.";; biglinux) INFO="BigLinux|-|https://www.biglinux.com.br/|Is the right choice if you want to have an easy and enriching experience with Linux. It has been perfected over more than 19 years, following our motto: 'In search of the perfect system'.";;
@ -172,14 +157,10 @@ function error_specify_release() {
*ubuntu-server*) *ubuntu-server*)
echo -en " - Releases:\t" echo -en " - Releases:\t"
releases_ubuntu-server releases_ubuntu-server
echo -en " - Archs:\t"
get_supported_archs "${OS}"
;; ;;
*ubuntu*) *ubuntu*)
echo -en " - Releases:\t" echo -en " - Releases:\t"
releases_ubuntu releases_ubuntu
echo -en " - Archs:\t"
get_supported_archs "${OS}"
;; ;;
*windows*) *windows*)
echo -en " - Releases:\t" echo -en " - Releases:\t"
@ -187,7 +168,6 @@ function error_specify_release() {
echo -en " - Languages:\t" echo -en " - Languages:\t"
"languages_${OS}" "languages_${OS}"
echo "${I18NS[@]}" echo "${I18NS[@]}"
# Windows uses multi-arch ISOs, skip architecture display
;; ;;
*) *)
echo -en " - Releases:\t" echo -en " - Releases:\t"
@ -196,8 +176,6 @@ function error_specify_release() {
echo -en " - Editions:\t" echo -en " - Editions:\t"
"editions_${OS}" | fmt -w 80 "editions_${OS}" | fmt -w 80
fi fi
echo -en " - Archs:\t"
get_supported_archs "${OS}"
;; ;;
esac esac
echo -e "\nERROR! You must specify a release." echo -e "\nERROR! You must specify a release."
@ -366,7 +344,6 @@ function test_result() {
local EDITION="${3:-}" local EDITION="${3:-}"
local URL="${4:-}" local URL="${4:-}"
local RESULT="${5:-}" local RESULT="${5:-}"
local REASON="${6:-}"
if [ -n "${EDITION}" ]; then if [ -n "${EDITION}" ]; then
OS="${OS}-${RELEASE}-${EDITION}" OS="${OS}-${RELEASE}-${EDITION}"
else else
@ -376,11 +353,7 @@ function test_result() {
if [ -n "${RESULT}" ]; then if [ -n "${RESULT}" ]; then
# Pad the OS string for consistent output # Pad the OS string for consistent output
OS=$(printf "%-35s" "${OS}") OS=$(printf "%-35s" "${OS}")
if [ -n "${REASON}" ]; then echo -e "${RESULT}: ${OS} ${URL}"
echo -e "${RESULT}: ${OS} ${REASON}"
else
echo -e "${RESULT}: ${OS} ${URL}"
fi
else else
OS=$(printf "%-36s" "${OS}:") OS=$(printf "%-36s" "${OS}:")
echo -e "${OS} ${URL}" echo -e "${OS} ${URL}"
@ -401,11 +374,6 @@ function test_all() {
for RELEASE in $("releases_${FUNC}"); do for RELEASE in $("releases_${FUNC}"); do
if [[ $(type -t "editions_${OS}") == function ]]; then if [[ $(type -t "editions_${OS}") == function ]]; then
for EDITION in $(editions_"${OS}"); do for EDITION in $(editions_"${OS}"); do
# Check architecture support before generating URL
if ! is_arch_supported "${OS}" "${ARCH}"; then
test_result "${OS}" "${RELEASE}" "${EDITION}" "" "SKIP" "(not available for ${ARCH})"
continue
fi
validate_release releases_"${OS}" validate_release releases_"${OS}"
URL=$(get_"${OS}" | cut -d' ' -f1 | head -n 1) URL=$(get_"${OS}" | cut -d' ' -f1 | head -n 1)
if [ "${OPERATION}" == "show" ]; then if [ "${OPERATION}" == "show" ]; then
@ -429,27 +397,12 @@ function test_all() {
validate_release releases_macos validate_release releases_macos
(get_macos) (get_macos)
elif [ "${OS}" == "ubuntu-server" ]; then elif [ "${OS}" == "ubuntu-server" ]; then
# Check architecture support before generating URL
if ! is_arch_supported "${OS}" "${ARCH}"; then
test_result "${OS}" "${RELEASE}" "" "" "SKIP" "(not available for ${ARCH})"
continue
fi
validate_release releases_ubuntu-server validate_release releases_ubuntu-server
(get_ubuntu-server) (get_ubuntu-server)
elif [[ "${OS}" == *ubuntu* ]]; then elif [[ "${OS}" == *ubuntu* ]]; then
# Ubuntu desktop is amd64 only (no arch function = amd64 default)
if ! is_arch_supported "${OS}" "${ARCH}"; then
test_result "${OS}" "${RELEASE}" "" "" "SKIP" "(not available for ${ARCH})"
continue
fi
validate_release releases_ubuntu validate_release releases_ubuntu
(get_ubuntu) (get_ubuntu)
else else
# Check architecture support before generating URL
if ! is_arch_supported "${OS}" "${ARCH}"; then
test_result "${OS}" "${RELEASE}" "" "" "SKIP" "(not available for ${ARCH})"
continue
fi
validate_release releases_"${OS}" validate_release releases_"${OS}"
URL=$(get_"${OS}" | cut -d' ' -f1 | head -n 1) URL=$(get_"${OS}" | cut -d' ' -f1 | head -n 1)
if [ "${OPERATION}" == "show" ]; then if [ "${OPERATION}" == "show" ]; then
@ -470,7 +423,6 @@ function os_support() {
archcraft \ archcraft \
archlinux \ archlinux \
artixlinux \ artixlinux \
azurelinux \
batocera \ batocera \
bazzite \ bazzite \
biglinux \ biglinux \
@ -614,10 +566,6 @@ function editions_artixlinux() {
echo $(web_pipe "https://mirror1.artixlinux.org/iso/" | grep "artix-" | cut -d'"' -f2 | grep -v sig | sed 's/artix-//' | sed 's/-[0-9]\{8\}-x86_64.iso//' | sort -u) echo $(web_pipe "https://mirror1.artixlinux.org/iso/" | grep "artix-" | cut -d'"' -f2 | grep -v sig | sed 's/artix-//' | sed 's/-[0-9]\{8\}-x86_64.iso//' | sort -u)
} }
function releases_azurelinux() {
echo 3.0
}
function releases_batocera() { function releases_batocera() {
#shellcheck disable=SC2046,SC2005 #shellcheck disable=SC2046,SC2005
echo $(web_pipe "https://mirrors.o2switch.fr/batocera/x86_64/stable/" | grep ^\<a | cut -d'"' -f2 | cut -d '/' -f1 | grep -v '\.' | sort -ru | tail -n +2 | head -n 5) echo $(web_pipe "https://mirrors.o2switch.fr/batocera/x86_64/stable/" | grep ^\<a | cut -d'"' -f2 | cut -d '/' -f1 | grep -v '\.' | sort -ru | tail -n +2 | head -n 5)
@ -734,9 +682,9 @@ function releases_easyos() {
# get the latest 2 years of releases so that when we hit next year we still have the latest 2 years # get the latest 2 years of releases so that when we hit next year we still have the latest 2 years
TWO_YEARS=$(web_pipe https://distro.ibiblio.org/easyos/amd64/releases/kirkstone/ | grep -o -E '[[:digit:]]{4}/' | sort -nr | tr -d / | head -n 2 ) TWO_YEARS=$(web_pipe https://distro.ibiblio.org/easyos/amd64/releases/kirkstone/ | grep -o -E '[[:digit:]]{4}/' | sort -nr | tr -d / | head -n 2 )
for YEAR in ${TWO_YEARS} ; do for YEAR in ${TWO_YEARS} ; do
ALL_RELEASES="${ALL_RELEASES} $(web_pipe "https://distro.ibiblio.org/easyos/amd64/releases/kirkstone/${YEAR}/" | grep -o -E '[[:digit:]]+(\.[[:digit:]])+/' | tr -d / | sort -nr)" ALL_RELEASES="${ALL_RELEASES} $(web_pipe https://distro.ibiblio.org/easyos/amd64/releases/kirkstone/${YEAR}/ | grep -o -E '[[:digit:]]+(\.[[:digit:]])+/' | tr -d / | sort -nr)"
done done
echo "${ALL_RELEASES}" echo ${ALL_RELEASES}
} }
@ -961,7 +909,7 @@ function releases_parrotsec() {
RELEASES="${RELEASES} ${REL}" RELEASES="${RELEASES} ${REL}"
fi fi
done done
echo "${RELEASES}" echo ${RELEASES}
} }
function editions_parrotsec() { function editions_parrotsec() {
@ -1033,7 +981,7 @@ function releases_rebornos() {
function releases_rockylinux() { function releases_rockylinux() {
#shellcheck disable=SC2046,SC2005 #shellcheck disable=SC2046,SC2005
echo $(web_pipe "http://dl.rockylinux.org/vault/rocky/" | grep "class=\"link" | grep -v -e 'full' -e 'RC' -e 'ISO' -e 'Parent' | cut -d'"' -f4 | tr -d / | sort -ru) echo $(web_pipe "http://dl.rockylinux.org/vault/rocky/" | grep "^<a href" | grep -v full | grep -v RC | grep -v ISO | cut -d'"' -f2 | tr -d / | sort -ru)
} }
function editions_rockylinux() { function editions_rockylinux() {
@ -1202,94 +1150,6 @@ function releases_zorin() {
echo 18 17 16 echo 18 17 16
} }
# Architecture support functions
# These declare which architectures each distro supports.
# Distros without an arch_*() function default to "amd64" only.
function arch_alma() {
echo "amd64 arm64"
}
function arch_alpine() {
echo "amd64 arm64"
}
function arch_azurelinux() {
echo "amd64 arm64"
}
function arch_debian() {
case "${EDITION}" in
netinst) echo "amd64 arm64";;
*) echo "amd64";;
esac
}
function arch_fedora() {
case "${EDITION}" in
Onyx) echo "amd64";;
*) echo "amd64 arm64";;
esac
}
function arch_ubuntu-server() {
echo "amd64 arm64"
}
function arch_ubuntu() {
# Ubuntu Desktop ARM64 only available from 25.10 onwards
local MAJOR MINOR
# When RELEASE is unset (initial arch check), return all supported architectures
# Actual validation happens in get_ubuntu() when release is known
if [ -z "${RELEASE}" ]; then
echo "amd64 arm64"
return
fi
# Non-numeric releases (daily-live, etc.) default to amd64 only
if [[ ! "${RELEASE}" =~ ^[0-9]+\.[0-9]+$ ]]; then
echo "amd64"
return
fi
MAJOR="${RELEASE%%.*}"
MINOR="${RELEASE##*.}"
# 25.10 and later support ARM64
if [ "${MAJOR}" -gt 25 ] || { [ "${MAJOR}" -eq 25 ] && [ "${MINOR}" -ge 10 ]; }; then
echo "amd64 arm64"
else
echo "amd64"
fi
}
# Check if a given architecture is supported for an OS
function is_arch_supported() {
local OS="${1}"
local CHECK_ARCH="${2}"
local SUPPORTED=""
# Check if arch function exists for this OS
if [[ $(type -t "arch_${OS}") == function ]]; then
SUPPORTED=$(arch_"${OS}")
else
# Default: amd64 only
SUPPORTED="amd64"
fi
# Check if requested arch is in supported list
[[ " ${SUPPORTED} " == *" ${CHECK_ARCH} "* ]]
}
# Get supported architectures for an OS
function get_supported_archs() {
local OS="${1}"
# Check if arch function exists for this OS
if [[ $(type -t "arch_${OS}") == function ]]; then
arch_"${OS}"
else
# Default: amd64 only
echo "amd64"
fi
}
function editions_zorin() { function editions_zorin() {
# Lite edition not available for Zorin 18 (Pro-only starting from 18) # Lite edition not available for Zorin 18 (Pro-only starting from 18)
# When RELEASE is unset (e.g. csv_data context), return all editions # When RELEASE is unset (e.g. csv_data context), return all editions
@ -1310,87 +1170,28 @@ function check_hash() {
iso="${VM_PATH}/${1}" iso="${VM_PATH}/${1}"
fi fi
hash="${2}" hash="${2}"
# Guess the hash algorithm by the hash length
case ${#hash} in
32) hash_algo=md5sum;;
40) hash_algo=sha1sum;;
64) hash_algo=sha256sum;;
128) hash_algo=sha512sum;;
*) echo "WARNING! Can't guess hash algorithm, not checking ${iso} hash."
return;;
esac
# Check for algorithm prefix (e.g., "sha256:abc123..." or "b2sum:abc123...") # Use GNU coreutils on macOS/Darwin (prefixed with 'g')
if [[ "${hash}" == *":"* ]]; then
local hash_prefix="${hash%%:*}"
hash="${hash#*:}"
# Normalise algorithm prefix to lowercase
hash_prefix="$(echo "${hash_prefix}" | tr '[:upper:]' '[:lower:]')"
case "${hash_prefix}" in
md5) hash_algo=md5sum;;
sha1) hash_algo=sha1sum;;
sha256) hash_algo=sha256sum;;
sha512) hash_algo=sha512sum;;
b2sum|blake2|blake2b) hash_algo=b2sum;;
*) echo "WARNING! Unknown hash algorithm '${hash_prefix}', not checking ${iso} hash."
return;;
esac
else
# Guess the hash algorithm by the hash length
case ${#hash} in
32) hash_algo=md5sum;;
40) hash_algo=sha1sum;;
64) hash_algo=sha256sum;;
128) hash_algo=sha512sum;;
*) echo "WARNING! Can't guess hash algorithm, not checking ${iso} hash."
return;;
esac
fi
# On macOS/Darwin, prefer GNU coreutils (prefixed with 'g') if available,
# otherwise fall back to native 'shasum' command
local hash_cmd="${hash_algo}"
if [ "${HOST_OS}" = "Darwin" ]; then if [ "${HOST_OS}" = "Darwin" ]; then
case ${hash_algo} in case ${hash_algo} in
md5sum) md5sum) hash_algo=gmd5sum;;
if command -v gmd5sum &>/dev/null; then sha1sum) hash_algo=gsha1sum;;
hash_cmd=gmd5sum sha256sum) hash_algo=gsha256sum;;
else sha512sum) hash_algo=gsha512sum;;
# MD5 not directly supported by shasum; use native md5 command
hash_cmd="md5 -r"
fi;;
sha1sum)
if command -v gsha1sum &>/dev/null; then
hash_cmd=gsha1sum
else
hash_cmd="shasum -a 1"
fi;;
sha256sum)
if command -v gsha256sum &>/dev/null; then
hash_cmd=gsha256sum
else
hash_cmd="shasum -a 256"
fi;;
sha512sum)
if command -v gsha512sum &>/dev/null; then
hash_cmd=gsha512sum
else
hash_cmd="shasum -a 512"
fi;;
b2sum)
if command -v gb2sum &>/dev/null; then
hash_cmd=gb2sum
else
echo "WARNING! b2sum not available on macOS without GNU coreutils, not checking ${iso} hash."
return
fi;;
esac esac
fi fi
echo -n "Checking ${iso} with ${hash_cmd}... " echo -n "Checking ${iso} with ${hash_algo}... "
# Handle MD5 on macOS specially (md5 -r outputs "hash filename" format) if ! echo "${hash} ${iso}" | ${hash_algo} --check --status; then
if [ "${hash_cmd}" = "md5 -r" ]; then
local computed_hash
computed_hash=$(md5 -r "${iso}" | cut -d' ' -f1)
if [ "${computed_hash}" != "${hash}" ]; then
echo "ERROR!"
echo "${iso} doesn't match ${hash}. Try running 'quickget' again."
exit 1
else
echo "Good!"
fi
elif ! printf '%s %s\n' "${hash}" "${iso}" | ${hash_cmd} --check --status; then
echo "ERROR!" echo "ERROR!"
echo "${iso} doesn't match ${hash}. Try running 'quickget' again." echo "${iso} doesn't match ${hash}. Try running 'quickget' again."
exit 1 exit 1
@ -1442,11 +1243,6 @@ function web_get() {
test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}"
exit 0 exit 0
elif [ "${OPERATION}" == "test" ]; then elif [ "${OPERATION}" == "test" ]; then
# Check architecture support before testing URL
if ! is_arch_supported "${OS}" "${ARCH}"; then
test_result "${OS}" "${RELEASE}" "${EDITION}" "" "SKIP" "(not available for ${ARCH})"
exit 0
fi
CHECK=$(web_check "${URL}" && echo "PASS" || echo "FAIL") CHECK=$(web_check "${URL}" && echo "PASS" || echo "FAIL")
test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" "${CHECK}" test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" "${CHECK}"
exit 0 exit 0
@ -1462,12 +1258,12 @@ function web_get() {
if [[ ${OS} != windows && ${OS} != macos && ${OS} != windows-server ]]; then if [[ ${OS} != windows && ${OS} != macos && ${OS} != windows-server ]]; then
echo "Downloading $(pretty_name "${OS}") ${RELEASE} ${EDITION}" echo "Downloading $(pretty_name "${OS}") ${RELEASE} ${EDITION}"
echo "- URL: ${URL}" echo "- URL: ${URL}"
echo "- PATH: ${PWD}/${DIR}/${FILE}"
fi fi
if ! curl --disable --progress-bar --location --output "${DIR}/${FILE}" --continue-at - --user-agent "${USER_AGENT}" "${HEADERS[@]}" -- "${URL}"; then if ! curl --disable --progress-bar --location --output "${DIR}/${FILE}" --continue-at - --user-agent "${USER_AGENT}" "${HEADERS[@]}" -- "${URL}"; then
echo "ERROR! Failed to download ${URL} with curl." echo "ERROR! Failed to download ${URL} with curl."
rm -f "${DIR}/${FILE}" rm -f "${DIR}/${FILE}"
exit 1
fi fi
} }
@ -1512,11 +1308,6 @@ function zsync_get() {
test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}"
exit 0 exit 0
elif [ "${OPERATION}" == "test" ]; then elif [ "${OPERATION}" == "test" ]; then
# Check architecture support before testing URL
if ! is_arch_supported "${OS}" "${ARCH}"; then
test_result "${OS}" "${RELEASE}" "${EDITION}" "" "SKIP" "(not available for ${ARCH})"
exit 0
fi
CHECK=$(web_check "${URL}" && echo "PASS" || echo "FAIL") CHECK=$(web_check "${URL}" && echo "PASS" || echo "FAIL")
test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" "${CHECK}" test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" "${CHECK}"
exit 0 exit 0
@ -1627,19 +1418,10 @@ function make_vm_config() {
if [ ! -e "${CONF_FILE}" ]; then if [ ! -e "${CONF_FILE}" ]; then
echo "Making ${CONF_FILE}" echo "Making ${CONF_FILE}"
local ARCH_LINE=""
if [ "${ARCH}" != "${NORMALISED_HOST_ARCH}" ]; then
if [ "${ARCH}" == "arm64" ]; then
ARCH_LINE="arch=\"aarch64\""
else
ARCH_LINE="arch=\"x86_64\""
fi
fi
cat << EOF > "${CONF_FILE}" cat << EOF > "${CONF_FILE}"
#!${QUICKEMU} --vm #!${QUICKEMU} --vm
guest_os="${GUEST}" guest_os="${GUEST}"
${ARCH_LINE:+${ARCH_LINE} disk_img="${VM_PATH}/disk.qcow2"
}disk_img="${VM_PATH}/disk.qcow2"
${IMAGE_TYPE}="${VM_PATH}/${IMAGE_FILE}" ${IMAGE_TYPE}="${VM_PATH}/${IMAGE_FILE}"
EOF EOF
echo " - Setting ${CONF_FILE} executable" echo " - Setting ${CONF_FILE} executable"
@ -1659,7 +1441,7 @@ EOF
echo "disk_size=\"8G\"" >> "${CONF_FILE}";; echo "disk_size=\"8G\"" >> "${CONF_FILE}";;
bazzite) bazzite)
echo "disk_size=\"64G\"" >> "${CONF_FILE}";; echo "disk_size=\"64G\"" >> "${CONF_FILE}";;
dragonflybsd|haiku|openbsd|netbsd|slackware|slax|tinycore) dragonflybsd|haiku|openbsd|netbsd|slackware|slax|tails|tinycore)
echo "boot=\"legacy\"" >> "${CONF_FILE}";; echo "boot=\"legacy\"" >> "${CONF_FILE}";;
deepin) deepin)
echo "disk_size=\"64G\"" >> "${CONF_FILE}" echo "disk_size=\"64G\"" >> "${CONF_FILE}"
@ -1754,10 +1536,8 @@ EOF
function get_alma() { function get_alma() {
local HASH="" local HASH=""
local QEMU_ARCH="x86_64" local ISO="AlmaLinux-${RELEASE}-latest-x86_64-${EDITION}.iso"
[ "${ARCH}" == "arm64" ] && QEMU_ARCH="aarch64" local URL="https://repo.almalinux.org/almalinux/${RELEASE}/isos/x86_64"
local ISO="AlmaLinux-${RELEASE}-latest-${QEMU_ARCH}-${EDITION}.iso"
local URL="https://repo.almalinux.org/almalinux/${RELEASE}/isos/${QEMU_ARCH}"
HASH="$(web_pipe "${URL}/CHECKSUM" | grep "(${ISO}" | cut -d' ' -f4)" HASH="$(web_pipe "${URL}/CHECKSUM" | grep "(${ISO}" | cut -d' ' -f4)"
echo "${URL}/${ISO} ${HASH}" echo "${URL}/${ISO} ${HASH}"
} }
@ -1765,13 +1545,11 @@ function get_alma() {
function get_alpine() { function get_alpine() {
local HASH="" local HASH=""
local ISO="" local ISO=""
local QEMU_ARCH="x86_64" local URL="https://dl-cdn.alpinelinux.org/alpine/${RELEASE}/releases/x86_64"
[ "${ARCH}" == "arm64" ] && QEMU_ARCH="aarch64"
local URL="https://dl-cdn.alpinelinux.org/alpine/${RELEASE}/releases/${QEMU_ARCH}"
local VERSION="" local VERSION=""
VERSION=$(web_pipe "${URL}/latest-releases.yaml" | awk '/"Xen"/{found=0} {if(found) print} /"Virtual"/{found=1}' | grep 'version:' | head -1 | awk '{print $2}') VERSION=$(web_pipe "${URL}/latest-releases.yaml" | awk '/"Xen"/{found=0} {if(found) print} /"Virtual"/{found=1}' | grep 'version:' | awk '{print $2}')
ISO="alpine-virt-${VERSION}-${QEMU_ARCH}.iso" ISO="alpine-virt-${VERSION}-x86_64.iso"
HASH=$(web_pipe "${URL}/latest-releases.yaml" | awk '/"Xen"/{found=0} {if(found) print} /"Virtual"/{found=1}' | grep 'sha256:' | head -1 | awk '{print $2}') HASH=$(web_pipe "${URL}/latest-releases.yaml" | awk '/"Xen"/{found=0} {if(found) print} /"Virtual"/{found=1}' | grep 'sha256:' | awk '{print $2}')
echo "${URL}/${ISO} ${HASH}" echo "${URL}/${ISO} ${HASH}"
} }
@ -1822,14 +1600,9 @@ function get_antix() {
function get_archcraft() { function get_archcraft() {
local HASH="" local HASH=""
local ISO=""
local URL="" local URL=""
local VERSION_FOLDER=""
URL="https://sourceforge.net/projects/archcraft/files/${RELEASE}/download" URL="https://sourceforge.net/projects/archcraft/files/${RELEASE}/download"
URL="$(web_redirect "${URL}" | cut -d? -f1)" URL="$(web_redirect "${URL}" | cut -d? -f1)"
ISO="$(basename "${URL}")"
VERSION_FOLDER="$(dirname "${URL}" | xargs basename)"
HASH=$(web_pipe "https://sourceforge.net/projects/archcraft/files/${VERSION_FOLDER}/${ISO}.sha256sum" | cut -d' ' -f1)
echo "${URL} ${HASH}" echo "${URL} ${HASH}"
} }
@ -1851,15 +1624,6 @@ function get_artixlinux() {
echo "${URL}/${ISO} ${HASH}" echo "${URL}/${ISO} ${HASH}"
} }
function get_azurelinux() {
local QEMU_ARCH="x86_64"
[ "${ARCH}" == "arm64" ] && QEMU_ARCH="aarch64"
local URL="https://aka.ms/azurelinux-${RELEASE}-${QEMU_ARCH}.iso"
local ISO
ISO="$(web_redirect "${URL}")"
echo "${ISO}"
}
function get_batocera() { function get_batocera() {
local HASH="" local HASH=""
local ISO="" local ISO=""
@ -1953,21 +1717,13 @@ function get_crunchbang++() {
} }
function get_debian() { function get_debian() {
local DEBIAN_ARCH="${ARCH}"
local DEBCURRENT="" local DEBCURRENT=""
local HASH="" local HASH=""
local ISO="debian-live-${RELEASE}-${DEBIAN_ARCH}-${EDITION}.iso" local ISO="debian-live-${RELEASE}-amd64-${EDITION}.iso"
local URL="https://cdimage.debian.org/cdimage/archive/${RELEASE}-live/${DEBIAN_ARCH}/iso-hybrid" local URL="https://cdimage.debian.org/cdimage/archive/${RELEASE}-live/amd64/iso-hybrid"
# Debian only provides netinst images for ARM64
if [ "${DEBIAN_ARCH}" == "arm64" ] && [ "${EDITION}" != "netinst" ]; then
echo "ERROR! Debian ${EDITION} is not available for ARM64. Use 'netinst' edition."
exit 1
fi
DEBCURRENT=$(web_pipe "https://cdimage.debian.org/debian-cd/" | grep '\.[0-9]/' | cut -d'>' -f 9 | cut -d'/' -f 1) DEBCURRENT=$(web_pipe "https://cdimage.debian.org/debian-cd/" | grep '\.[0-9]/' | cut -d'>' -f 9 | cut -d'/' -f 1)
case "${RELEASE}" in case "${RELEASE}" in
"${DEBCURRENT}") URL="https://cdimage.debian.org/debian-cd/${RELEASE}-live/${DEBIAN_ARCH}/iso-hybrid";; "${DEBCURRENT}") URL="https://cdimage.debian.org/debian-cd/${RELEASE}-live/amd64/iso-hybrid";;
esac esac
if [ "${EDITION}" == "netinst" ]; then if [ "${EDITION}" == "netinst" ]; then
URL="${URL/-live/}" URL="${URL/-live/}"
@ -2086,15 +1842,11 @@ function get_endless() {
} }
function get_fedora() { function get_fedora() {
local FEDORA_ARCH="x86_64"
local HASH="" local HASH=""
local ISO="" local ISO=""
local JSON="" local JSON=""
local URL="" local URL=""
local VARIANT="" local VARIANT=""
[ "${ARCH}" == "arm64" ] && FEDORA_ARCH="aarch64"
case ${EDITION} in case ${EDITION} in
Server|Kinoite|Onyx|Silverblue|Sericea|Workstation|KDE) VARIANT="${EDITION}";; Server|Kinoite|Onyx|Silverblue|Sericea|Workstation|KDE) VARIANT="${EDITION}";;
*) VARIANT="Spins";; *) VARIANT="Spins";;
@ -2112,10 +1864,12 @@ function get_fedora() {
RELEASE="${RELEASE/_/ }" RELEASE="${RELEASE/_/ }"
fi fi
# shellcheck disable=SC2086 # shellcheck disable=SC2086
# Fedora may promote variants from Spins to Editions, in which case we want to accept either "Spins" or the specific edition name to preserve backwards compatibility # Fedora may promote variants from Spins to Editions, in which case we want to accept either "Spins" or the specific edition name to preserve backwards compatibility
# For example, Fedora 42 KDE is now an edition, while previous releases are spins # For example, Fedora 42 KDE is now an edition, while previous releases are spins
JSON=$(web_pipe "https://getfedora.org/releases.json" | jq '.[] | select((.variant=="'"${VARIANT}"'" or .variant=="'"${EDITION}"'") and .subvariant=="'"${EDITION}"'" and .arch=="'"${FEDORA_ARCH}"'" and .version=="'"${RELEASE}"'" and (.link | endswith(".iso")))') JSON=$(web_pipe "https://getfedora.org/releases.json" | jq '.[] | select((.variant=="'"${VARIANT}"'" or .variant=="'"${EDITION}"'") and .subvariant=="'"${EDITION}"'" and .arch=="x86_64" and .version=="'"${RELEASE}"'" and (.link | endswith(".iso")))')
URL=$(echo "${JSON}" | jq -r '.link' | head -n1) URL=$(echo "${JSON}" | jq -r '.link' | head -n1)
HASH=$(echo "${JSON}" | jq -r '.sha256' | head -n1) HASH=$(echo "${JSON}" | jq -r '.sha256' | head -n1)
echo "${URL} ${HASH}" echo "${URL} ${HASH}"
@ -2233,7 +1987,6 @@ function get_kolibrios() {
local HASH="" local HASH=""
local ISO="latest-iso.7z" local ISO="latest-iso.7z"
local URL="http://builds.kolibrios.org/${EDITION}" local URL="http://builds.kolibrios.org/${EDITION}"
HASH=$(web_pipe "${URL}/sha256sums.txt" | grep "${ISO}" | cut -d' ' -f1)
echo "${URL}/${ISO} ${HASH}" echo "${URL}/${ISO} ${HASH}"
} }
@ -2263,12 +2016,9 @@ function get_lmde() {
function get_maboxlinux() { function get_maboxlinux() {
local HASH="" local HASH=""
local ISO=""
local URL="" local URL=""
URL="https://sourceforge.net/projects/mabox-linux/files/${RELEASE}/download" URL="https://sourceforge.net/projects/mabox-linux/files/${RELEASE}/download"
URL="$(web_redirect "${URL}" | cut -d? -f1)" URL="$(web_redirect "${URL}" | cut -d? -f1)"
ISO="$(basename "${URL}")"
HASH=$(web_pipe "https://repo.maboxlinux.org/iso/${ISO}.md5" | cut -d' ' -f1)
echo "${URL} ${HASH}" echo "${URL} ${HASH}"
} }
@ -2398,14 +2148,11 @@ function get_macos() {
rm "${VM_PATH}/RecoveryImage.dmg" "${VM_PATH}/RecoveryImage.chunklist" rm "${VM_PATH}/RecoveryImage.dmg" "${VM_PATH}/RecoveryImage.chunklist"
echo " - RecoveryImage.img is ready." echo " - RecoveryImage.img is ready."
fi fi
echo "Downloading OpenCore & UEFI firmware" echo "Downloading OpenCore & UEFI firmware"
# Pin to last known-good commit; OVMF_CODE.fd was removed from master on 26 Jan 2026 web_get "https://github.com/kholia/OSX-KVM/raw/master/OpenCore/OpenCore.qcow2" "${VM_PATH}"
local OSX_KVM_COMMIT="da4b23b5e92c5b939568700034367e8b7649fe90" web_get "https://github.com/kholia/OSX-KVM/raw/master/OVMF_CODE.fd" "${VM_PATH}"
web_get "https://github.com/kholia/OSX-KVM/raw/${OSX_KVM_COMMIT}/OpenCore/OpenCore.qcow2" "${VM_PATH}"
web_get "https://github.com/kholia/OSX-KVM/raw/${OSX_KVM_COMMIT}/OVMF_CODE.fd" "${VM_PATH}"
if [ ! -e "${VM_PATH}/OVMF_VARS-1920x1080.fd" ]; then if [ ! -e "${VM_PATH}/OVMF_VARS-1920x1080.fd" ]; then
web_get "https://github.com/kholia/OSX-KVM/raw/${OSX_KVM_COMMIT}/OVMF_VARS-1920x1080.fd" "${VM_PATH}" web_get "https://github.com/kholia/OSX-KVM/raw/master/OVMF_VARS-1920x1080.fd" "${VM_PATH}"
fi fi
fi fi
make_vm_config RecoveryImage.img make_vm_config RecoveryImage.img
@ -2683,12 +2430,13 @@ function get_rebornos() {
} }
function get_rockylinux() { function get_rockylinux() {
if { [[ "${RELEASE}" =~ ^8. ]] || [[ "${RELEASE}" =~ ^10. ]]; } && [[ "${EDITION}" == "dvd" ]]; then if [[ "${RELEASE}" =~ ^8. ]] && [[ "${EDITION}" == "dvd" ]]; then
EDITION="dvd1" EDITION="dvd1"
fi fi
local HASH="" local HASH=""
local ISO="Rocky-${RELEASE}-x86_64-${EDITION}.iso" local ISO="Rocky-${RELEASE}-x86_64-${EDITION}.iso"
local URL="https://dl.rockylinux.org/vault/rocky/${RELEASE}/isos/x86_64" local URL=""
URL="https://dl.rockylinux.org/vault/rocky/${RELEASE}/isos/x86_64"
HASH=$(web_pipe "${URL}/CHECKSUM" | grep "SHA256" | grep "${ISO})" | cut -d' ' -f4) HASH=$(web_pipe "${URL}/CHECKSUM" | grep "SHA256" | grep "${ISO})" | cut -d' ' -f4)
echo "${URL}/${ISO} ${HASH}" echo "${URL}/${ISO} ${HASH}"
} }
@ -2833,18 +2581,13 @@ function get_tuxedo-os() {
} }
function get_ubuntu-server() { function get_ubuntu-server() {
local DATA=""
local HASH="" local HASH=""
local ISO="" local ISO=""
local NAME="live-server" local NAME="live-server"
local UBUNTU_ARCH="${ARCH}"
local URL="" local URL=""
if [[ "${RELEASE}" == "daily"* ]]; then if [[ "${RELEASE}" == "daily"* ]]; then
URL="https://cdimage.ubuntu.com/${OS}/${RELEASE}/current" URL="https://cdimage.ubuntu.com/${OS}/${RELEASE}/current"
elif [ "${UBUNTU_ARCH}" == "arm64" ]; then
# ARM64 ISOs are hosted on cdimage.ubuntu.com
URL="https://cdimage.ubuntu.com/releases/${RELEASE}/release"
else else
URL="https://releases.ubuntu.com/${RELEASE}" URL="https://releases.ubuntu.com/${RELEASE}"
fi fi
@ -2854,11 +2597,11 @@ function get_ubuntu-server() {
esac esac
if web_check "${URL}/SHA256SUMS"; then if web_check "${URL}/SHA256SUMS"; then
DATA=$(web_pipe "${URL}/SHA256SUMS" | grep "${NAME}" | grep "${UBUNTU_ARCH}" | grep iso | tail -n 1 ) DATA=$(web_pipe "${URL}/SHA256SUMS" | grep "${NAME}" | grep amd64 | grep iso | tail -n 1 )
ISO=$(cut -d'*' -f2 <<<"${DATA}") ISO=$(cut -d'*' -f2 <<<"${DATA}")
HASH=$(cut -d' ' -f1 <<<"${DATA}") HASH=$(cut -d' ' -f1 <<<"${DATA}")
else else
DATA=$(web_pipe "${URL}/MD5SUMS" | grep "${NAME}" | grep "${UBUNTU_ARCH}" | grep iso | tail -n 1 ) DATA=$(web_pipe "${URL}/MD5SUMS" | grep "${NAME}" | grep amd64 | grep iso | tail -n 1 )
ISO=$(cut -d' ' -f3 <<<"${DATA}") ISO=$(cut -d' ' -f3 <<<"${DATA}")
HASH=$(cut -d' ' -f1 <<<"${DATA}") HASH=$(cut -d' ' -f1 <<<"${DATA}")
fi fi
@ -2873,22 +2616,10 @@ function get_ubuntu-server() {
} }
function get_ubuntu() { function get_ubuntu() {
local DATA=""
local HASH=""
local ISO="" local ISO=""
local UBUNTU_ARCH="${ARCH}" local HASH=""
local URL="" local URL=""
local DATA=""
# Validate architecture support now that RELEASE is known
if ! is_arch_supported "${OS}" "${UBUNTU_ARCH}"; then
if [ "${OPERATION}" == "test" ] || [ "${OPERATION}" == "show" ]; then
test_result "${OS}" "${RELEASE}" "" "" "SKIP" "(not available for ${UBUNTU_ARCH})"
exit 0
else
echo "ERROR! $(pretty_name "${OS}") ${RELEASE} is not available for ${UBUNTU_ARCH} architecture."
exit 1
fi
fi
if [[ "${RELEASE}" == "daily"* ]] && [ "${OS}" == "ubuntustudio" ]; then if [[ "${RELEASE}" == "daily"* ]] && [ "${OS}" == "ubuntustudio" ]; then
# Ubuntu Studio daily-live images are in the dvd directory # Ubuntu Studio daily-live images are in the dvd directory
@ -2900,24 +2631,21 @@ function get_ubuntu() {
else else
URL="https://cdimage.ubuntu.com/${OS}/jammy/daily-live/current" URL="https://cdimage.ubuntu.com/${OS}/jammy/daily-live/current"
fi fi
VM_PATH="${OS}-jammy-live$(arch_suffix)" VM_PATH="${OS}-jammy-live"
elif [[ "${RELEASE}" == "daily"* ]] || [ "${RELEASE}" == "dvd" ]; then elif [[ "${RELEASE}" == "daily"* ]] || [ "${RELEASE}" == "dvd" ]; then
URL="https://cdimage.ubuntu.com/${OS}/${RELEASE}/current" URL="https://cdimage.ubuntu.com/${OS}/${RELEASE}/current"
VM_PATH="${OS}-${RELEASE}$(arch_suffix)" VM_PATH="${OS}-${RELEASE}"
elif [ "${OS}" == "ubuntu" ] && [ "${UBUNTU_ARCH}" == "arm64" ]; then
# ARM64 desktop ISOs are hosted on cdimage.ubuntu.com
URL="https://cdimage.ubuntu.com/releases/${RELEASE}/release"
elif [ "${OS}" == "ubuntu" ]; then elif [ "${OS}" == "ubuntu" ]; then
URL="https://releases.ubuntu.com/${RELEASE}" URL="https://releases.ubuntu.com/${RELEASE}"
else else
URL="https://cdimage.ubuntu.com/${OS}/releases/${RELEASE}/release" URL="https://cdimage.ubuntu.com/${OS}/releases/${RELEASE}/release"
fi fi
if web_check "${URL}/SHA256SUMS"; then if web_check "${URL}/SHA256SUMS"; then
DATA=$(web_pipe "${URL}/SHA256SUMS" | grep 'desktop\|dvd\|install' | grep "${UBUNTU_ARCH}" | grep iso | grep -v "+mac" | tail -n 1 ) DATA=$(web_pipe "${URL}/SHA256SUMS" | grep 'desktop\|dvd\|install' | grep amd64 | grep iso | grep -v "+mac" | tail -n 1 )
ISO=$(cut -d'*' -f2 <<<"${DATA}" | sed '1q;d') ISO=$(cut -d'*' -f2 <<<"${DATA}" | sed '1q;d')
HASH=$(cut -d' ' -f1 <<<"${DATA}" | sed '1q;d') HASH=$(cut -d' ' -f1 <<<"${DATA}" | sed '1q;d')
else else
DATA=$(web_pipe "${URL}/MD5SUMS" | grep 'desktop\|dvd\|install' | grep "${UBUNTU_ARCH}" | grep iso | grep -v "+mac" | tail -n 1 ) DATA=$(web_pipe "${URL}/MD5SUMS" | grep 'desktop\|dvd\|install' | grep amd64 | grep iso | grep -v "+mac" | tail -n 1 )
ISO=$(cut -d'*' -f2 <<<"${DATA}") ISO=$(cut -d'*' -f2 <<<"${DATA}")
HASH=$(cut -d' ' -f1 <<<"${DATA}") HASH=$(cut -d' ' -f1 <<<"${DATA}")
fi fi
@ -3618,10 +3346,7 @@ function create_vm() {
if [[ ${ISO} = *".gz"* ]]; then if [[ ${ISO} = *".gz"* ]]; then
gzip -d "${VM_PATH}/${ISO}" gzip -d "${VM_PATH}/${ISO}"
ISO="${ISO/.gz/}" ISO="${ISO/.gz/}"
fi fi;;
# Resize the raw image to provide space for Batocera's partition expansion
require_qemu_img
${QEMU_IMG} resize -f raw "${VM_PATH}/${ISO}" 128G;;
dragonflybsd) dragonflybsd)
# Could be other OS iso files compressed with bzip2 or gzip # Could be other OS iso files compressed with bzip2 or gzip
# but for now we'll keep this to know cases # but for now we'll keep this to know cases
@ -3763,23 +3488,21 @@ Advanced usage:
quickget --download ubuntu 22.04 quickget --download ubuntu 22.04
Arguments: Arguments:
--arch <arch> : Set architecture (arm64, aarch64, amd64, x86_64) --download <os> <release> [edition] : Download image; no VM configuration
--download <os> <release> [edition] : Download image; no VM configuration --create-config <os> [path/url] [flags] : Create VM config for an OS image
--create-config <os> [path/url] [flags] : Create VM config for an OS image --open-homepage <os> : Open homepage for the OS
--open-homepage <os> : Open homepage for the OS --show [os] : Show OS information
--show [os] : Show OS information --version : Show version
--version : Show version --help : Show this help message
--help : Show this help message
------------------------------------ Flags ------------------------------------- ------------------------------------ Flags -------------------------------------
--create-config: --create-config:
--disable-unattended : Force quickget not to set up an unattended installation --disable-unattended : Force quickget not to set up an unattended installation
-------------------------- For testing & development --------------------------- -------------------------- For testing & development ---------------------------
--url [os] [release] [edition] : Show image URL(s) --url [os] [release] [edition] : Show image URL(s)
--check [os] [release] [edition] : Check image URL(s) --check [os] [release] [edition] : Check image URL(s)
--check-all-arch [os] [release] [edition] : Check downloads for all architectures (amd64 and arm64) --list : List all supported systems
--list : List all supported systems --list-csv : List everything in csv format
--list-csv : List everything in csv format --list-json : List everything in json format
--list-json : List everything in json format
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Supported Operating Systems:\n\n' "$(${QUICKEMU} --version)" "${CURL_VERSION}" Supported Operating Systems:\n\n' "$(${QUICKEMU} --version)" "${CURL_VERSION}"
@ -3796,9 +3519,6 @@ fi
QUICKEMU=$(resolve_quickemu) QUICKEMU=$(resolve_quickemu)
I18NS=() I18NS=()
OPERATION="" OPERATION=""
CHECK_ALL_ARCH="false"
# Normalised host architecture for foreign arch detection
NORMALISED_HOST_ARCH="${ARCH}"
CURL=$(command -v curl) CURL=$(command -v curl)
if [ ! -x "${CURL}" ]; then if [ ! -x "${CURL}" ]; then
echo "ERROR! curl not found. Please install curl" echo "ERROR! curl not found. Please install curl"
@ -3807,33 +3527,10 @@ fi
CURL_VERSION=$("${CURL}" --version | head -n 1 | cut -d' ' -f2) CURL_VERSION=$("${CURL}" --version | head -n 1 | cut -d' ' -f2)
#TODO: Deprecate `list`, `list_csv`, and `list_json` in favor of `--list`, `--list-csv`, and `--list-json` #TODO: Deprecate `list`, `list_csv`, and `list_json` in favor of `--list`, `--list-csv`, and `--list-json`
# Function to process --arch flag
function parse_arch_flag() {
if [ "${1}" == "--arch" ] || [ "${1}" == "-arch" ]; then
case "${2}" in
arm64|aarch64) ARCH="arm64";;
amd64|x86_64) ARCH="amd64";;
*) echo "ERROR! Unsupported architecture: ${2}"; exit 1;;
esac
return 0 # Flag was found
fi
return 1 # Flag was not found
}
# Process --arch flag first if present (can be combined with other flags)
if parse_arch_flag "${1}" "${2}"; then
shift 2
fi
case "${1}" in case "${1}" in
--download|-download) --download|-download)
OPERATION="download" OPERATION="download"
shift shift
# Handle --arch after --download
if parse_arch_flag "${1}" "${2}"; then
shift 2
fi
;; ;;
--create-config|-create-config) --create-config|-create-config)
OPERATION="config" OPERATION="config"
@ -3864,10 +3561,6 @@ case "${1}" in
--url|-url) --url|-url)
OPERATION="show" OPERATION="show"
shift shift
# Handle --arch after --url
if parse_arch_flag "${1}" "${2}"; then
shift 2
fi
if [ -z "${1}" ]; then if [ -z "${1}" ]; then
for OS in $(os_support); do for OS in $(os_support); do
(test_all "${OS}") (test_all "${OS}")
@ -3880,10 +3573,6 @@ case "${1}" in
--check|-check) --check|-check)
OPERATION="test" OPERATION="test"
shift shift
# Handle --arch after --check
if parse_arch_flag "${1}" "${2}"; then
shift 2
fi
if [ -z "${1}" ]; then if [ -z "${1}" ]; then
for OS in $(os_support); do for OS in $(os_support); do
(test_all "${OS}") (test_all "${OS}")
@ -3893,25 +3582,6 @@ case "${1}" in
test_all "${1}" test_all "${1}"
exit 0 exit 0
fi;; fi;;
--check-all-arch|-check-all-arch)
OPERATION="test"
CHECK_ALL_ARCH="true"
shift
if [ -z "${1}" ]; then
for CHECK_ARCH in amd64 arm64; do
ARCH="${CHECK_ARCH}"
for OS in $(os_support); do
(test_all "${OS}")
done
done
exit 0
elif [ -z "${2}" ]; then
for CHECK_ARCH in amd64 arm64; do
ARCH="${CHECK_ARCH}"
test_all "${1}"
done
exit 0
fi;;
--list-csv|-list-csv|list|list_csv) list_csv;; --list-csv|-list-csv|list|list_csv) list_csv;;
--list-json|-list-json|list_json) list_json;; --list-json|-list-json|list_json) list_json;;
--list|-list) list_supported;; --list|-list) list_supported;;
@ -3926,69 +3596,9 @@ fi
os_supported os_supported
# Handle --check-all-arch for specific release/edition
if [ "${CHECK_ALL_ARCH}" == "true" ] && [ -n "${2}" ]; then
RELEASE="${2}"
EDITION="${3:-}"
for CHECK_ARCH in amd64 arm64; do
ARCH="${CHECK_ARCH}"
# Check architecture support before testing URL
if ! is_arch_supported "${OS}" "${ARCH}"; then
if [ -n "${EDITION}" ]; then
test_result "${OS}" "${RELEASE}" "${EDITION}" "" "SKIP" "(not available for ${ARCH})"
else
test_result "${OS}" "${RELEASE}" "" "" "SKIP" "(not available for ${ARCH})"
fi
continue
fi
# Validate release
case ${OS} in
*ubuntu-server*) validate_release releases_ubuntu-server;;
*ubuntu*) validate_release releases_ubuntu;;
*) validate_release "releases_${OS}";;
esac
# Generate and check URL
if [[ $(type -t "editions_${OS}") == function ]] && [ -n "${EDITION}" ]; then
URL=$(get_"${OS}" | cut -d' ' -f1 | head -n 1)
elif [ "${OS}" == "macos" ]; then
(get_macos)
continue
elif [[ "${OS}" == *"ubuntu-server"* ]]; then
(get_ubuntu-server)
continue
elif [[ "${OS}" == *"ubuntu"* ]]; then
(get_ubuntu)
continue
elif [[ "${OS}" == "windows"* ]]; then
test_result "${OS}" "${RELEASE}" "${EDITION}" "" "SKIP" "(Windows not supported in check mode)"
continue
else
URL=$(get_"${OS}" | cut -d' ' -f1 | head -n 1)
fi
CHECK=$(web_check "${URL}" && echo "PASS" || echo "FAIL")
test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" "${CHECK}"
done
exit 0
fi
# Validate architecture support before attempting download
# Skip for OSes with editions_* functions - they have edition-dependent arch support
# and will be validated after EDITION is parsed
if [[ $(type -t "editions_${OS}") != function ]]; then
if ! is_arch_supported "${OS}" "${ARCH}"; then
if [ "${OPERATION}" == "test" ] || [ "${OPERATION}" == "show" ]; then
test_result "${OS}" "${2:-}" "${3:-}" "" "SKIP" "(not available for ${ARCH})"
exit 0
else
echo "ERROR! $(pretty_name "${OS}") is not available for ${ARCH} architecture."
exit 1
fi
fi
fi
if [ -n "${2}" ]; then if [ -n "${2}" ]; then
RELEASE="${2}" RELEASE="${2}"
VM_PATH="${OS}-${RELEASE}$(arch_suffix)" VM_PATH="${OS}-${RELEASE}"
# If the OS has an editions_() function, use it. # If the OS has an editions_() function, use it.
if [[ $(type -t "editions_${OS}") == function ]]; then if [[ $(type -t "editions_${OS}") == function ]]; then
validate_release "releases_${OS}" validate_release "releases_${OS}"
@ -4010,18 +3620,8 @@ if [ -n "${2}" ]; then
echo -e "\nERROR! You must specify an edition." echo -e "\nERROR! You must specify an edition."
exit 1 exit 1
fi fi
# Now that EDITION is known, validate architecture support
if ! is_arch_supported "${OS}" "${ARCH}"; then
if [ "${OPERATION}" == "test" ] || [ "${OPERATION}" == "show" ]; then
test_result "${OS}" "${RELEASE}" "${EDITION}" "" "SKIP" "(not available for ${ARCH})"
exit 0
else
echo "ERROR! $(pretty_name "${OS}") ${EDITION} is not available for ${ARCH} architecture."
exit 1
fi
fi
handle_missing handle_missing
VM_PATH="${OS}-${RELEASE}-${EDITION}$(arch_suffix)" VM_PATH="${OS}-${RELEASE}-${EDITION}"
create_vm "$("get_${OS}" "${EDITION}")" create_vm "$("get_${OS}" "${EDITION}")"
elif [ "${OS}" == "macos" ]; then elif [ "${OS}" == "macos" ]; then
# macOS doesn't use create_vm() # macOS doesn't use create_vm()
@ -4044,7 +3644,7 @@ if [ -n "${2}" ]; then
if ! is_valid_language "${I18N}"; then if ! is_valid_language "${I18N}"; then
error_not_supported_lang error_not_supported_lang
fi fi
VM_PATH="$(echo "${OS}-${RELEASE}-${I18N// /-}" | tr -d '()')$(arch_suffix)" VM_PATH="$(echo "${OS}-${RELEASE}-${I18N// /-}" | tr -d '()')"
fi fi
validate_release "releases_${OS}" validate_release "releases_${OS}"
get_windows get_windows