diff --git a/README.md b/README.md index 59face5..83ed5ae 100644 --- a/README.md +++ b/README.md @@ -17,29 +17,22 @@ distributions where the virtual machines can be stored anywhere, such as external USB storage. Quickemu is opinionated and will attempt to *"do the right thing"* rather than -expose rich configuration options. See the video where I explain some of my -motivations for creating this script. +expose rich configuration options. Quickemu is a frontend to the fully +accelerated [qemu-virgil](https://snapcraft.io/qemu-virgil). See the video +where I explain some of my motivations for creating this script. [![Replace VirtualBox with Bash & QEMU](https://img.youtube.com/vi/AOTYWEgw0hI/0.jpg)](https://www.youtube.com/watch?v=AOTYWEgw0hI) ## Installation -### Ubuntu 19.10 or newer +Clone this repository: -Install qemu - -```bash -sudo apt install qemu qemu-kvm libvirt-clients libvirt-daemon bridge-utils ovmf -sudo adduser ${SUDO_USER} kvm +``` +git clone https://github.com/wimpysworld/quickemu.git ``` -Install `samba` *(optional)* if you want to share home directories with guest virtual machines - -```bash -sudo apt install samba -``` - -Install the `qemu-virgil` snap *(optional)* +Install the `qemu-virgil` snap. You can find details about how to install snapd +and `qemu-virgil` on the [Snap Store page for qemu-virgil](https://snapcraft.io/qemu-virgil) ```bash snap install qemu-virgil @@ -68,16 +61,16 @@ Which will output something like this: ``` Starting /media/martin/Quickemu/ubuntu-focal-desktop.conf + - QEMU: /snap/bin/qemu-virgil v4.2.0 - BIOS: Legacy - - Disk: /media/martin/Quickemu/ubuntu/focal-desktop-amd64.qcow2 - - Size: 64G + - Disk: /media/martin/Quickemu/ubuntu/focal-desktop-amd64.qcow2 (64G) - ISO: /media/martin/Quickemu/ubuntu/focal-desktop-amd64.iso - CPU: 4 Core(s) - RAM: 4G - UI: sdl - GL: on - VIRGL: on - - Monitor: 1664x936 + - Display: 1664x936 - smbd: /home/martin will be exported to the guest via smb://10.0.2.4/qemu - ssh: 22221/tcp is connected. Login via 'ssh user@localhost -p 22221' ``` @@ -93,7 +86,6 @@ You can also pass optional parameters --efi : Enable EFI BIOS (experimental). --restore : Restore the snapshot. --snapshot : Create a disk snapshot. - --virgil : Use virgil, if available. ``` ## TODO @@ -101,4 +93,5 @@ You can also pass optional parameters - [x] Make display configuration more robust - [x] Improve stdout presentation - [x] Make disk image optionally size configurable - - [ ] Improve snapshot management \ No newline at end of file + - [ ] Improve snapshot management + - [ ] Create desktop launcher for a VM \ No newline at end of file diff --git a/quickemu.sh b/quickemu.sh index 85461fe..7054fb9 100755 --- a/quickemu.sh +++ b/quickemu.sh @@ -48,41 +48,34 @@ function vm_boot() { local GL="on" local VIRGL="on" local UI="sdl" - - # If QEMU has not already been selected, pick one - if [ -z "${QEMU}" ]; then - if [ -e /snap/bin/qemu-virgil ]; then - QEMU="/snap/bin/qemu-virgil" - QEMU_IMG="/snap/bin/qemu-virgil.qemu-img" - #QEMU_IMG="/usr/bin/qemu-img" - elif [ -e /usr/bin/qemu-system-x86_64 ]; then - QEMU="/usr/bin/qemu-system-x86_64" - QEMU_IMG="/usr/bin/qemu-img" - else - echo "ERROR! Could not find QEMU. Quitting." - exit 1 - fi - fi local QEMU_VER=$(${QEMU} -version | head -n1 | cut -d' ' -f4 | cut -d'(' -f1) - local QEMU_BIN=$(basename ${QEMU}) + echo "Starting ${VM}" echo " - QEMU: ${QEMU} v${QEMU_VER}" if [ ${ENABLE_EFI} -eq 1 ]; then - if [ "${QEMU_BIN}" == "qemu-virgil" ] && [ -e /snap/qemu-virgil/current/usr/share/qemu/edk2-x86_64-code.fd ] ; then + if [ -e /snap/qemu-virgil/current/usr/share/qemu/edk2-x86_64-code.fd ] ; then BIOS="-drive if=pflash,format=raw,readonly,file=/snap/qemu-virgil/current/usr/share/qemu/edk2-x86_64-code.fd" VIRGL="off" - elif [ -e /usr/share/qemu/OVMF.fd ]; then - BIOS="-drive if=pflash,format=raw,readonly,file=/usr/share/qemu/OVMF.fd" - VIRGL="off" else echo " - EFI: Booting requested but no EFI firmware found." echo " Booting from Legacy BIOS." fi - echo " - BIOS: ${BIOS}" + echo " - BIOS: EFI" else echo " - BIOS: Legacy" fi + if [ -n "${disk_img}" ]; then + disk_img_snapshot="${disk_img}.snapshot" + else + echo "ERROR! No disk_img defined." + exit 1 + fi + + if [ -z "${disk}" ]; then + disk="64G" + fi + echo " - Disk: ${disk_img} (${disk})" # If the disk is present but doesn't appear to have an install, then # remove it. @@ -130,45 +123,34 @@ function vm_boot() { # Determine what display to use local display="-display ${UI},gl=${GL}" - if [ "${QEMU_VER}" == "2.11.1" ]; then - display="-display sdl" - # Fix stuttering mouse pointer when SDL backend is used. - export SDL_VIDEO_X11_DGAMOUSE=0 - fi echo " - UI: ${UI}" echo " - GL: ${GL}" echo " - VIRGL: ${VIRGL}" - # TODO: Detect Wayland here and "do the right thing". - # Determine the most suitable 16:9 resolution of for VM based - # on the lowest resolution connected monitor. - local xres=800 - local yres=600 - - local LOWEST_WIDTH=$(xrandr --listmonitors | grep -v Monitors | cut -d' ' -f4 | cut -d'/' -f1 | sort | head -n1) - if [ ${LOWEST_WIDTH} -ge 3840 ]; then - xres=3200 - yres=1800 - elif [ ${LOWEST_WIDTH} -ge 2560 ]; then - xres=2048 - yres=1152 - elif [ ${LOWEST_WIDTH} -ge 1920 ]; then - xres=1664 - yres=936 - elif [ ${LOWEST_WIDTH} -ge 1280 ]; then - xres=1152 - yres=648 + local xres=1152 + local yres=648 + if [ "${XDG_SESSION_TYPE}" == "x11" ]; then + local LOWEST_WIDTH=$(xrandr --listmonitors | grep -v Monitors | cut -d' ' -f4 | cut -d'/' -f1 | sort | head -n1) + if [ ${LOWEST_WIDTH} -ge 3840 ]; then + xres=3200 + yres=1800 + elif [ ${LOWEST_WIDTH} -ge 2560 ]; then + xres=2048 + yres=1152 + elif [ ${LOWEST_WIDTH} -ge 1920 ]; then + xres=1664 + yres=936 + elif [ ${LOWEST_WIDTH} -ge 1280 ]; then + xres=1152 + yres=648 + fi fi + echo " - Display: ${xres}x${yres}" - if [ "${QEMU_BIN}" == "qemu-virgil" ]; then - echo " - Monitor: ${xres}x${yres}" - fi local NET="" # If smbd is available, export $HOME to the guest via samba - if [ "${QEMU_BIN}" == "qemu-virgil" ] && [ -e /snap/qemu-virgil/current/usr/sbin/smbd ]; then - NET=",smb=${HOME}" - elif [ "${QEMU_BIN}" == "qemu-system-x86_64" ] && [ -e /usr/sbin/smbd ]; then + if [ -e /snap/qemu-virgil/current/usr/sbin/smbd ]; then NET=",smb=${HOME}" fi @@ -187,7 +169,6 @@ function vm_boot() { echo " - ssh: All ports for exposing ssh have been exhausted." fi - #echo " - QEMU: qemu-${ENGINE}" # Boot the iso image ${QEMU} -name ${VMNAME},process=${VMNAME} \ ${BIOS} \ @@ -221,17 +202,15 @@ function usage() { echo "You can also pass optional parameters" echo " --delete : Delete the disk image." echo " --efi : Enable EFI BIOS (experimental)." - echo " --qemu : Override full path to QEMU executable." echo " --restore : Restore the snapshot." echo " --snapshot : Create a disk snapshot." exit 1 } -disk="64G" -BIOS="" DELETE=0 ENABLE_EFI=0 -QEMU="" +readonly QEMU="/snap/bin/qemu-virgil" +readonly QEMU_IMG="/snap/bin/qemu-virgil.qemu-img" RESTORE=0 SNAPSHOT=0 VM="" @@ -250,10 +229,6 @@ while [ $# -gt 0 ]; do -snapshot|--snapshot) SNAPSHOT=1 shift;; - -qemu|--qemu) - QEMU="$2" - shift - shift;; -vm|--vm) VM="$2" shift @@ -266,23 +241,18 @@ while [ $# -gt 0 ]; do esac done -if [ -n "${VM}" ] || [ -e "${VM}" ]; then - source "${VM}" - echo Starting "${VM}" - if [ -n "${disk_img}" ]; then - disk_img_snapshot="${disk_img}.snapshot" - else - echo "ERROR! No disk_img defined." - exit 1 - fi -else - echo "ERROR! VM not found." +# Check we have qemu-virgil available +if [ ! -e "${QEMU}" ] && [ ! -e "${QEMU_IMG}" ]; then + echo "ERROR! qemu-virgil not found. Please install the qemu-virgil snap." + echo " https://snapcraft.io/qemu-virgil" exit 1 fi -if [ -n "${QEMU}" ] && [ ! -e "${QEMU}" ]; then - echo "ERROR! ${QEMU} not found. Quitting" - exit 1 +if [ -n "${VM}" ] || [ -e "${VM}" ]; then + source "${VM}" +else + echo "ERROR! Virtual machine configuration not found." + usage fi if [ ${DELETE} -eq 1 ]; then