%global upstream_name vmbuddy %global giturl https://github.com/tulilirockz/vmbuddy.git %global gitbranch main %global gitcommit %(git ls-remote %{giturl} refs/heads/%{gitbranch} 2>/dev/null | awk '{print $1}') %global gitshort %(c="%{gitcommit}"; if [ -n "$c" ]; then echo "${c:0:7}"; else echo "unknown"; fi) Name: vmbuddy Version: 0.1.3.r6.g8376895 Release: 100.2.3%{?dist} Summary: QEMU wrapper written in Bash with sensible defaults License: BSD-3-Clause URL: https://github.com/tulilirockz/vmbuddy ExclusiveArch: x86_64 aarch64 BuildRequires: git BuildRequires: python3 Requires: bash Requires: coreutils Requires: util-linux Requires: procps-ng Requires: swtpm Requires: swtpm-tools %ifarch x86_64 Requires: qemu-system-x86-core Requires: edk2-ovmf %endif %ifarch aarch64 Requires: qemu-system-aarch64-core Requires: edk2-aarch64 %endif Recommends: qemu-ui-gtk Recommends: qemu-audio-pipewire Recommends: qemu-device-display-virtio-gpu-gl Recommends: qemu-device-display-virtio-vga-gl Recommends: qemu-device-usb-host Recommends: qemu-device-usb-redirect Provides: vmbuddy = %{version}-%{release} Conflicts: vmbuddy %description vmbuddy is a small Bash wrapper around QEMU. It autodetects the host QEMU binary, sets up UEFI, TPM, virtio devices, networking, audio, display, and other QEMU defaults for quickly launching VM disk images. This git package clones the upstream main branch during the RPM build. %prep rm -rf %{upstream_name} git clone --depth 1 --branch %{gitbranch} %{giturl} %{upstream_name} cd %{upstream_name} # Upstream changes this script often, so do not carry a fragile line-number # patch. Replace the firmware autodetection block by markers instead. python3 - <<'PY' from pathlib import Path path = Path("vmbuddy.sh") data = path.read_text() start = data.find("# We want to use flathub whenever possible") end = data.find("\nwhile :; do", start) if start == -1 or end == -1: raise SystemExit("Could not find vmbuddy firmware autodetection block") replacement = r'''vmbuddy_find_uefi_binary() { local arch="${1:-${QEMU_RUNNER_ARCHITECTURE:-$(uname -m)}}" local candidate local candidates=() case "${arch}" in x86_64) candidates=( "/usr/share/edk2/ovmf/OVMF_CODE_4M.fd" "/usr/share/edk2/ovmf/OVMF_CODE.fd" "/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd" "/usr/share/edk2/x64/OVMF_CODE.4m.fd" "/usr/share/edk2/x64/OVMF_CODE.fd" "/usr/share/OVMF/OVMF_CODE_4M.fd" "/usr/share/OVMF/OVMF_CODE.fd" "/usr/share/qemu/edk2-x86_64-code.fd" "/app/lib/extensions/Qemu/share/qemu/edk2-x86_64-code.fd" ) ;; aarch64|arm64) candidates=( "/usr/share/edk2/aarch64/QEMU_EFI.fd" "/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw" "/usr/share/edk2/aarch64/QEMU_EFI.silent.fd" "/usr/share/AAVMF/AAVMF_CODE.fd" "/usr/share/qemu-efi-aarch64/QEMU_EFI.fd" "/usr/share/qemu/edk2-aarch64-code.fd" "/app/lib/extensions/Qemu/share/qemu/edk2-aarch64-code.fd" ) ;; *) candidates=( "/usr/share/qemu/edk2-${arch}-code.fd" "/app/lib/extensions/Qemu/share/qemu/edk2-${arch}-code.fd" ) ;; esac for candidate in "${candidates[@]}"; do if [ -e "${candidate}" ]; then printf '%s\n' "${candidate}" return 0 fi done printf '/app/lib/extensions/Qemu/share/qemu/edk2-%s-code.fd\n' "${arch}" } if [ -z "${QEMU_RUNNER_UEFI_BINARY}" ]; then QEMU_RUNNER_UEFI_BINARY="$(vmbuddy_find_uefi_binary "${QEMU_RUNNER_ARCHITECTURE}")" fi ''' path.write_text(data[:start] + replacement + data[end:]) PY # If the user changes architecture at runtime, recompute the default firmware # path for that requested architecture unless they also pass --uefi manually. python3 - <<'PY' from pathlib import Path path = Path("vmbuddy.sh") data = path.read_text() old = ''' QEMU_RUNNER_ARCHITECTURE="${2}" QEMU_RUNNER_BINARY="$(system_or_fallback "qemu-system-${QEMU_RUNNER_ARCHITECTURE}" "flatpak run --command=qemu-system-${QEMU_RUNNER_ARCHITECTURE} org.virt_manager.virt-manager")" shift ''' new = ''' QEMU_RUNNER_ARCHITECTURE="${2}" QEMU_RUNNER_BINARY="$(system_or_fallback "qemu-system-${QEMU_RUNNER_ARCHITECTURE}" "flatpak run --command=qemu-system-${QEMU_RUNNER_ARCHITECTURE} org.virt_manager.virt-manager")" QEMU_RUNNER_UEFI_BINARY="$(vmbuddy_find_uefi_binary "${QEMU_RUNNER_ARCHITECTURE}")" shift ''' if old in data and new not in data: data = data.replace(old, new, 1) path.write_text(data) PY %build # Nothing to build. vmbuddy is a shell script. %install install -Dm0755 %{upstream_name}/vmbuddy.sh %{buildroot}%{_bindir}/vmbuddy install -Dm0644 %{upstream_name}/LICENSE %{buildroot}%{_licensedir}/%{name}/LICENSE install -Dm0644 %{upstream_name}/README.md %{buildroot}%{_docdir}/%{name}/README.md %files %license %{_licensedir}/%{name}/LICENSE %doc %{_docdir}/%{name}/README.md %{_bindir}/vmbuddy %changelog * Wed Jul 08 2026 Sl (Shahaf Levi) - 0.1.0^git%{gitshort}-3 - Replace fragile patch application with marker-based firmware autodetection rewrite * Fri Jun 26 2026 Sl (Shahaf Levi) - 0.1.0^git%{gitshort}-2 - Patch upstream firmware autodetection to prefer system OVMF/AAVMF paths on Arch and Fedora - Prefer distro OVMF/AAVMF firmware paths before the Flatpak fallback - Keep upstream Flatpak firmware path as fallback for --flatpak usage * Fri Jun 26 2026 Sl (Shahaf Levi) - 0.1.0^git%{gitshort}-1 - Initial git package for vmbuddy built from upstream main - Support x86_64 and aarch64 builds