diff --git a/README.md b/README.md index 7d4c757..7ec3050 100644 --- a/README.md +++ b/README.md @@ -225,8 +225,8 @@ with your preferred flavour. - `ubuntukylin` (Ubuntu Kylin) - `ubuntu-mate` (Ubuntu MATE) - `ubuntustudio` (Ubuntu Studio) -- `ubuntu-unity` (Ubuntu Unity) - `ubuntu` (Ubuntu) +- `ubuntu-unity` (Ubuntu Unity) - `xubuntu` (Xubuntu) ## Other Operating Systems @@ -260,6 +260,7 @@ with your preferred flavour. - `kolibrios` (KolibriOS) - `linuxmint` (Linux Mint) - `lmde` (Linux Mint Debian Edition) +- `mageia` (Mageia) - `manjaro` (Manjaro) - `mxlinux` (MX Linux) - `netboot` (netboot.xyz) @@ -270,10 +271,13 @@ with your preferred flavour. - `oraclelinux` (Oracle Linux) - `popos` (Pop!\_OS) - `reactos` (ReactOS) +- `rebornos` (RebornOS) - `rockylinux` (Rocky Linux) - `slackware` (Slackware) - `solus` (Solus) - `tails` (Tails) +- `truenas-core` (TrueNAS Core) +- `truenas-scale` (TrueNAS Scale) - `void` (Void Linux) - `zorin` (Zorin OS) @@ -405,6 +409,9 @@ There are some considerations when running macOS via Quickemu. - Optimised by default, but no GPU acceleration is available. - Host CPU vendor is detected and guest CPU is optimised accordingly. + - [VirtIO Block + Media](https://www.kraxel.org/blog/2019/06/macos-qemu-guest/) is + used for the system disk where supported. - [VirtIO `usb-tablet`](http://philjordan.eu/osx-virt/) is used for the mouse. - VirtIO Network (`virtio-net`) is supported and enabled on macOS @@ -443,8 +450,15 @@ sudo rm /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist Now reboot, and the App Store should work. -## Windows 8.1, 10 & 11 Guests +## Windows 10 & 11 Guests +`quickget` can not download +[Windows10](https://www.microsoft.com/software-download/windows10) and +[Windows 11](https://www.microsoft.com/software-download/windows11) +automatically, but does automatically create an optimised virtual +machine configuration that you can just add an Windows .iso image to. +This configuration also includes the [VirtIO drivers for +Windows](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/). `quickget` can automatically download Windows 8.1, [Windows 10](https://www.microsoft.com/en-gb/software-download/windows10ISO) and [Windows @@ -465,22 +479,12 @@ quickemu --vm windows-11.conf - Username: `Quickemu` - Password: `quickemu` -### Regional versions - -By default `quickget` will download the *"English International"* -release, but you can optionally specify one of the supported languages: -For example: - -``` bash -quickget windows 11 "Chinese (Traditional)" -``` - The default Windows 11 configuration looks like this: ``` bash guest_os="windows" disk_img="windows-11/disk.qcow2" -iso="windows-11/Win11_EnglishInternational_x64.iso" +iso="windows-11/windows-11.iso" fixed_iso="windows-11/virtio-win.iso" tpm="on" secureboot="on" @@ -771,12 +775,11 @@ You can also pass optional parameters --mouse : Set mouse. @Options: 'tablet' (default), 'ps2', 'usb', 'virtio' --usb-controller : Set usb-controller. @Options: 'ehci' (default), 'xhci', 'none' --extra_args|--xa : Pass additional arguments to qemu. 1 per element eg --xa '-device' --xa 'tpm-tis,tpmdev=tpm0' - --show_args : Show all the compiled qemu & swmtp arguments as a human readable list, before starting VM --version : Print version ``` - +``` ## Desktop shortcuts Desktop shortcuts can be created for a VM, the shortcuts are saved in diff --git a/build-docs b/build-docs index 83f2eab..43c38df 160000 --- a/build-docs +++ b/build-docs @@ -1 +1 @@ -Subproject commit 83f2eab64f307de03be0f4ed5860c76f7883b7a7 +Subproject commit 43c38df5ef08bada423b076274604951d5c13c0d diff --git a/docs/quickemu.1 b/docs/quickemu.1 index 0226a81..39cefe8 100644 --- a/docs/quickemu.1 +++ b/docs/quickemu.1 @@ -14,7 +14,7 @@ . ftr VB CB . ftr VBI CBI .\} -.TH "QUICKEMU" "1" "October 21, 2022" "quickemu" "Quickemu User Manual" +.TH "QUICKEMU" "1" "February 4, 2023" "quickemu" "Quickemu User Manual" .hy .SH NAME .PP @@ -324,6 +324,8 @@ All the official Ubuntu flavours are supported, just replace .IP \[bu] 2 \f[V]ubuntu\f[R] (Ubuntu) .IP \[bu] 2 +\f[V]ubuntu-unity\f[R] (Ubuntu Unity) +.IP \[bu] 2 \f[V]xubuntu\f[R] (Xubuntu) .SS Other Operating Systems .PP @@ -383,6 +385,8 @@ All the official Ubuntu flavours are supported, just replace .IP \[bu] 2 \f[V]lmde\f[R] (Linux Mint Debian Edition) .IP \[bu] 2 +\f[V]mageia\f[R] (Mageia) +.IP \[bu] 2 \f[V]manjaro\f[R] (Manjaro) .IP \[bu] 2 \f[V]mxlinux\f[R] (MX Linux) @@ -403,6 +407,8 @@ All the official Ubuntu flavours are supported, just replace .IP \[bu] 2 \f[V]reactos\f[R] (ReactOS) .IP \[bu] 2 +\f[V]rebornos\f[R] (RebornOS) +.IP \[bu] 2 \f[V]rockylinux\f[R] (Rocky Linux) .IP \[bu] 2 \f[V]slackware\f[R] (Slackware) @@ -411,6 +417,10 @@ All the official Ubuntu flavours are supported, just replace .IP \[bu] 2 \f[V]tails\f[R] (Tails) .IP \[bu] 2 +\f[V]truenas-core\f[R] (TrueNAS Core) +.IP \[bu] 2 +\f[V]truenas-scale\f[R] (TrueNAS Scale) +.IP \[bu] 2 \f[V]void\f[R] (Void Linux) .IP \[bu] 2 \f[V]zorin\f[R] (Zorin OS) @@ -609,6 +619,10 @@ Optimised by default, but no GPU acceleration is available. .IP \[bu] 2 Host CPU vendor is detected and guest CPU is optimised accordingly. .IP \[bu] 2 +VirtIO Block +Media (https://www.kraxel.org/blog/2019/06/macos-qemu-guest/) is used +for the system disk where supported. +.IP \[bu] 2 VirtIO \f[V]usb-tablet\f[R] (http://philjordan.eu/osx-virt/) is used for the mouse. .IP \[bu] 2 @@ -663,8 +677,15 @@ sudo rm /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist .fi .PP Now reboot, and the App Store should work. -.SS Windows 8.1, 10 & 11 Guests -.PP +.SS Windows 10 & 11 Guests +.PP +\f[V]quickget\f[R] can not download +Windows10 (https://www.microsoft.com/software-download/windows10) and +Windows 11 (https://www.microsoft.com/software-download/windows11) +automatically, but does automatically create an optimised virtual +machine configuration that you can just add an Windows .iso image to. +This configuration also includes the VirtIO drivers for +Windows (https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/). \f[V]quickget\f[R] can automatically download Windows 8.1, Windows 10 (https://www.microsoft.com/en-gb/software-download/windows10ISO) and Windows 11 (https://www.microsoft.com/en-gb/software-download/windows11) @@ -691,17 +712,6 @@ Username: \f[V]Quickemu\f[R] .IP \[bu] 2 Password: \f[V]quickemu\f[R] .RE -.SS Regional versions -.PP -By default \f[V]quickget\f[R] will download the \f[I]\[lq]English -International\[rq]\f[R] release, but you can optionally specify one of -the supported languages: For example: -.IP -.nf -\f[C] -quickget windows 11 \[dq]Chinese (Traditional)\[dq] -\f[R] -.fi .PP The default Windows 11 configuration looks like this: .IP @@ -709,7 +719,7 @@ The default Windows 11 configuration looks like this: \f[C] guest_os=\[dq]windows\[dq] disk_img=\[dq]windows-11/disk.qcow2\[dq] -iso=\[dq]windows-11/Win11_EnglishInternational_x64.iso\[dq] +iso=\[dq]windows-11/windows-11.iso\[dq] fixed_iso=\[dq]windows-11/virtio-win.iso\[dq] tpm=\[dq]on\[dq] secureboot=\[dq]on\[dq] diff --git a/docs/quickemu.1.md b/docs/quickemu.1.md index 15a0b3c..54a8c1b 100644 --- a/docs/quickemu.1.md +++ b/docs/quickemu.1.md @@ -1,6 +1,6 @@ --- author: Martin Wimpress -date: October 21, 2022 +date: February 4, 2023 footer: quickemu header: Quickemu User Manual section: 1 @@ -250,6 +250,7 @@ with your preferred flavour. - `ubuntu-mate` (Ubuntu MATE) - `ubuntustudio` (Ubuntu Studio) - `ubuntu` (Ubuntu) +- `ubuntu-unity` (Ubuntu Unity) - `xubuntu` (Xubuntu) ## Other Operating Systems @@ -283,6 +284,7 @@ with your preferred flavour. - `kolibrios` (KolibriOS) - `linuxmint` (Linux Mint) - `lmde` (Linux Mint Debian Edition) +- `mageia` (Mageia) - `manjaro` (Manjaro) - `mxlinux` (MX Linux) - `netboot` (netboot.xyz) @@ -293,10 +295,13 @@ with your preferred flavour. - `oraclelinux` (Oracle Linux) - `popos` (Pop!\_OS) - `reactos` (ReactOS) +- `rebornos` (RebornOS) - `rockylinux` (Rocky Linux) - `slackware` (Slackware) - `solus` (Solus) - `tails` (Tails) +- `truenas-core` (TrueNAS Core) +- `truenas-scale` (TrueNAS Scale) - `void` (Void Linux) - `zorin` (Zorin OS) @@ -434,6 +439,9 @@ There are some considerations when running macOS via Quickemu. - Optimised by default, but no GPU acceleration is available. - Host CPU vendor is detected and guest CPU is optimised accordingly. + - [VirtIO Block + Media](https://www.kraxel.org/blog/2019/06/macos-qemu-guest/) is + used for the system disk where supported. - [VirtIO `usb-tablet`](http://philjordan.eu/osx-virt/) is used for the mouse. - VirtIO Network (`virtio-net`) is supported and enabled on macOS @@ -472,8 +480,15 @@ sudo rm /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist Now reboot, and the App Store should work. -## Windows 8.1, 10 & 11 Guests +## Windows 10 & 11 Guests +`quickget` can not download +[Windows10](https://www.microsoft.com/software-download/windows10) and +[Windows 11](https://www.microsoft.com/software-download/windows11) +automatically, but does automatically create an optimised virtual +machine configuration that you can just add an Windows .iso image to. +This configuration also includes the [VirtIO drivers for +Windows](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/). `quickget` can automatically download Windows 8.1, [Windows 10](https://www.microsoft.com/en-gb/software-download/windows10ISO) and [Windows @@ -494,22 +509,12 @@ quickemu --vm windows-11.conf - Username: `Quickemu` - Password: `quickemu` -### Regional versions - -By default `quickget` will download the *"English International"* -release, but you can optionally specify one of the supported languages: -For example: - -``` bash -quickget windows 11 "Chinese (Traditional)" -``` - The default Windows 11 configuration looks like this: ``` bash guest_os="windows" disk_img="windows-11/disk.qcow2" -iso="windows-11/Win11_EnglishInternational_x64.iso" +iso="windows-11/windows-11.iso" fixed_iso="windows-11/virtio-win.iso" tpm="on" secureboot="on" diff --git a/docs/quickemu_conf.1 b/docs/quickemu_conf.1 index 7dc6c23..a66ef36 100644 --- a/docs/quickemu_conf.1 +++ b/docs/quickemu_conf.1 @@ -14,7 +14,7 @@ . ftr VB CB . ftr VBI CBI .\} -.TH "QUICKEMU_CONF" "1" "October 21, 2022" "quickemu_conf" "Quickemu Configuration Manual" +.TH "QUICKEMU_CONF" "1" "February 4, 2023" "quickemu_conf" "Quickemu Configuration Manual" .hy .SH NAME .PP @@ -38,6 +38,8 @@ boot=\[dq]efi\[dq] cpu_cores=\[dq]\[dq] disk_img=\[dq]\[dq] disk_size=\[dq]\[dq] +display=\[dq]\[dq] +extra_args=\[dq]\[dq] fixed_iso=\[dq]\[dq] floppy=\[dq]\[dq] guest_os=\[dq]linux\[dq] @@ -52,6 +54,24 @@ ram=\[dq]\[dq] secureboot=\[dq]off\[dq] tpm=\[dq]off\[dq] usb_devices=() +viewer=\[dq]spicy\[dq] +ssh_port=\[dq]\[dq] +spice_port=\[dq]\[dq] +public_dir=\[dq]\[dq] +monitor=\[dq]socket\[dq] +monitor_telnet_port=\[dq]4440\[dq] +monitor_telnet_host=\[dq]localhost\[dq] +monitor_cmd=\[dq]\[dq] +serial=\[dq]socket\[dq] +serial_telnet_port=\[dq]6660\[dq] +serial_telnet_host=\[dq]localhost\[dq] +# options: ehci(USB2.0), xhci(USB3.0) +usb_controller=\[dq]ehci\[dq] +# options: ps2, usb, virtio +keyboard=\[dq]usb\[dq] +keyboard_layout=\[dq]en-us\[dq] +# options: ps2, usb, tablet, virtio +mouse=\[dq]tablet\[dq] \f[R] .fi .SH EXAMPLES diff --git a/docs/quickemu_conf.1.md b/docs/quickemu_conf.1.md index 09b9a31..eb0db42 100644 --- a/docs/quickemu_conf.1.md +++ b/docs/quickemu_conf.1.md @@ -1,6 +1,6 @@ --- author: Martin Wimpress -date: October 21, 2022 +date: February 4, 2023 footer: quickemu_conf header: Quickemu Configuration Manual section: 1 @@ -29,6 +29,8 @@ boot="efi" cpu_cores="" disk_img="" disk_size="" +display="" +extra_args="" fixed_iso="" floppy="" guest_os="linux" @@ -43,6 +45,24 @@ ram="" secureboot="off" tpm="off" usb_devices=() +viewer="spicy" +ssh_port="" +spice_port="" +public_dir="" +monitor="socket" +monitor_telnet_port="4440" +monitor_telnet_host="localhost" +monitor_cmd="" +serial="socket" +serial_telnet_port="6660" +serial_telnet_host="localhost" +# options: ehci(USB2.0), xhci(USB3.0) +usb_controller="ehci" +# options: ps2, usb, virtio +keyboard="usb" +keyboard_layout="en-us" +# options: ps2, usb, tablet, virtio +mouse="tablet" ``` # EXAMPLES diff --git a/docs/quickget.1 b/docs/quickget.1 index 4e5fd85..60484ee 100644 --- a/docs/quickget.1 +++ b/docs/quickget.1 @@ -14,7 +14,7 @@ . ftr VB CB . ftr VBI CBI .\} -.TH "QUICKGET" "1" "October 21, 2022" "quickget" "Quickget User Manual" +.TH "QUICKGET" "1" "February 4, 2023" "quickget" "Quickget User Manual" .hy .SH NAME .PP @@ -106,6 +106,8 @@ All the official Ubuntu flavours are supported, just replace .IP \[bu] 2 \f[V]ubuntu\f[R] (Ubuntu) .IP \[bu] 2 +\f[V]ubuntu-unity\f[R] (Ubuntu Unity) +.IP \[bu] 2 \f[V]xubuntu\f[R] (Xubuntu) .SS Other Operating Systems .PP @@ -165,6 +167,8 @@ All the official Ubuntu flavours are supported, just replace .IP \[bu] 2 \f[V]lmde\f[R] (Linux Mint Debian Edition) .IP \[bu] 2 +\f[V]mageia\f[R] (Mageia) +.IP \[bu] 2 \f[V]manjaro\f[R] (Manjaro) .IP \[bu] 2 \f[V]mxlinux\f[R] (MX Linux) @@ -185,6 +189,8 @@ All the official Ubuntu flavours are supported, just replace .IP \[bu] 2 \f[V]reactos\f[R] (ReactOS) .IP \[bu] 2 +\f[V]rebornos\f[R] (RebornOS) +.IP \[bu] 2 \f[V]rockylinux\f[R] (Rocky Linux) .IP \[bu] 2 \f[V]slackware\f[R] (Slackware) @@ -193,6 +199,10 @@ All the official Ubuntu flavours are supported, just replace .IP \[bu] 2 \f[V]tails\f[R] (Tails) .IP \[bu] 2 +\f[V]truenas-core\f[R] (TrueNAS Core) +.IP \[bu] 2 +\f[V]truenas-scale\f[R] (TrueNAS Scale) +.IP \[bu] 2 \f[V]void\f[R] (Void Linux) .IP \[bu] 2 \f[V]zorin\f[R] (Zorin OS) @@ -391,6 +401,10 @@ Optimised by default, but no GPU acceleration is available. .IP \[bu] 2 Host CPU vendor is detected and guest CPU is optimised accordingly. .IP \[bu] 2 +VirtIO Block +Media (https://www.kraxel.org/blog/2019/06/macos-qemu-guest/) is used +for the system disk where supported. +.IP \[bu] 2 VirtIO \f[V]usb-tablet\f[R] (http://philjordan.eu/osx-virt/) is used for the mouse. .IP \[bu] 2 @@ -445,8 +459,15 @@ sudo rm /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist .fi .PP Now reboot, and the App Store should work. -.SS Windows 8.1, 10 & 11 Guests +.SS Windows 10 & 11 Guests .PP +\f[V]quickget\f[R] can not download +Windows10 (https://www.microsoft.com/software-download/windows10) and +Windows 11 (https://www.microsoft.com/software-download/windows11) +automatically, but does automatically create an optimised virtual +machine configuration that you can just add an Windows .iso image to. +This configuration also includes the VirtIO drivers for +Windows (https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/). \f[V]quickget\f[R] can automatically download Windows 8.1, Windows 10 (https://www.microsoft.com/en-gb/software-download/windows10ISO) and Windows 11 (https://www.microsoft.com/en-gb/software-download/windows11) @@ -473,17 +494,6 @@ Username: \f[V]Quickemu\f[R] .IP \[bu] 2 Password: \f[V]quickemu\f[R] .RE -.SS Regional versions -.PP -By default \f[V]quickget\f[R] will download the \f[I]\[lq]English -International\[rq]\f[R] release, but you can optionally specify one of -the supported languages: For example: -.IP -.nf -\f[C] -quickget windows 11 \[dq]Chinese (Traditional)\[dq] -\f[R] -.fi .PP The default Windows 11 configuration looks like this: .IP @@ -491,7 +501,7 @@ The default Windows 11 configuration looks like this: \f[C] guest_os=\[dq]windows\[dq] disk_img=\[dq]windows-11/disk.qcow2\[dq] -iso=\[dq]windows-11/Win11_EnglishInternational_x64.iso\[dq] +iso=\[dq]windows-11/windows-11.iso\[dq] fixed_iso=\[dq]windows-11/virtio-win.iso\[dq] tpm=\[dq]on\[dq] secureboot=\[dq]on\[dq] diff --git a/docs/quickget.1.md b/docs/quickget.1.md index c307883..c3e72e6 100644 --- a/docs/quickget.1.md +++ b/docs/quickget.1.md @@ -1,6 +1,6 @@ --- author: Martin Wimpress -date: October 21, 2022 +date: February 4, 2023 footer: quickget header: Quickget User Manual section: 1 @@ -82,6 +82,7 @@ with your preferred flavour. - `ubuntu-mate` (Ubuntu MATE) - `ubuntustudio` (Ubuntu Studio) - `ubuntu` (Ubuntu) +- `ubuntu-unity` (Ubuntu Unity) - `xubuntu` (Xubuntu) ## Other Operating Systems @@ -115,6 +116,7 @@ with your preferred flavour. - `kolibrios` (KolibriOS) - `linuxmint` (Linux Mint) - `lmde` (Linux Mint Debian Edition) +- `mageia` (Mageia) - `manjaro` (Manjaro) - `mxlinux` (MX Linux) - `netboot` (netboot.xyz) @@ -125,10 +127,13 @@ with your preferred flavour. - `oraclelinux` (Oracle Linux) - `popos` (Pop!\_OS) - `reactos` (ReactOS) +- `rebornos` (RebornOS) - `rockylinux` (Rocky Linux) - `slackware` (Slackware) - `solus` (Solus) - `tails` (Tails) +- `truenas-core` (TrueNAS Core) +- `truenas-scale` (TrueNAS Scale) - `void` (Void Linux) - `zorin` (Zorin OS) @@ -266,6 +271,9 @@ There are some considerations when running macOS via Quickemu. - Optimised by default, but no GPU acceleration is available. - Host CPU vendor is detected and guest CPU is optimised accordingly. + - [VirtIO Block + Media](https://www.kraxel.org/blog/2019/06/macos-qemu-guest/) is + used for the system disk where supported. - [VirtIO `usb-tablet`](http://philjordan.eu/osx-virt/) is used for the mouse. - VirtIO Network (`virtio-net`) is supported and enabled on macOS @@ -304,8 +312,15 @@ sudo rm /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist Now reboot, and the App Store should work. -## Windows 8.1, 10 & 11 Guests +## Windows 10 & 11 Guests +`quickget` can not download +[Windows10](https://www.microsoft.com/software-download/windows10) and +[Windows 11](https://www.microsoft.com/software-download/windows11) +automatically, but does automatically create an optimised virtual +machine configuration that you can just add an Windows .iso image to. +This configuration also includes the [VirtIO drivers for +Windows](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/). `quickget` can automatically download Windows 8.1, [Windows 10](https://www.microsoft.com/en-gb/software-download/windows10ISO) and [Windows @@ -326,22 +341,12 @@ quickemu --vm windows-11.conf - Username: `Quickemu` - Password: `quickemu` -### Regional versions - -By default `quickget` will download the *"English International"* -release, but you can optionally specify one of the supported languages: -For example: - -``` bash -quickget windows 11 "Chinese (Traditional)" -``` - The default Windows 11 configuration looks like this: ``` bash guest_os="windows" disk_img="windows-11/disk.qcow2" -iso="windows-11/Win11_EnglishInternational_x64.iso" +iso="windows-11/windows-11.iso" fixed_iso="windows-11/virtio-win.iso" tpm="on" secureboot="on" diff --git a/quickemu b/quickemu index 492a6fe..ddab8dd 100755 --- a/quickemu +++ b/quickemu @@ -542,13 +542,13 @@ function vm_boot() { case ${macos_release} in catalina) BALLOON="" - MAC_DISK_DEV="ide-hd,bus=ahci.2" + MAC_DISK_DEV="virtio-blk-pci" NET_DEVICE="vmxnet3" USB_HOST_PASSTHROUGH_CONTROLLER="usb-ehci" ;; big-sur|monterey|ventura) BALLOON="-device virtio-balloon" - MAC_DISK_DEV="ide-hd,bus=ahci.2" + MAC_DISK_DEV="virtio-blk-pci" NET_DEVICE="virtio-net" USB_HOST_PASSTHROUGH_CONTROLLER="nec-usb-xhci" GUEST_TWEAKS="${GUEST_TWEAKS} -global nec-usb-xhci.msi=off" @@ -568,7 +568,11 @@ function vm_boot() { fi ;; windows) - CPU="-cpu host,kvm=on,+hypervisor,+invtsc,l3-cache=on,migratable=no,hv_passthrough" + if [ "${QEMU_VER_SHORT}" -gt 60 ]; then + CPU="-cpu host,kvm=on,+hypervisor,+invtsc,l3-cache=on,migratable=no,hv_passthrough" + else + CPU="-cpu host,kvm=on,+hypervisor,+invtsc,l3-cache=on,migratable=no,hv_frequencies,kvm_pv_unhalt,hv_reenlightenment,hv_relaxed,hv_spinlocks=8191,hv_stimer,hv_synic,hv_time,hv_vapic,hv_vendor_id=1234567890ab,hv_vpindex" + fi if [ "${HOST_CPU_VENDOR}" == "AuthenticAMD" ]; then CPU="${CPU},topoext" fi @@ -1071,19 +1075,18 @@ function vm_boot() { if [ "${guest_os}" == "macos" ]; then # shellcheck disable=SC2054 args+=(-device ahci,id=ahci - -device ide-hd,bus=ahci.0,drive=BootLoader,bootindex=0,rotation_rate=1 - -drive id=BootLoader,if=none,format=qcow2,discard=unmap,file="${MAC_BOOTLOADER}") + -device ide-hd,bus=ahci.0,drive=BootLoader,bootindex=0 + -drive id=BootLoader,if=none,format=qcow2,file="${MAC_BOOTLOADER}") if [ -n "${img}" ]; then # shellcheck disable=SC2054 - args+=(-device ide-hd,bus=ahci.1,drive=RecoveryImage,rotation_rate=1 - -drive id=RecoveryImage,if=none,format=raw,discard=unmap,file="${img}") + args+=(-device ide-hd,bus=ahci.1,drive=RecoveryImage + -drive id=RecoveryImage,if=none,format=raw,file="${img}") fi # shellcheck disable=SC2054,SC2206 - args+=(-device ${MAC_DISK_DEV},drive=SystemDisk,rotation_rate=1 - -drive id=SystemDisk,if=none,format=qcow2,discard=unmap,file="${disk_img}" ${STATUS_QUO}) - + args+=(-device ${MAC_DISK_DEV},drive=SystemDisk + -drive id=SystemDisk,if=none,format=qcow2,file="${disk_img}" ${STATUS_QUO}) elif [ "${guest_os}" == "kolibrios" ]; then # shellcheck disable=SC2054,SC2206 args+=(-device ahci,id=ahci @@ -1109,9 +1112,8 @@ function vm_boot() { else # shellcheck disable=SC2054,SC2206 - args+=(-device virtio-scsi-pci,id=scsi0 - -device scsi-hd,drive=SystemDisk,bus=scsi0.0,lun=0,rotation_rate=1 - -drive id=SystemDisk,if=none,format=qcow2,discard=unmap,file="${disk_img}" ${STATUS_QUO}) + args+=(-device virtio-blk-pci,drive=SystemDisk + -drive id=SystemDisk,if=none,format=qcow2,file="${disk_img}" ${STATUS_QUO}) fi # https://wiki.qemu.org/Documentation/9psetup @@ -1226,33 +1228,6 @@ function vm_boot() { SHELL_ARGS="${SHELL_ARGS//)/\\)}" SHELL_ARGS="${SHELL_ARGS//Quickemu Project/\"Quickemu Project\"}" - # Show all the compiled qemu & swmtp arguments as a human readable list - - QemuArgsFile="${VMDIR}/QemuArgsList.txt" - - printf "\n\n Present Working Directory: %s" "$(pwd)" > "$QemuArgsFile" - printf "\n\n Qemu: %s\n" "$QEMU" >> "$QemuArgsFile" - - for a in "${args[@]}"; do - if [[ "$a" == -dev* ]]; then printf "\n\n %s" "$a" >> "$QemuArgsFile" - elif [[ "$a" == -* ]]; then printf "\n %s" "$a" >> "$QemuArgsFile" - else printf " %s" "$a" >> "$QemuArgsFile" - fi - done - - if [[ $tpm == "on" ]]; then - printf "\n\n\n Secure Boot: %s \n\n %s " "$SWTPM" "${tpm_args[*]}" >> "$QemuArgsFile" - else - printf "\n\n\n Secure Boot: Not Set" >> "$QemuArgsFile" - fi - printf "\n\n\n" >> "$QemuArgsFile" - - if [[ $ShowQemuArgs ]]; then - cat "$QemuArgsFile" - read -rp " [enter] to continue, ctrl-c to quit > " - printf "\n\n" - fi - if [ ${VM_UP} -eq 0 ]; then # Enable grab-on-hover for SDL: https://github.com/quickemu-project/quickemu/issues/541 case "${OUTPUT}" in @@ -1360,7 +1335,6 @@ function usage() { echo " --mouse : Set mouse. @Options: 'tablet' (default), 'ps2', 'usb', 'virtio'" echo " --usb-controller : Set usb-controller. @Options: 'ehci' (default), 'xhci', 'none'" echo " --extra_args|--xa : Pass additional arguments to qemu. 1 per element eg --xa '-device' --xa 'tpm-tis,tpmdev=tpm0'" - echo " --show_args : Show all the compiled qemu & swmtp arguments as a human readable list, before starting VM" echo " --version : Print version" exit 1 } @@ -1533,7 +1507,7 @@ EXTRA_ARGS="" # shellcheck disable=SC2155 readonly LAUNCHER=$(basename "${0}") readonly DISK_MIN_SIZE=$((197632 * 8)) -readonly VERSION="4.4" +readonly VERSION="4.6" # TODO: Make this run the native architecture binary QEMU=$(command -v qemu-system-x86_64) @@ -1667,9 +1641,6 @@ else if [[ ! $EXTRA_ARGS ]]; then EXTRA_ARGS="$1" else EXTRA_ARGS+=" $1" ; fi shift ;; - -show_args|--show_args|--show-qemu-args) - ShowQemuArgs=1 - shift;; -version|--version) echo "${VERSION}" exit;; diff --git a/quickemu-tools b/quickemu-tools new file mode 100755 index 0000000..915550f --- /dev/null +++ b/quickemu-tools @@ -0,0 +1,830 @@ +#! /bin/bash + +## Copyright (c) Alex Genovese https://github.com/TuxVinyards + +# licence: GPL3 https://www.gnu.org/licenses + + +## Provides a set of qcow snapshot & msr tools to work with quickemu + +# https://github.com/quickemu-project/quickemu https://gitlab.com/qemu-project/qemu + +# Users should install 'quickemu' and may set up Virtual Machines as normal. + + +## Install by placing script in /usr/bin (ensure chmod +x) + +# Run by opening a terminal in the VM folder and typing: + +# quickemu-tools --vm "file.conf" + + +## Based on 'quickemu-mod' https://github.com/TuxVinyards/quickemu-mod + +# but, as having run time mods & hypervisor recipes removed, this 'tools' version + +# now disengages it from having to keep track of the main project ... + + +# In theory, further disengagement could be achieved by routing straight 'qemu-img' + +# But as this should work with any version of the original 'quickemu' + +# the quickemu methods have been left, so any future add-ons might be possible. REVIEW + + + +## Any snippets re-used from https://github.com/quickemu-project/quickemu + +# are used to make the two projects work together easily & are used mainly + +# for the benefit of the original project. + +# Original snippets may be subject the original MIT licence. + +# The 'tools' project, as separate script, is covered by GPL3 + +# even it it becomes adopted by the original project. + +# IF ANY 'MODDED' CODE BECOMES USED IN THE ORIGINAL QUICKEMU SCRIPTS, + +# OR ANY OTHER SIMILAR PROJECT, YOU SHOULD SHOW BOTH OF THE LICENCES + +# & SHOW CLEAR ATTRIBUTIONS TO THE CODE SECTIONS USED. + + + +QtoolsVersion="2023.03.28" + + + +## API --vm "file.conf" [ --path "path/folder" ] + +# where path to be used if .conf file not in current folder / present working directory + + +## SETTINGS + +# General color & theming + +X_Shade="3" + +# Yellow 3 (recommended), Blue 4, Cyan 6 (brighter blue), Red 1 + +# https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit + + +# File for default KVM behaviour for unhandled machine-specific registers. ( REVIEW ) + +# Edit here if your OS locates 'modprobe.d' differently. Default is "/etc/modprobe.d/kvm-quickemu.conf" + +KVM_MSR_ModProbeFile="/etc/modprobe.d/kvm-quickemu.conf" + + +CurrentFolder="$(pwd)" + + +## Make sure shell is set during session to decimal separator of dot + +# LC_ALL=C changes too much, just set the numeric. + +# See locale setting discussion: https://unix.stackexchange.com/a/149129 + +# Also https://unix.stackexchange.com/questions/62316/why-is-there-no-euro-english-locale?rq=1 + +# & http://www.unicode.org/L2/L2001/01102-POSIX15897.htm + + +export "LC_NUMERIC=C" + +export "LC_COLLATE=C" + + +## MOD Standard Quickemu checks for '< 4' which at 2022/3 now needs a bump. + +# Some ver 5 script is now present in the standard release too ... + +# More Version 5 style scripting should be used: + +# See http://mywiki.wooledge.org/BashGuide/Practices#Choose_Your_Shell + +if ((BASH_VERSINFO[0] < 5)); then + echo "Sorry, you need Bash 5.0 or newer to run this script." + exit 1 +fi + + +LAUNCHER="$(basename "$0")" + + +if [[ ! $(type -p quickemu) ]]; then + echo "ERROR! QuickEmu not found. Please install." + exit 1 +fi + + +# TODO add 'guestfs-tools' & an interface for 'virt-resize' + + +printColor () { + + tput setaf "$X_Shade" + + # shellcheck disable=SC2059 + + printf "$@" + + tput sgr0 + +} + +exit () { + + # trap to keep terminal open if started by mouse click -t secs + + printf "\n\n" + + if [[ ! $CLI ]] && [[ $1 ]]; then + + printColor " ERROR : [Enter] to quit or [h] to hold terminal open \n\n" + + read -rp " > " -t 30 ExitTrap + + fi + + [[ ! $CLI ]] && [[ $ExitTrap == "h" ]] && printf "\n\n Holding terminal open [Enter] to quit \n\n" && read -rp " > " + + tput cnorm + + command exit "$@" + +} + + +function_find_kvm_msr_default_and_status () { + + # outputs boths vars 'KVM_MSR_DefaultConf' & 'KVM_MSR_status' with value Y or N + + # finds and flags if MSRS has a config conflict + + KVM_MSR_status="$(cat /sys/module/kvm/parameters/ignore_msrs)" + + [[ ! $KVM_MSR_ModProbeFile ]] && KVM_MSR_ModProbeFile="/etc/modprobe.d/kvm-quickemu.conf" + + KVM_MSR_DefaultConf="$(cat "$KVM_MSR_ModProbeFile" 2> /dev/null)" + + [[ "$KVM_MSR_DefaultConf" == *'=Y' ]] && KVM_MSR_default="Y" + + [[ "$KVM_MSR_DefaultConf" == *'=N' ]] || [[ ! -e "$KVM_MSR_ModProbeFile" ]] && KVM_MSR_default="N" + + if [[ $VM_InstanceName ]]; then + + if [[ "$VM_InstanceName" == *windows* ]] || [[ "$VM_InstanceName" == *macos* ]] ; then + + if [[ $KVM_MSR_status == "N" ]]; then KVM_MSR_Error=1 ; else KVM_MSR_Error= ; fi + + elif [[ "$VM_InstanceName" != *windows* ]] && [[ "$VM_InstanceName" != *macos* ]] ; then + + if [[ $KVM_MSR_status == "Y" ]]; then KVM_MSR_Error=1 ; else KVM_MSR_Error= ; fi + + else + + KVM_MSR_Error= + + fi + + fi +} + +print_kvm_status () { + + function_find_kvm_msr_default_and_status + + if [[ $KVM_MSR_status == "Y" ]] ; then + + printf "\n\n KVM: /sys/module/kvm/parameters/ignore_msrs = Y" + + [[ $VM_InstanceName ]] && [[ $KVM_MSR_Error ]] && printColor " ERROR " + + printf "\n" + + else + + printf "\n\n KVM: /sys/module/kvm/parameters/ignore_msrs = N" + + [[ $VM_InstanceName ]] && [[ $KVM_MSR_Error ]] && printColor " ERROR " + + printf "\n" + + fi + +} + + +toggle_msr_defaults () { + + # Modded & now reversible rewrite of original quickemu's function 'ignore_msrs_always' + + # https://www.linux-kvm.org/page/Category:Docs + + if [[ ! -d /etc/modprobe.d ]]; then + + printf "\n ERROR! /etc/modprobe.d was not found. \n\n See notes, it may be possible to manually create modprobe.d/kvm-quickemu.conf \n\n" + + else + + printColor "\n\n Configure default, boot-up, KVM behaviour " + + printf "for unhandled machine-specific registers" + + printf "\n\n Normal setting is N (don't ignore) but Windows and MacOS require Y (true) 'ignore' " + + + function_find_kvm_msr_default_and_status + + printColor "\n\n Status: /sys/module/kvm/parameters/ignore_msrs = %s Current Default = %s" "$KVM_MSR_status" "$KVM_MSR_default" + + + [[ ! $KVM_MSR_ModProbeFile ]] && KVM_MSR_ModProbeFile="/etc/modprobe.d/kvm-quickemu.conf" + + if [[ ! -e "$KVM_MSR_ModProbeFile" ]]; then + + printf "\n\n \'%s\' needs to be created " "$KVM_MSR_ModProbeFile" + + fi + + printf "\n\n [y] to set Y [n] to set N [b] to go back \n\n" + + read -rp " > " Set_MSR_defaults + + # set .conf file content & update initramfs in all kernels (y/n or none) + + if [[ $Set_MSR_defaults == "y" ]]; then + + printf "\n\n Updating 'initramfs' may take a moment or two ... \n\n" + + # As per Martin's solution in original quickemu, needs 'tee' to get this to work, + # but route tee's stdout to null to tidy the screen + + echo "options kvm ignore_msrs=Y" | sudo tee "$KVM_MSR_ModProbeFile" 1> /dev/null + sudo update-initramfs -k all -u + + elif [[ $Set_MSR_defaults == "n" ]]; then + + printf "\n\n Updating 'initramfs' may take a moment or two ... \n\n" + + echo "options kvm ignore_msrs=N" | sudo tee "$KVM_MSR_ModProbeFile" 1> /dev/null + sudo update-initramfs -k all -u + + fi + + fi + + [[ $CLI ]] && exit 1 + +} + + +show_kvm_sudo_security_note () { + + printColor "\n QuickEmu-Tools require 'sudo' permissions to echo true or false to 'ignore_msrs'" + + printf "\n\n This allows you to create a temporary MSRS status that may be changed at any time," + + printf "\n\n allowing you to match the selected guest VM that you want to run." + + + printColor "\n\n\n If you have concerns about this script, or about giving elevated permissions, " + + printf "\n\n then the script should be checked or you should issue these commands manually:" + + printf "\n\n Open a side terminal, use shift-crtl-c to copy the displayed command & shift-crtl-v to paste it. " + + printf "\n\n Elevated permissions will then exist only in the side terminal & cease once it is closed. " + + printf "\n\n Return to q-tools & select 'leave as'. Q-Tools will re-read msrs settings & auto-update. " + + + printColor "\n\n\n If you mainly use Windows or Mac VM's then a file '.../modprobe.d/kvm-quickemu.conf' " + + printf "\n\n can be created to modify the load up settings. Quickemu-Tools has a new built in function" + + printf "\n\n that can set this up & also allows future adjustments may be made." + + printf "\n\n Or it may be carried out manually... See settings, script & further notes for details." + + printColor "\n\n\n Status: /sys/module/kvm/parameters/ignore_msrs = %s Current Default = %s" "$KVM_MSR_status" "$KVM_MSR_default" + + printf "\n\n Windows or MacOS should be set to 'Y' " + + printf "\n" + +} + + +select_msr_config () { + + # MSR_offer normally present if MSRS/OS conflict previously detected, + # however, presume selector is being used to change current status REVIEW + + print_kvm_status + + if [[ $KVM_MSR_status == "Y" ]]; then MSR_offer="N" ; else MSR_offer="Y" ; fi + + KVM_MSR_selector= + + [[ $KVM_MSR_selector_LoadHelp ]] && show_kvm_sudo_security_note + + + while true ; do + + if [[ $MSR_offer == "Y" ]]; then + + printf "\n\n Set Y : echo 1 | sudo tee /sys/module/kvm/parameters/ignore_msrs ? " + + printColor "\n\n [y] to set Y " + + printf " [enter] leave as N" + + else + + printf "\n\n Set N : echo 0 | sudo tee /sys/module/kvm/parameters/ignore_msrs ? " + + printColor "\n\n [n] to set N " + + printf " [enter] leave as Y" + + fi + + printf " [d] to set the boot defaults" + + [[ $KVM_MSR_selector != "h" ]] || [[ $KVM_MSR_selector_LoadHelp ]] && printf " [h] see help " + + printf "\n\n" + + read -rp " > " KVM_MSR_selector + + printf "\n" + + [[ $KVM_MSR_selector == "h" ]] && show_kvm_sudo_security_note + + [[ ! $KVM_MSR_selector ]] && break + + [[ $KVM_MSR_selector == "y" && $MSR_offer == "N" ]] || [[ $KVM_MSR_selector == "n" && $MSR_offer == "Y" ]] && break + + if [[ $KVM_MSR_selector == "y" ]]|| [[ $KVM_MSR_selector == "n" ]]; then + + # As per Martin's solution in original quickemu, needs 'tee' to get this to work, + # but route tee's stdout to null to tidy the screen + + [[ $KVM_MSR_selector == "y" ]] && echo 1 | sudo tee /sys/module/kvm/parameters/ignore_msrs 1> /dev/null + + [[ $KVM_MSR_selector == "n" ]] && echo 0 | sudo tee /sys/module/kvm/parameters/ignore_msrs 1> /dev/null + + print_kvm_status + + printColor "\n\n [enter] to return \n\n" + read -rp " > " + + break + + fi + + if [[ $KVM_MSR_selector == "d" ]]; then + + toggle_msr_defaults + + if [[ $Set_MSR_defaults == "b" ]]; then + + Set_MSR_defaults= + print_kvm_status + printColor "\n\n Make TEMPORARY setting adjustments to MSRS ?" + + else + function_find_kvm_msr_default_and_status + break + fi + + fi + + done + + KVM_MSR_selector= + KVM_MSR_selector_LoadHelp= + +} + +msrs_conflict_check_resolver() { + + # Do a check ... + + function_find_kvm_msr_default_and_status + + # Display & Offer config settings if MSRS/OS CONFLICT exists + + if [[ $KVM_MSR_status == "N" ]] ; then + + # usual system default = N + + if [[ "$VM_InstanceName" == *windows* ]] || [[ "$VM_InstanceName" == *macos* ]] ; then + + printColor "\n\n Selected: %s " "$VM_InstanceName" + + printf " 'ignore_msrs' is recommended for Windows and Mac" + + #printf "\n\n Status: /sys/module/kvm/parameters/ignore_msrs = N Default = %s" "$KVM_MSR_default" + + MSR_offer="Y" + + select_msr_config + + function_find_kvm_msr_default_and_status + + if [[ $KVM_MSR_status == "N" ]]; then KVM_MSR_Error=1 ; else KVM_MSR_Error= ; fi + + fi + + else + + # Status = Y & which is only recommended for Windows & Mac + + if [[ "$VM_InstanceName" != *windows* ]] && [[ "$VM_InstanceName" != *macos* ]] ; then + + printColor "\n\n Selected: %s " "$VM_InstanceName" + + printf " 'ignore_msrs' is only recommended for Windows and Mac" + + #printf "\n\n Status: /sys/module/kvm/parameters/ignore_msrs = Y Default = %s" "$KVM_MSR_default" + + MSR_offer="N" + + select_msr_config + + function_find_kvm_msr_default_and_status + + if [[ $KVM_MSR_status == "Y" ]]; then KVM_MSR_Error=1 ; else KVM_MSR_Error= ; fi + + fi + + fi + +} + + + +function_conf_error () { + + printf "\n\n ERROR Quickemu-Tools Settings, VM folder & conf file(s)" + + if [[ $1 ]] ; then printf "\n\n Please check %s settings, location & content ... \n\n" "$1" + + else printf "\n\n Please check the settings and re-run this script ... \n\n" ; fi + + printColor "\n\n [Enter] for help [q] to quit \n\n" + + read -rp " > " + + [[ $REPLY == "q" ]] && printf "\n\n" && command exit + + show_quickemu_tools_help + + command exit +} + + +function_snapshot_list() { + + printf "\n\n" + + quickemu -vm "$VM_Conf_File" --snapshot info + +} + + +function show_quickemu_tools_help { + + printColor "\n\n QuickEmu-Tools version %s " "$QtoolsVersion" + + printColor "\n\n Easy snapshot & MSRS tools for the QuickEmu Project" + + printf "\n\n Manage multiple snapshots. Recover Disk Space. " + + printf "\n\n Toggle boot-up & temporary MSRS's " + + printf "\n\n\n For code contributions, add-ons, info & updates see:" + + printf "\n\n https://github.com/TuxVinyards/" + + printf "\n\n\n From a terminal: " + + printColor "%s --vm \"vm-name.conf\" [ --path \"path/folder\" ] " "$LAUNCHER" + + printf "\n\n Add path if working from outside the VM's .conf folder" + + printf "\n\n [enter] to return \n\n" + + read -rp " > " +} + +show_qmod_title() { + + printColor "\n\n Quickemu Tools - Version %s" "$QtoolsVersion" + + printf "\n\n A menu interfaced tool set for the quickemu project ..... \n\n" + +} + + +function_show_main_menu_header () { + + printf "\033c" + + show_qmod_title + + printColor " %s " "$VM_InstanceName" + + printf " @ %s" "$VM_Conf_Dir" + +} + + + +## API READ #################################################################################################### + + +# https://unix.stackexchange.com/questions/220330/hide-and-unhide-cursor-with-tput + +tput civis + +if [[ ! $1 ]]; then + + show_quickemu_tools_help + + echo + command exit 1 + +else + + ## API --vm "file.conf" [ --path "path/folder" ] + + # where path to be used if .conf file not in current folder / present working directory + + while [[ $# -gt 0 ]]; do + + case "$1" in + + -vm|--vm) + VM_Conf_File="$2" + shift + shift ;; + + --path|-path) + VM_Conf_Dir="$2" + shift + shift ;; + + esac + + done + + + [[ ! $VM_Conf_Dir ]] && VM_Conf_Dir="$CurrentFolder" + + [[ ! $VM_Conf_File ]] && function_conf_error "Qtools COMMAND LINE Instruction," + + [[ ! -e "$VM_Conf_Dir/$VM_Conf_File" ]] && function_conf_error "Qtools COMMAND LINE Instruction," + + + ## Check file/folder exists + + [[ ! -d "$VM_Conf_Dir" ]] && function_conf_error "folder" + + # change directory to where the VM is + + if [[ $CurrentFolder != "$VM_Conf_Dir" ]]; then + + ! cd "$VM_Conf_Dir" && printColor "\n\n ERROR .conf folder switching \n\n" && exit 1 + + fi + + [[ ! -e "$VM_Conf_File" ]] && function_conf_error ".conf file" + + + # Quickemu sets the same name to the .conf file and to the main folder + + VM_InstanceName="${VM_Conf_File/.conf}" + + # VM_QCOW_Dir="$VM_Conf_Dir/$VM_InstanceName" + + # check that the dir contains the right files && grep .conf for right content + + [[ ! $(ls "$VM_InstanceName"/*.qcow2 2> /dev/null) ]] && function_conf_error "folder" + + ! grep -q 'guest_os=' "$VM_Conf_File" && function_conf_error ".conf file" + + + ## Check KVM parameter settings & advise according to guest OS + + KVM_MSR_selector= + + function_find_kvm_msr_default_and_status + + #msrs_conflict_check_resolver + +fi + + +printf "\033c" + +show_qmod_title + +MultiInstanceError="$(pgrep -c 'quickemu-mod')" + +if [[ $MultiInstanceError -gt 1 ]]; then + + printColor "\n\n ERROR more than one instance of q-tools is running \n\n" + + read -rp " Close the other instances, then press [enter] to continue > " + +fi + +# MAIN MENU (select VM then choose actions to do) + +while true ; do + + MainMenuChoice= + + SnapTitle= + + SnapNumber= + + SnapName= + + function_show_main_menu_header + + + if [[ ! $MainMenuChoice ]]; then + + print_kvm_status + + printf "\n\n [m] toggle msrs " + + printf "\n\n\n [sl] list [sc] create [sd] delete [sa] apply snapshots " + + + printf "\n\n\n [h] show help & info " + + printf "\n\n [q] quit " + + printf "\n\n\n" + + read -rp " > " MainMenuChoice + + fi + + + # ACTIONS: + + if [[ $MainMenuChoice == "h" ]] ; then + + show_quickemu_tools_help + + elif [[ $MainMenuChoice == "m" ]] ; then + + #KVM_MSR_selector_LoadHelp=1 + select_msr_config + #msrs_conflict_check_resolver + + elif [[ $MainMenuChoice == "q" ]] ; then + + printf "\n\n" + MainMenuChoice= + break + exit + + elif [[ $MainMenuChoice == "sl" ]] ; then + + function_snapshot_list + printf "\n\n [enter] to return to menu \n\n " + read -rp " > " + + elif [[ $MainMenuChoice == "sc" ]] ; then + + function_snapshot_list + printColor "\n\n Give [title] or [enter] for date.time [b] back to menu " + SnapTitle= + printf "\n\n" + read -rp " > " SnapTitle + printf "\n\n" + + [[ ! $SnapTitle ]] && SnapTitle="$(date +%b%d.%R)" + + [[ $SnapTitle != "b" ]] && quickemu -vm "$VM_Conf_File" --snapshot create "$SnapTitle" + + printf "\n\n [enter] to return to menu \n\n " + read -rp " > " + + elif [[ $MainMenuChoice == "sd" ]] ; then + + printColor "\n\n Quickemu-Tools Snapshot Deletion:" + function_snapshot_list + + # Create range-selectable array + SnapListString="$(function_snapshot_list | grep '[0-9][0-9]:')" + mapfile -t SnapListArrRaw <<< "$SnapListString" + + i=0 + printColor "\n\n ID Array Name \n\n" + while [[ "${SnapListArrRaw[$i]}" ]]; do + IFS=' ' read -ra SnapListArrSeparated <<< "${SnapListArrRaw[$i]}" + printf "%2d %2d %s \n" "${SnapListArrSeparated[0]}" "$i" "${SnapListArrSeparated[1]}" + ((i+=1)) + done + + SnapListArrTotal=$((i-1)) + + printColor "\n\n Give ARRAY number 0 to %s of snapshot or start of snapshot range to delete" "$SnapListArrTotal" + printf "\n\n [enter] to return to main menu " + + SnapName= + SnapDeleteStart= + SnapDeleteEnd= + SnapDeleteConfirm= + + printf "\n\n" + read -rp " > " SnapDeleteStart + + + if [[ $SnapDeleteStart ]]; then + + printColor "\n\n [enter] for individual snapshot or ARRAY [number] for end of range (inclusive) \n\n" + read -rp " > " SnapDeleteEnd + + if [[ $SnapDeleteEnd ]]; then + printf "\n Array Range = %s to %s " "$SnapDeleteStart" "$SnapDeleteEnd" + else + printf "\n Delete = Array entry %s " "$SnapDeleteStart" + SnapDeleteEnd="$SnapDeleteStart" + fi + + printColor "\n\n [enter] to continue [b] back to main menu \n\n" + + read -rp " > " SnapDeleteConfirm + + + if [[ $SnapDeleteConfirm == "b" ]]; then + + printf "\n\n Deletion schedule has been CANCELLED" + + else + + SnapDeleteRangeCounter=$SnapDeleteStart + + while [[ $SnapDeleteRangeCounter -le $SnapDeleteEnd ]]; do + IFS=' ' read -ra SnapListArrSeparated <<< "${SnapListArrRaw[$SnapDeleteRangeCounter]}" + SnapName="${SnapListArrSeparated[1]}" + + if [[ ! $SnapName ]]; then + printColor "\n\n ERROR with SnapShot Array List \n\n" + exit 1 + else + printColor "\n\n Deleting SnapShot %2d %2d %s \n\n" "${SnapListArrSeparated[0]}" "$SnapDeleteRangeCounter" "${SnapListArrSeparated[1]}" + quickemu -vm "$VM_Conf_File" --snapshot delete "$SnapName" + fi + ((SnapDeleteRangeCounter+=1)) + done + + fi + + printf "\n\n [enter] to return to menu \n\n " + read -rp " > " + + fi + + elif [[ $MainMenuChoice == "sa" ]] ; then + + function_snapshot_list + printColor "\n\n Give number of snapshot to use [enter] to return to menu " + SnapNumber= + + printf "\n\n" + read -rp " > " SnapNumber + printf "\n\n" + + if [[ $SnapNumber ]]; then + + quickemu -vm "$VM_Conf_File" --snapshot apply "$SnapNumber" + + printf "\n\n May take a moment .... \n\n" + printColor "\n\n Snapshot %s has been applied. \n\n" "$SnapNumber " + + fi + + fi + +done + + +# vim:tabstop=2:shiftwidth=2:expandtab + +## \ No newline at end of file diff --git a/quickget b/quickget index 1abb77f..b03b5ab 100755 --- a/quickget +++ b/quickget @@ -49,6 +49,7 @@ function pretty_name() { kolibrios) PRETTY_NAME="KolibriOS";; linuxmint) PRETTY_NAME="Linux Mint";; lmde) PRETTY_NAME="Linux Mint Debian Edition";; + mageia) PRETTY_NAME="Mageia";; mxlinux) PRETTY_NAME="MX Linux";; netboot) PRETTY_NAME="netboot.xyz";; netbsd) PRETTY_NAME="NetBSD";; @@ -59,7 +60,10 @@ function pretty_name() { oraclelinux) PRETTY_NAME="Oracle Linux";; popos) PRETTY_NAME="Pop!_OS";; reactos) PRETTY_NAME="ReactOS";; + rebornos) PRETTY_NAME="RebornOS";; rockylinux) PRETTY_NAME="Rocky Linux";; + truenas-core) PRETTY_NAME="TrueNAS Core";; + truenas-scale) PRETTY_NAME="TrueNAS Scale";; ubuntu-budgie) PRETTY_NAME="Ubuntu Budgie";; ubuntukylin) PRETTY_NAME="Ubuntu Kylin";; ubuntu-mate) PRETTY_NAME="Ubuntu MATE";; @@ -188,6 +192,7 @@ function os_support() { kubuntu \ linuxmint \ lmde \ + mageia \ manjaro \ mxlinux \ netboot \ @@ -200,10 +205,13 @@ function os_support() { oraclelinux \ popos \ reactos \ + rebornos \ rockylinux \ slackware \ solus \ tails \ + truenas-core \ + truenas-scale \ ubuntu \ ubuntu-budgie \ ubuntukylin \ @@ -217,7 +225,7 @@ function os_support() { } function releases_alma() { - echo 8.6 8.7 9.0 9.1-beta-1 + echo 8.6 8.7 9.0 9.1 } function editions_alma() { @@ -253,7 +261,7 @@ function editions_arcolinux() { } function releases_cachyos() { - echo 220919 221023 + echo 230121 } function editions_cachyos() { @@ -288,17 +296,22 @@ function releases_devuan() { } function releases_dragonflybsd() { - echo 6.2.1 + echo 6.4.0 } function releases_elementary() { - echo 6.1 + echo 7.0 } function releases_endeavouros() { echo apollo_22_1 \ + artemis-22_6 \ + artemis_neo_22_7 \ + artemis_neo_22_8 \ + artemis_nova_22_9 \ atlantis-21_4 \ - atlantis_neo-21_5 + atlantis_neo-21_5 \ + cassini_22_12 } function releases_fedora() { @@ -357,7 +370,7 @@ function editions_ghostbsd() { } function releases_haiku() { - echo r1beta3 + echo r1beta3 r1beta4 } function editions_haiku() { @@ -377,7 +390,7 @@ function releases_kolibrios() { } function releases_linuxmint(){ - echo 20.2 20.3 21 + echo 20.2 20.3 21 21.1 } function editions_linuxmint(){ @@ -391,8 +404,16 @@ function releases_lmde(){ echo 5 } +function releases_mageia(){ + echo 8 +} + +function editions_mageia(){ + echo Plasma GNOME Xfce +} + function releases_mxlinux(){ - echo 21.2.1 + echo 21.3 } function editions_mxlinux(){ @@ -422,7 +443,7 @@ function releases_netbsd() { } function releases_nixos(){ - echo 21.05 21.11 22.05 + echo 21.05 21.11 22.05 22.11 } function editions_nixos(){ @@ -454,8 +475,18 @@ function releases_reactos() { echo latest } +function releases_rebornos() { + echo latest +} + +function get_rebornos() { + local ISO=$(curl -s 'https://www.rebornos.org/download/' | grep -ohE 'https://pub-cb7a4d4f7a974896b3bf40c52d1defbc.r2.dev/RebornOS-ISO/(rebornos_xfce_minimal|rebornos_iso)-[0-9]{4}.[0-9]{2}.[0-9]{2}-x86_64.iso' | tail -n1) + local HASH=$(curl -s 'https://www.rebornos.org/download/' | grep -ozP 'Checksum MD5:.*[0-9a-fA-F]{32}' | grep -zoP '[0-9a-fA-F]{32}' | cut -d '' -f1) + echo "${ISO} ${HASH}" +} + function releases_rockylinux() { - echo 8.3 8.4 8.5 9.0 + echo 8.3 8.4 8.5 9.0 9.1 } # Rocky have renamed dvd1 -> dvd at 9.0 @@ -480,6 +511,21 @@ function releases_tails() { echo stable } +function releases_truenas() { + if [[ $OS == truenas ]] ; then + echo "ERROR! The supported TrueNAS OS values are truenas-core or truenas-scale" + exit 1; + fi + } + +function releases_truenas-core() { + echo 12.0 13.0 +} + +function releases_truenas-scale() { + echo 22.02 22.12 +} + function releases_ubuntu() { local LTS_SUPPORT="14.04 16.04 18.04 20.04 22.04" local INTERIM_SUPPORT="22.10" @@ -506,7 +552,7 @@ function releases_ubuntu() { daily-live \ daily-canary \ ; - + else echo ${LTS_SUPPORT} \ ${INTERIM_SUPPORT} \ @@ -749,6 +795,9 @@ function make_vm_config() { reactos) GUEST="reactos" IMAGE_TYPE="iso";; + truenas*) + GUEST="truenas" + IMAGE_TYPE="iso";; windows) GUEST="windows" IMAGE_TYPE="iso";; @@ -779,7 +828,7 @@ EOF # OS specific tweaks case ${OS} in - alma|centos-stream|oraclelinux|rockylinux) + alma|centos-stream|oraclelinux|popos|rockylinux) echo "disk_size=\"32G\"" >> "${CONF_FILE}";; batocera) echo "disk_size=\"8G\"" >> "${CONF_FILE}";; @@ -799,6 +848,14 @@ EOF echo "disk_size=\"2G\"" >> "${CONF_FILE}" echo "ram=\"128M\"" >> "${CONF_FILE}" ;; + truenas-scale|truenas-core) + echo + echo "boot=\"legacy\"" >> "${CONF_FILE}" + # the rest is non-functional + # echo "bootdrive_size=\"5G\"" >> "${CONF_FILE}" # boot drive + # echo "1stdrive_size=\"20G\"" >> "${CONF_FILE}" # for testing + # echo "2nddrive_size=\"20G\"" >> "${CONF_FILE}" # again, for testing + ;; zorin) case ${EDITION} in education64|edulite64) @@ -1032,7 +1089,14 @@ function get_dragonflybsd() { function get_elementary() { local HASH="" - local ISO="elementaryos-${RELEASE}-stable.20211218-rc.iso" + case ${RELEASE} in + 6.2) + local ISO="elementaryos-${RELEASE}-stable.20211218-rc.iso" + ;; + 7.0) + local ISO="elementaryos-${RELEASE}-stable.20230129rc.iso" + ;; + esac local URL="https://ams3.dl.elementary.io/download" echo "${URL}/$(date +%s | base64)/${ISO} ${HASH}" } @@ -1278,6 +1342,13 @@ function get_macos() { make_vm_config RecoveryImage.img } +function get_mageia() { + local EDITION="${1:-}" + local ISO=$(wget -q https://www.mageia.org/en/downloads/get/?q="Mageia-${RELEASE}-Live-${EDITION}-x86_64.iso" -O- | grep 'click here'| grep -o 'href=.*\.iso'|cut -d\" -f2) + local HASH=$(wget -q -O- "${ISO}.sha512" | cut -d' ' -f1) + echo "${ISO} ${HASH}" +} + function get_manjaro() { local HASH="" local ISO="" @@ -1406,7 +1477,7 @@ function get_rockylinux() { local URL="" case ${RELEASE} in - 9.0) URL="https://download.rockylinux.org/pub/rocky/${RELEASE}/isos/x86_64";; + 9.1) URL="https://download.rockylinux.org/pub/rocky/${RELEASE}/isos/x86_64";; *) URL="http://dl.rockylinux.org/vault/rocky/${RELEASE}/isos/x86_64/";; esac HASH=$(wget -q -O- "${URL}/CHECKSUM" | grep "SHA256" | grep "${ISO})" | cut -d' ' -f4) @@ -1443,6 +1514,29 @@ function get_tails() { echo "${URL} ${HASH}" } +function get_truenas-scale() { + local ISO="" + local URL="" + + local DLINFO="https://www.truenas.com/download-truenas-scale/" + + URL=$(wget -q ${DLINFO} -O- | grep -o "\"https://.*${RELEASE}.*\.iso\""|cut -d\" -f2) + HASH=$(wget -q ${URL}.sha256 -O- | cut -d' ' -f1 ) + + echo "${URL} ${HASH}" +} + +function get_truenas-core() { + local ISO="" + local URL="" + + local DLINFO="https://www.truenas.com/download-truenas-core/" + URL=$(wget -q ${DLINFO} -O- | grep -o "\"https://.*${RELEASE}.*\.iso\""|cut -d\" -f2) + HASH=$(wget -q ${URL}.sha256 -O- | cut -d' ' -f1) + + echo "${URL} ${HASH}" +} + function get_ubuntu() { local ISO="" local HASH="" @@ -1813,12 +1907,19 @@ function dbg_windows() { # Adapted from https://gist.github.com/hongkongkiwi/15a5bf16437315df256c118c163607cb function get_windows() { + # Use the API to automatically download a Windows .iso image + # The API we were using is unmaintained and not currently functional + # 0 : Prompt for a manual ISO download + # 1 : Use the API for automated download + local API_GUIDED_DOWNLOAD=0 + local ARCH="x64" local INDEX=0 local LANG_CODE="en" local LANG_EDITION="${1}" local LATEST_WINDOWS_VERSION="" local WINDOWS_NAME="" + local WINDOWS_ISO_URL="" local VERSION_ID="" local EDITION_ID="" local LANGUAGE_ID="" @@ -1828,59 +1929,72 @@ function get_windows() { local DOWNLOAD_ID="" local DOWNLOAD_URL="" - # Ignore the most recent Windows 10 release for now. - case ${RELEASE} in - 10) INDEX=0;; - 11) INDEX=0;; - esac - - echo "Getting Windows ${RELEASE} URL..." - WINDOWS_VERSIONS=$(wget -4 -q -O- "https://tb.rg-adguard.net/php/get_version.php?type_id=1" | jq '.versions | sort_by(-(.version_id | tonumber))') - dbg_windows "${WINDOWS_VERSIONS}" - LATEST_WINDOWS_VERSION=$(echo "${WINDOWS_VERSIONS}" | jq -c 'map(select(.name | contains("Windows '"${RELEASE}"'")))['${INDEX}']') - dbg_windows "${LATEST_WINDOWS_VERSION}" - WINDOWS_NAME=$(echo "${LATEST_WINDOWS_VERSION}" | jq -r .name) - dbg_windows "${WINDOWS_NAME}" - VERSION_ID=$(echo "${LATEST_WINDOWS_VERSION}" | jq -r .version_id) - dbg_windows "${VERSION_ID}" + if [ ${API_GUIDED_DOWNLOAD} -eq 1 ]; then + # Ignore the most recent Windows 10 release for now. + case ${RELEASE} in + 10) INDEX=0;; + 11) INDEX=0;; + esac - case ${RELEASE} in - 8) EDITION_ID=$(wget -4 -q -O- "https://tb.rg-adguard.net/php/get_edition.php?version_id=${VERSION_ID}&lang=name_${LANG_CODE}" | jq -r '.editions[] | select(.name_'${LANG_CODE}'=="Windows 8.1 Pro + Core").edition_id');; - 10|11) EDITION_ID=$(wget -4 -q -O- "https://tb.rg-adguard.net/php/get_edition.php?version_id=${VERSION_ID}&lang=name_${LANG_CODE}" | jq -r '.editions[] | select(.name_'${LANG_CODE}'=="Windows '"${RELEASE}"'").edition_id');; - esac - dbg_windows "${EDITION_ID}" - - LANGUAGE_ID=$(wget -4 -q -O- "https://tb.rg-adguard.net/php/get_language.php?edition_id=${EDITION_ID}&lang=name_${LANG_CODE}" | jq -r '.languages[] | select(.name_'${LANG_CODE}'=="'"${LANG_EDITION}"'").language_id') - dbg_windows "${LANGUAGE_ID}" - ARCH_INFO=$(wget -4 -q -O- "https://tb.rg-adguard.net/php/get_arch.php?language_id=${LANGUAGE_ID}") - dbg_windows "${ARCH_INFO}" - FILE_NAME=$(echo "${ARCH_INFO}" | jq -r '.archs[] | select(.name | contains("'${ARCH}'")).name') - dbg_windows "${FILE_NAME}" - ARCH_ID=$(echo "${ARCH_INFO}" | jq -r '.archs[] | select(.name | contains("'${ARCH}'")).arch_id') - dbg_windows "${ARCH_ID}" - DOWNLOAD_INFO=$(wget -4 -q -O- "https://tb.rg-adguard.net/dl.php?fileName=${ARCH_ID}&lang=en") - dbg_windows "${DOWNLOAD_INFO}" - DOWNLOAD_SHA1=$(echo "${DOWNLOAD_INFO}" | sed -e 's/<[^>]*>//g' | grep -o -P '(?<=SHA1: ).*(?= expire)' | sed 's/Link//') - dbg_windows "${DOWNLOAD_SHA1}" - DOWNLOAD_ID=$(echo "${DOWNLOAD_INFO}" | grep -oP '(?<=https:\/\/tb\.rg-adguard\.net/dl\.php\?go=)[0-9a-z]+') - dbg_windows "${DOWNLOAD_ID}" - REDIRECT_URL="https://tb.rg-adguard.net/dl.php?go=${DOWNLOAD_ID}" - dbg_windows "${REDIRECT_URL}" - DOWNLOAD_URL=$(curl --head --silent --write-out "%{redirect_url}\n" --output /dev/null "${REDIRECT_URL}") - dbg_windows "${DOWNLOAD_URL}" - - MS_BASE_URL="https://software.download.prss.microsoft.com/" - if [[ ! ${DOWNLOAD_URL} =~ ^${MS_BASE_URL} ]]; then - echo "Download URL not leading to Microsoft CDN" - exit 1 - fi + echo "Getting Windows ${RELEASE} URL..." + WINDOWS_VERSIONS=$(wget -4 -q -O- "https://tb.rg-adguard.net/php/get_version.php?type_id=1" | jq '.versions | sort_by(-(.version_id | tonumber))') + dbg_windows "${WINDOWS_VERSIONS}" + LATEST_WINDOWS_VERSION=$(echo "${WINDOWS_VERSIONS}" | jq -c 'map(select(.name | contains("Windows '"${RELEASE}"'")))['${INDEX}']') + dbg_windows "${LATEST_WINDOWS_VERSION}" + WINDOWS_NAME=$(echo "${LATEST_WINDOWS_VERSION}" | jq -r .name) + dbg_windows "${WINDOWS_NAME}" + VERSION_ID=$(echo "${LATEST_WINDOWS_VERSION}" | jq -r .version_id) + dbg_windows "${VERSION_ID}" + + case ${RELEASE} in + 8) EDITION_ID=$(wget -4 -q -O- "https://tb.rg-adguard.net/php/get_edition.php?version_id=${VERSION_ID}&lang=name_${LANG_CODE}" | jq -r '.editions[] | select(.name_'${LANG_CODE}'=="Windows 8.1 Pro + Core").edition_id');; + 10|11) EDITION_ID=$(wget -4 -q -O- "https://tb.rg-adguard.net/php/get_edition.php?version_id=${VERSION_ID}&lang=name_${LANG_CODE}" | jq -r '.editions[] | select(.name_'${LANG_CODE}'=="Windows '"${RELEASE}"'").edition_id');; + esac + dbg_windows "${EDITION_ID}" + + LANGUAGE_ID=$(wget -4 -q -O- "https://tb.rg-adguard.net/php/get_language.php?edition_id=${EDITION_ID}&lang=name_${LANG_CODE}" | jq -r '.languages[] | select(.name_'${LANG_CODE}'=="'"${LANG_EDITION}"'").language_id') + dbg_windows "${LANGUAGE_ID}" + ARCH_INFO=$(wget -4 -q -O- "https://tb.rg-adguard.net/php/get_arch.php?language_id=${LANGUAGE_ID}") + dbg_windows "${ARCH_INFO}" + FILE_NAME=$(echo "${ARCH_INFO}" | jq -r '.archs[] | select(.name | contains("'${ARCH}'")).name') + dbg_windows "${FILE_NAME}" + ARCH_ID=$(echo "${ARCH_INFO}" | jq -r '.archs[] | select(.name | contains("'${ARCH}'")).arch_id') + dbg_windows "${ARCH_ID}" + DOWNLOAD_INFO=$(wget -4 -q -O- "https://tb.rg-adguard.net/dl.php?fileName=${ARCH_ID}&lang=en") + dbg_windows "${DOWNLOAD_INFO}" + DOWNLOAD_SHA1=$(echo "${DOWNLOAD_INFO}" | sed -e 's/<[^>]*>//g' | grep -o -P '(?<=SHA1: ).*(?= expire)' | sed 's/Link//') + dbg_windows "${DOWNLOAD_SHA1}" + DOWNLOAD_ID=$(echo "${DOWNLOAD_INFO}" | grep -oP '(?<=https:\/\/tb\.rg-adguard\.net/dl\.php\?go=)[0-9a-z]+') + dbg_windows "${DOWNLOAD_ID}" + REDIRECT_URL="https://tb.rg-adguard.net/dl.php?go=${DOWNLOAD_ID}" + dbg_windows "${REDIRECT_URL}" + DOWNLOAD_URL=$(curl --head --silent --write-out "%{redirect_url}\n" --output /dev/null "${REDIRECT_URL}") + dbg_windows "${DOWNLOAD_URL}" + + MS_BASE_URL="https://software.download.prss.microsoft.com/" + if [[ ! ${DOWNLOAD_URL} =~ ^${MS_BASE_URL} ]]; then + echo "Download URL not leading to Microsoft CDN" + exit 1 + fi - echo "Downloading ${WINDOWS_NAME}..." - web_get "${DOWNLOAD_URL}" "${VM_PATH}" "${FILE_NAME}" + echo "Downloading ${WINDOWS_NAME}..." + web_get "${DOWNLOAD_URL}" "${VM_PATH}" "${FILE_NAME}" - # Windows 10 doesn't include a SHA1, so only check the integrity if the SHA1 is available. - if [ -n "${DOWNLOAD_SHA1}" ]; then - check_hash "${FILE_NAME}" "${DOWNLOAD_SHA1}" + # Windows 10 doesn't include a SHA1, so only check the integrity if the SHA1 is available. + if [ -n "${DOWNLOAD_SHA1}" ]; then + check_hash "${FILE_NAME}" "${DOWNLOAD_SHA1}" + fi + else + case ${RELEASE} in + 10) WINDOWS_ISO_URL="https://www.microsoft.com/software-download/windows10";; + 11) WINDOWS_ISO_URL="https://www.microsoft.com/software-download/windows11";; + esac + echo "######################################################################" + echo "# Download a Windows ${RELEASE} .iso image from:" + echo "# - ${WINDOWS_ISO_URL}" + echo "# Put the .iso image in the ${VM_PATH} directory and rename" + echo "# it to windows-${RELEASE}.iso." + echo "######################################################################" fi web_get "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso" "${VM_PATH}" @@ -1897,7 +2011,11 @@ function get_windows() { mkisofs -quiet -l -o "${VM_PATH}/unattended.iso" "${VM_PATH}/unattended/" ;; esac - make_vm_config "${FILE_NAME}" "virtio-win.iso" + + case "${API_GUIDED_DOWNLOAD}" in + 0) make_vm_config "windows-${RELEASE}.iso" "virtio-win.iso";; + 1) make_vm_config "${FILE_NAME}" "virtio-win.iso";; + esac } create_vm() { @@ -1995,6 +2113,7 @@ if [ -n "${2}" ]; then fi fi + VM_PATH="${OS}-${RELEASE}-${EDITION}" validate_release "releases_${OS}" create_vm "$("get_${OS}" "${EDITION}")"