Compare commits

...

38 Commits

Author SHA1 Message Date
Martin Wimpress 6c2aad8e4d chore: remove Whonix from os_info(); it doesn't have any generators 2024-05-08 15:04:35 +01:00
Martin Wimpress 80230f8469 style: correct HoloISO pretty name 2024-05-08 15:04:35 +01:00
Martin Wimpress e005a55268 style: correct Crunchbangplusplus pretty name 2024-05-08 15:04:35 +01:00
Martin Wimpress e2b39bf826 style: correct AlmaLinux pretty name 2024-05-08 15:04:35 +01:00
Martin Wimpress c84745b49f fix(quickget): make --check work for releases and editions 2024-05-08 15:04:35 +01:00
Martin Wimpress d46482abf9 fix(quickget): resolve shellcheck SC2004 notice
https://www.shellcheck.net/wiki/SC2004
2024-05-08 15:04:35 +01:00
Martin Wimpress 3832fe731c fix(quickget): update get_manjaro() to support new sway release 2024-05-08 15:04:35 +01:00
Martin Wimpress 4ebb74a993 fix(quickget): resolve some shellcheck SC2086 notices
https://www.shellcheck.net/wiki/SC2086
2024-05-08 15:04:35 +01:00
Martin Wimpress fe2dc839ed fix(quickemu): correct shellcheck SC2207 warnings
https://www.shellcheck.net/wiki/SC2207
2024-05-08 15:04:35 +01:00
Martin Wimpress 252f83c076 fix(quickemu): remove unused variable monitor_cmd SC2034
https://www.shellcheck.net/wiki/SC2034
2024-05-08 15:04:35 +01:00
Martin Wimpress 394f955870 fix(quickemu): resolve shellcheck SC2069 warnings
https://www.shellcheck.net/wiki/SC2069
2024-05-08 15:04:35 +01:00
Martin Wimpress 1596179ca5 fix(quickemu): resolve shellcheck SC2236
https://www.shellcheck.net/wiki/SC2236
2024-05-08 15:04:35 +01:00
Martin Wimpress 6ffa1692d6 fix(quickemu): resolve shellcheck SC2206 warnings
https://www.shellcheck.net/wiki/SC2206
2024-05-08 15:04:35 +01:00
Martin Wimpress aefc99efce fix(quickemu): resolve shellcheck SC2155 warnings
https://www.shellcheck.net/wiki/SC2155
2024-05-08 15:04:35 +01:00
Martin Wimpress 3292ce76ea fix(quickemu): disable shellcheck SC2054 and SC2140 warning
https://www.shellcheck.net/wiki/SC2054
https://www.shellcheck.net/wiki/SC2140
2024-05-08 15:04:35 +01:00
Martin Wimpress 9104bdba1d fix(quickget): disable SC2317 as many functions are called indirectly
https://www.shellcheck.net/wiki/SC2317
2024-05-08 15:04:35 +01:00
Martin Wimpress 7eac685f25 fix(quickget): disable shellcheck SC2207 warnings for ubuntu releases
https://www.shellcheck.net/wiki/SC2207
2024-05-08 15:04:35 +01:00
Martin Wimpress 7cfdfd0cec fix(quickget): make editions parsing shellcheck SC2207 compliant
https://www.shellcheck.net/wiki/SC2207
2024-05-08 15:04:35 +01:00
Martin Wimpress e52ba1fc60 fix(quickget): make show_os_info() shellcheck compliant
https://www.shellcheck.net/wiki/SC2086
2024-05-08 15:04:35 +01:00
Martin Wimpress 77fe26975d fix(quickget): disable shellcheck SC2317 for cleanup()
https://www.shellcheck.net/wiki/SC2317
2024-05-08 15:04:35 +01:00
Martin Wimpress ca87ff3b58 refactor(quickget): remove unnecessary string literals 2024-05-08 15:04:35 +01:00
Martin Wimpress b342e0ecb7 style(quickget): make not supported release and edition output consistent 2024-05-08 15:04:35 +01:00
Martin Wimpress e1a46b9b5a refactor(quickget): remove single use function error_not_supported_os() 2024-05-08 15:04:35 +01:00
Martin Wimpress 46b981728d fix(quickget): correct shellcheck SC2076 warnings
https://www.shellcheck.net/wiki/SC2076
2024-05-08 15:04:35 +01:00
Martin Wimpress 805eae9bd5 fix(quickget): make open_homepage() shellcheck compliant (SC2034)
https://www.shellcheck.net/wiki/SC2034
2024-05-08 15:04:35 +01:00
Martin Wimpress 1e05e7a3b2 refactor(quickget): special case image processing shellcheck compliant 2024-05-08 15:04:35 +01:00
Martin Wimpress 31de07fb9c docs(README.md): sign post the documentation for adding a new OS 2024-05-08 15:04:35 +01:00
Martin Wimpress f618ec3986 docs(README.md): update social links 2024-05-08 15:04:35 +01:00
Martin Wimpress ca70e88330 style: update help_message() to remove shorthand arguments 2024-05-08 15:04:35 +01:00
Martin Wimpress c981e8b8e5 style(quickget): drop shorthand arguments for consistency
quickemu has long hand command line arguments only. This commit removes the short hand arguments from the expanded capabilities introduced in quickget 4.9.3, so that both tools have a consistent user experience.
2024-05-08 15:04:35 +01:00
Martin Wimpress e0e23864c8 docs: replace screenshot with asciinema 2024-05-08 15:04:35 +01:00
Martin Wimpress 1637ee7fca chore(quickget): remove how-to from code; added to the wiki
https://github.com/quickemu-project/quickemu/wiki/06-Advanced-quickget-features#adding-a-new-os-to-quickget
2024-05-08 15:04:35 +01:00
Martin Wimpress ef9390d43c chore(quickget): remove obsolete logic for guix 2024-05-08 15:04:35 +01:00
Martin Wimpress 7e12bac3e6 style: add braces around variable names 2024-05-08 15:04:35 +01:00
Martin Wimpress f44222ad6f fix(shellcheck): add missing local variable in get_truenas-scale() 2024-05-08 15:04:35 +01:00
Martin Wimpress d408e15f51 refactor: simplify get_tuxedo-os() 2024-05-08 15:04:35 +01:00
Martin Wimpress 3ca857ace8 chore(quickget): remove obsolete daily check from ubuntu 2024-05-08 15:04:35 +01:00
Martin Wimpress ffbace0f4a fix(quickget): add daily-live to ubuntu-server 2024-05-08 15:04:35 +01:00
4 changed files with 175 additions and 161 deletions

BIN
.github/screenshot.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -5,14 +5,14 @@
**Quickly create and run optimised Windows, macOS and Linux virtual machines:**
<img src=".github/screenshot.png" alt="Quickemu Screenshot" />
**Made with 💝 for <img src=".github/tux.png" align="top" width="24" alt="Tux (Linux)"/>**
We have a Discord for this project:
[![Discord](https://img.shields.io/discord/712850672223125565?color=0C306A&label=WimpysWorld%20Discord&logo=Discord&logoColor=ffffff&style=flat-square)](https://discord.gg/sNmz3uw)
</div>
<p align="center">
&nbsp;<a href="https://wimpysworld.io/discord" target="_blank"><img alt="Discord" src="https://img.shields.io/discord/712850672223125565?style=for-the-badge&logo=discord&logoColor=%23ffffff&label=Discord&labelColor=%234253e8&color=%23e4e2e2"></a>&nbsp;
&nbsp;<a href="https://fosstodon.org/@wimpy" target="_blank"><img alt="Mastodon" src="https://img.shields.io/badge/Mastodon-6468fa?style=for-the-badge&logo=mastodon&logoColor=%23ffffff"></a>&nbsp;
&nbsp;<a href="https://twitter.com/m_wimpress" target="_blank"><img alt="Twitter" src="https://img.shields.io/badge/Twitter-303030?style=for-the-badge&logo=x&logoColor=%23ffffff"></a>&nbsp;
&nbsp;<a href="https://linkedin.com/in/martinwimpress" target="_blank"><img alt="LinkedIn" src="https://img.shields.io/badge/LinkedIn-1667be?style=for-the-badge&logo=linkedin&logoColor=%23ffffff"></a>&nbsp;
</p>
# Introduction
@ -85,6 +85,10 @@ quickemu --vm nixos-unstable.conf
- Execute `quickget` (with no arguments) to see a list of all the
supported operating systems.
## Demo
<div align="center"><a href="https://asciinema.org/a/658148?autoplay=1" target="_blank"><img src="https://asciinema.org/a/658148.svg" /></a></div>
# Documentation
The wiki describes how to get up and running with Quickemu and also
@ -129,6 +133,7 @@ We welcome contributions to Quickemu.
- Submit [Quickemu Pull
requests](https://github.com/quickemu-project/quickemu/pulls) to fix
bugs 🐞 or add new features ✨
- Follow our [guide to adding a new OS to quickget](https://github.com/quickemu-project/quickemu/wiki/06-Advanced-quickget-features#adding-a-new-os-to-quickget)
- Commit messages must [conform to the Conventional Commits
specification](https://www.conventionalcommits.org/).
specification](https://www.conventionalcommits.org/)
- [Sponsor the project](https://github.com/sponsors/flexiondotorg) 💖

View File

@ -237,6 +237,7 @@ function vm_boot() {
local OSK=""
local SOUND=""
local SMM="${SMM:-off}"
local TEMP_PORT=""
local USB_HOST_PASSTHROUGH_CONTROLLER="qemu-xhci"
local VGA=""
local VIDEO=""
@ -400,6 +401,7 @@ function vm_boot() {
if [ -n "${EFI_CODE}" ] || [ ! -e "${EFI_CODE}" ]; then
case ${secureboot} in
on)
# shellcheck disable=SC2054,SC2140
ovmfs=("/usr/share/OVMF/OVMF_CODE_4M.secboot.fd","/usr/share/OVMF/OVMF_VARS_4M.fd" \
"/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd","/usr/share/edk2/ovmf/OVMF_VARS.fd" \
"/usr/share/OVMF/x64/OVMF_CODE.secboot.fd","/usr/share/OVMF/x64/OVMF_VARS.fd" \
@ -410,6 +412,7 @@ function vm_boot() {
)
;;
*)
# shellcheck disable=SC2054,SC2140
ovmfs=("/usr/share/OVMF/OVMF_CODE_4M.fd","/usr/share/OVMF/OVMF_VARS_4M.fd" \
"/usr/share/edk2/ovmf/OVMF_CODE.fd","/usr/share/edk2/ovmf/OVMF_VARS.fd" \
"/usr/share/OVMF/OVMF_CODE.fd","/usr/share/OVMF/OVMF_VARS.fd" \
@ -443,7 +446,7 @@ function vm_boot() {
echo " Please install OVMF firmware."
exit 1
fi
if [ ! -z "${EFI_EXTRA_VARS}" ]; then
if [ -n "${EFI_EXTRA_VARS}" ]; then
if [ ! -e "${EFI_EXTRA_VARS}" ]; then
echo " - EFI: ERROR! EFI_EXTRA_VARS file ${EFI_EXTRA_VARS} does not exist."
exit 1
@ -992,7 +995,8 @@ function vm_boot() {
# Only enable SPICE is using SPICE display
if [ "${OUTPUT}" == "none" ] || [ "${OUTPUT}" == "spice" ] || [ "${OUTPUT}" == "spice-app" ]; then
args+=(-spice ${SPICE}
# shellcheck disable=SC2054
args+=(-spice "${SPICE}"
-device virtio-serial-pci
-chardev socket,id=agent0,path="${VMDIR}/${VMNAME}-agent.sock",server=on,wait=off
-device virtserialport,chardev=agent0,name=org.qemu.guest_agent.0
@ -1002,9 +1006,10 @@ function vm_boot() {
-device virtserialport,chardev=webdav0,name=org.spice-space.webdav.0)
fi
# shellcheck disable=SC2054
args+=(-device virtio-rng-pci,rng=rng0
-object rng-random,id=rng0,filename=/dev/urandom
-device ${USB_HOST_PASSTHROUGH_CONTROLLER},id=spicepass
-device "${USB_HOST_PASSTHROUGH_CONTROLLER}",id=spicepass
-chardev spicevmc,id=usbredirchardev1,name=usbredir
-device usb-redir,chardev=usbredirchardev1,id=usbredirdev1
-chardev spicevmc,id=usbredirchardev2,name=usbredir
@ -1016,6 +1021,7 @@ function vm_boot() {
)
if "${QEMU}" -chardev spicevmc,id=ccid,name= 2>&1 | grep -q smartcard; then
# shellcheck disable=SC2054
args+=(-chardev spicevmc,id=ccid,name=smartcard
-device ccid-card-passthru,chardev=ccid)
else
@ -1025,8 +1031,10 @@ function vm_boot() {
# setup usb-controller
[ -z "${USB_CONTROLLER}" ] && USB_CONTROLLER="$usb_controller"
if [ "${USB_CONTROLLER}" == "ehci" ]; then
# shellcheck disable=SC2054
args+=(-device usb-ehci,id=input)
elif [ "${USB_CONTROLLER}" == "xhci" ]; then
# shellcheck disable=SC2054
args+=(-device qemu-xhci,id=input)
elif [ -z "${USB_CONTROLLER}" ] || [ "${USB_CONTROLLER}" == "none" ]; then
# add nothing
@ -1039,8 +1047,10 @@ function vm_boot() {
# @INFO: must be set after usb-controller
[ -z "${KEYBOARD}" ] && KEYBOARD="$keyboard"
if [ "${KEYBOARD}" == "usb" ]; then
# shellcheck disable=SC2054
args+=(-device usb-kbd,bus=input.0)
elif [ "${KEYBOARD}" == "virtio" ]; then
# shellcheck disable=SC2054
args+=(-device virtio-keyboard)
elif [ "${KEYBOARD}" == "ps2" ] || [ -z "${KEYBOARD}" ]; then
# add nothing, default is ps/2 keyboard
@ -1053,7 +1063,7 @@ function vm_boot() {
# @INFO: When using the VNC display, you must use the -k parameter to set the keyboard layout if you are not using en-us.
[ -z "${KEYBOARD_LAYOUT}" ] && KEYBOARD_LAYOUT="$keyboard_layout"
if [ -n "${KEYBOARD_LAYOUT}" ]; then
args+=(-k ${KEYBOARD_LAYOUT})
args+=(-k "${KEYBOARD_LAYOUT}")
fi
# FIXME: Check for device availability. qemu will fail to start otherwise
@ -1067,10 +1077,13 @@ function vm_boot() {
# @INFO: must be set after usb-controller
[ -z "${MOUSE}" ] && MOUSE="$mouse"
if [ "${MOUSE}" == "usb" ]; then
# shellcheck disable=SC2054
args+=(-device usb-mouse,bus=input.0)
elif [ "${MOUSE}" == "tablet" ]; then
# shellcheck disable=SC2054
args+=(-device usb-tablet,bus=input.0)
elif [ "${MOUSE}" == "virtio" ]; then
# shellcheck disable=SC2054
args+=(-device virtio-mouse)
elif [ "${MOUSE}" == "ps2" ] || [ -z "${MOUSE}" ]; then
# add nothing, default is ps/2 mouse
@ -1189,6 +1202,7 @@ function vm_boot() {
args+=(-drive if=ide,index=0,media=disk,file="${disk_img}")
elif [ "${guest_os}" == "windows-server" ]; then
# shellcheck disable=SC2054,SC2206
args+=(-device ide-hd,drive=SystemDisk
-drive id=SystemDisk,if=none,format=qcow2,file="${disk_img}" ${STATUS_QUO})
@ -1239,16 +1253,18 @@ function vm_boot() {
echo " - Monitor: (off)"
elif [ "${MONITOR}" == "telnet" ]; then
# Find a free port to expose monitor-telnet to the guest
local temp_port="$(get_port ${MONITOR_TELNET_PORT} 9)"
if [ -z "${temp_port}" ]; then
TEMP_PORT="$(get_port ${MONITOR_TELNET_PORT} 9)"
if [ -z "${TEMP_PORT}" ]; then
echo " - Monitor: All Monitor-Telnet ports have been exhausted."
else
MONITOR_TELNET_PORT="${temp_port}"
args+=(-monitor telnet:${MONITOR_TELNET_HOST}:${MONITOR_TELNET_PORT},server,nowait)
MONITOR_TELNET_PORT="${TEMP_PORT}"
# shellcheck disable=SC2054
args+=(-monitor telnet:"${MONITOR_TELNET_HOST}:${MONITOR_TELNET_PORT}",server,nowait)
echo " - Monitor: On host: telnet ${MONITOR_TELNET_HOST} ${MONITOR_TELNET_PORT}"
echo "monitor-telnet,${MONITOR_TELNET_PORT},${MONITOR_TELNET_HOST}" >> "${VMDIR}/${VMNAME}.ports"
fi
elif [ "${MONITOR}" == "socket" ]; then
# shellcheck disable=SC2054,SC2206
args+=(-monitor unix:${VM_MONITOR_SOCKETPATH},server,nowait)
echo " - Monitor: On host: nc -U \"${VM_MONITOR_SOCKETPATH}\""
echo " or : socat -,echo=0,icanon=0 unix-connect:${VM_MONITOR_SOCKETPATH}"
@ -1276,16 +1292,18 @@ function vm_boot() {
args+=(-serial none)
elif [ "${SERIAL}" == "telnet" ]; then
# Find a free port to expose serial-telnet to the guest
local temp_port="$(get_port ${SERIAL_TELNET_PORT} 9)"
if [ -z "${temp_port}" ]; then
TEMP_PORT="$(get_port ${SERIAL_TELNET_PORT} 9)"
if [ -z "${TEMP_PORT}" ]; then
echo " - Serial: All Serial-Telnet ports have been exhausted."
else
SERIAL_TELNET_PORT="${temp_port}"
SERIAL_TELNET_PORT="${TEMP_PORT}"
# shellcheck disable=SC2054,SC2206
args+=(-serial telnet:${SERIAL_TELNET_HOST}:${SERIAL_TELNET_PORT},server,nowait)
echo " - Serial: On host: telnet ${SERIAL_TELNET_HOST} ${SERIAL_TELNET_PORT}"
echo "serial-telnet,${SERIAL_TELNET_PORT},${SERIAL_TELNET_HOST}" >> "${VMDIR}/${VMNAME}.ports"
fi
elif [ "${SERIAL}" == "socket" ]; then
# shellcheck disable=SC2054,SC2206
args+=(-serial unix:${VM_SERIAL_SOCKETPATH},server,nowait)
echo " - Serial: On host: nc -U \"${VM_SERIAL_SOCKETPATH}\""
echo " or : socat -,echo=0,icanon=0 unix-connect:${VM_SERIAL_SOCKETPATH}"
@ -1298,6 +1316,7 @@ function vm_boot() {
EXTRA_ARGS="${extra_args}"
fi
if [ -n "${EXTRA_ARGS}" ]; then
# shellcheck disable=SC2206
args+=(${EXTRA_ARGS})
fi
@ -1468,9 +1487,12 @@ function parse_ports_from_file {
local FILE="${VMDIR}/${VMNAME}.ports"
# parse ports
local port_name=( $(cat "$FILE" | cut -d, -f1) )
local port_number=( $(cat "$FILE" | cut -d, -f2) )
local host_name=( $(cat "$FILE" | gawk 'FS="," {print $3,"."}') )
# shellcheck disable=SC2207
local port_name=( $(cat "${FILE}" | cut -d',' -f 1) )
# shellcheck disable=SC2207
local port_number=( $(cat "${FILE}" | cut -d',' -f 2) )
# shellcheck disable=SC2207
local host_name=( $(cat "${FILE}" | gawk 'FS="," {print $3,"."}') )
for ((i=0; i<${#port_name[@]}; i++)); do
if [ "${port_name[$i]}" == "ssh" ]; then
@ -1562,7 +1584,6 @@ public_dir=""
monitor="socket"
monitor_telnet_port="4440"
monitor_telnet_host="localhost"
monitor_cmd=""
serial="socket"
serial_telnet_port="6660"
serial_telnet_host="localhost"
@ -1675,7 +1696,7 @@ else
shift
shift;;
-screenpct|--screenpct)
if [ ! -z "${2##*[!0-9]*}" ] ; then
if [ -n "${2##*[!0-9]*}" ] ; then
if [[ ${2} -ge 25 && ${2} -lt 100 ]] ; then
SCREENPCT=${2}
else
@ -1924,7 +1945,7 @@ if [ -n "${VM}" ] && [ -e "${VM}" ]; then
VM_UP=0
if [ -r "${VMDIR}/${VMNAME}.pid" ]; then
VM_PID=$(head -c50 "${VMDIR}/${VMNAME}.pid")
kill -0 ${VM_PID} 2>&1 >/dev/null
kill -0 ${VM_PID} > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "VM already started!"
VM_UP=1

262
quickget
View File

@ -1,28 +1,10 @@
#!/usr/bin/env bash
# SC2317: Command appears to be unreachable. Check usage (or ignore if invoked indirectly).
# - https://www.shellcheck.net/wiki/SC2317
# - Disable globally because many functions are called indirectly
# shellcheck disable=SC2317
export LC_ALL=C
# Here the quick 'n dirty guide to adding a new OS to quickget
#
# 1. Update os_support() - add new OS, all lowercase
# 2. Update os_info() - Fill all posible fields for new OS (leave empty if no login, but | must stay same)
# Here is whats should be there...
# <OS name>) INFO="<OS nice name>|<OS based on>|<OS default login:pass if any>|<OS homepage>|<ABOUT>";;
# 4. Create a releases_newos() generator (required) outputs the current supported release versions (from newest)
# 5. Create a editions_newos() generator (optional) outputs the editions if new OS has multiple flavours/editions
# 6. Update make_vm_config() - add any *required* new OS tweaks
# 7. Create a get_newos() function - that does something like this: (Look at other OS)
# For cutting first field with hash you can use function `cut_1` instead of `cut -d' ' -f1``
#
#function get_newos() {
# local EDITION="${1:-}"
# local HASH=""
# local ISO="newos-${RELEASE}-${EDITION}-amd64.iso"
# local URL="https://www.newos.org/download/${RELEASE}/${EDITION}"
#
# HASH=$(web_pipe "${URL}/SHA512SUMS" | grep "${ISO}" | cut_1)
# echo "${URL}/${ISO} ${HASH}"
#}
function cleanup() {
if [ -n "$(jobs -p)" ]; then
kill "$(jobs -p)" 2>/dev/null
@ -40,7 +22,7 @@ function os_info() {
SIMPLE_NAME="${1}"
case ${SIMPLE_NAME} in
#name) INFO="PrettyName|BasedOf|Credentials|Homepage|Info";;
alma) INFO="Alma Linux|Fedora,RedHat|-|https://almalinux.org/|Community owned and governed, forever-free enterprise Linux distribution, focused on long-term stability, providing a robust production-grade platform. AlmaLinux OS is binary compatible with RHEL®.";;
alma) INFO="AlmaLinux|Fedora,RedHat|-|https://almalinux.org/|Community owned and governed, forever-free enterprise Linux distribution, focused on long-term stability, providing a robust production-grade platform. AlmaLinux OS is binary compatible with RHEL®.";;
alpine) INFO="Alpine Linux|Independent|-|https://alpinelinux.org/|Security-oriented, lightweight Linux distribution based on musl libc and busybox.";;
android) INFO="Android x86|Independent|-|https://www.android-x86.org/|Port Android Open Source Project to x86 platform.";;
antix) INFO="Antix|Debian|-|https://antixlinux.com/|Fast, lightweight and easy to install systemd-free linux live CD distribution based on Debian Stable for Intel-AMD x86 compatible systems.";;
@ -58,7 +40,7 @@ function os_info() {
cachyos) INFO="CachyOS|Arch|-|https://cachyos.org/|Designed to deliver lightning-fast speeds and stability, ensuring a smooth and enjoyable computing experience every time you use it.";;
centos-stream) INFO="CentOS Stream|Fedora,RedHat|-|https://www.centos.org/centos-stream/|Continuously delivered distro that tracks just ahead of Red Hat Enterprise Linux (RHEL) development, positioned as a midstream between Fedora Linux and RHEL.";;
chimeralinux) INFO="Chimera Linux|Independent|anon:chimera root:chimera|https://chimera-linux.org/|Modern, general-purpose non-GNU Linux distribution.";;
crunchbang++) INFO="#!++|Debian|-|https://www.crunchbangplusplus.org/|The classic minimal crunchbang feel, now with debian 12 bookworm.";;
crunchbang++) INFO="Crunchbangplusplus|Debian|-|https://www.crunchbangplusplus.org/|The classic minimal crunchbang feel, now with debian 12 bookworm.";;
debian) INFO="Debian|Independent|-|https://www.debian.org/|Complete Free Operating System with perfect level of ease of use and stability.";;
deepin) INFO="Deepin|Debian|-|https://www.deepin.org/|Beautiful UI design, intimate human-computer interaction, and friendly community environment make you feel at home.";;
devuan) INFO="Devuan|Debian|-|https://www.devuan.org/|Fork of Debian without systemd that allows users to reclaim control over their system by avoiding unnecessary entanglements and ensuring Init Freedom.";;
@ -77,7 +59,7 @@ function os_info() {
gnomeos) INFO="GNOME OS|Independent|-|https://os.gnome.org/|Alpha nightly bleeding edge distro of GNOME";;
guix) INFO="Guix|Independent|-|https://guix.gnu.org/|Distribution of the GNU operating system developed by the GNU Project—which respects the freedom of computer users.";;
haiku) INFO="Haiku|Independent|-|https://www.haiku-os.org/|Specifically targets personal computing. Inspired by the BeOS, Haiku is fast, simple to use, easy to learn and yet very powerful.";;
holoiso) INFO="SteamOS HoloISO|Arch,SteamOS|-|https://github.com/HoloISO/holoiso|Bring the Steam Decks SteamOS Holo redistribution and provide a close-to-official SteamOS experience.";;
holoiso) INFO="HoloISO|Arch,SteamOS|-|https://github.com/HoloISO/holoiso|Bring the Steam Decks SteamOS Holo redistribution and provide a close-to-official SteamOS experience.";;
kali) INFO="Kali|Debian|-|https://www.kali.org/|The most advanced Penetration Testing Distribution.";;
kdeneon) INFO="KDE Neon|Debian,Ubuntu|-|https://neon.kde.org/|Latest and greatest of KDE community software packaged on a rock-solid base.";;
kolibrios) INFO="KolibriOS|Independent|-|http://kolibrios.org/en/|Tiny yet incredibly powerful and fast operating system.";;
@ -133,7 +115,6 @@ function os_info() {
vanillaos) INFO="Vanilla OS|Debian,Ubuntu|-|https://vanillaos.org/|Designed to be a reliable and productive operating system for your daily work.";;
void) INFO="Void Linux|Independent|anon:voidlinux|https://voidlinux.org/|General purpose operating system. Its package system allows you to quickly install, update and remove software; software is provided in binary packages or can be built directly from sources.";;
vxlinux) INFO="VX Linux|Void|-|https://vxlinux.org/|Pre-configured, secure systemd-free Plasma desktop with focus on convenience, performance and simplicity. Based on the excellent Void Linux.";;
whonix) INFO="Whonix|Debian|-|https://www.whonix.org/|Superior Internet Privacy with Whonix™ As handy as an app - delivering maximum anonymity and security.";;
windows) INFO="Windows|proprietary|-|https://www.microsoft.com/en-us/windows/|Whether youre gaming, studying, running a business, or running a household, Windows helps you get it done.";;
windows-server) INFO="Windows Server|proprietary|-|https://www.microsoft.com/en-us/windows-server/|Platform for building an infrastructure of connected applications, networks, and web services.";;
xubuntu) INFO="Xubuntu|Ubuntu|-|https://xubuntu.org/|Elegant and easy to use operating system. Xubuntu comes with Xfce, which is a stable, light and configurable desktop environment.";;
@ -145,7 +126,7 @@ function os_info() {
function show_os_info() {
while getopts ":12345" opt; do
case $opt in
1|2|3|4|5) os_info "${2}" | cut -d'|' -f${opt};;
1|2|3|4|5) os_info "${2}" | cut -d'|' -f "${opt}";;
*) error_not_supported_argument;;
esac
done
@ -161,21 +142,23 @@ function os_homepage() {
}
function error_specify_os() {
echo 'ERROR! You must specify an operating system.'
echo '- Supported Operating Systems:'
echo "ERROR! You must specify an operating system."
echo "- Supported Operating Systems:"
os_support | fold -s -w "$(tput cols)"
echo -e "\nTo see all possible arguments, use:\n quickget -h or quickget --help"
exit 1
}
function os_supported() {
if [[ ! " $(os_support) " =~ " ${OS} " ]]; then
error_not_supported_os
if [[ ! "$(os_support)" =~ ${OS} ]]; then
echo -e "ERROR! ${OS} is not a supported OS.\n"
os_support | fold -s -w "$(tput cols)"
exit 1
fi
}
function error_specify_release() {
echo 'ERROR! You must specify a release.'
echo "ERROR! You must specify a release."
case ${OS} in
*ubuntu-server*)
echo -n ' - Releases: '
@ -212,30 +195,24 @@ function error_specify_edition() {
#TODO: Not yet used!
function error_specify_path() {
echo 'ERROR! You must specify path.'
echo "ERROR! You must specify path."
error_specify_os
exit 1
}
function error_not_supported_os() {
echo -e "ERROR! ${OS} is not a supported OS.\n"
os_support | fold -s -w "$(tput cols)"
exit 1
}
function error_not_supported_release() {
if [[ ! " ${RELEASES[*]} " =~ " ${RELEASE} " ]]; then
echo -e "ERROR! ${DISPLAY_NAME} ${RELEASE} is not a supported release."
echo -n 'Supported releases: '
if [[ ! "${RELEASES[*]}" =~ ${RELEASE} ]]; then
echo -e "ERROR! ${DISPLAY_NAME} ${RELEASE} is not a supported release.\n"
echo -n ' - Supported releases: '
"releases_${OS}"
exit 1
fi
}
function error_not_supported_edition() {
if [[ ! " ${EDITIONS[*]} " =~ " ${EDITION} " ]]; then
if [[ ! "${EDITIONS[*]}" =~ ${EDITION} ]]; then
echo -e "ERROR! ${EDITION} is not a supported $(pretty_name "${OS}") edition\n"
echo -n ' - Editions: '
echo -n ' - Supported editions: '
for EDITION in "${EDITIONS[@]}"; do
echo -n "${EDITION} "
done
@ -452,7 +429,7 @@ function test_all() {
if [ "${OPERATION}" == "show" ]; then
test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}"
elif [ "${OPERATION}" == "test" ]; then
CHECK=$(web_check "${URL}" && echo 'PASS' || echo 'FAIL')
CHECK=$(web_check "${URL}" && echo "PASS" || echo "FAIL")
test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" "${CHECK}"
fi
done
@ -481,7 +458,7 @@ function test_all() {
if [ "${OPERATION}" == "show" ]; then
test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}"
elif [ "${OPERATION}" == "test" ]; then
CHECK=$(web_check "${URL}" && echo 'PASS' || echo 'FAIL')
CHECK=$(web_check "${URL}" && echo "PASS" || echo "FAIL")
test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" "${CHECK}"
fi
fi
@ -733,6 +710,7 @@ function releases_debian() {
local OLD=""
NEW=$(web_pipe "https://cdimage.debian.org/debian-cd/" | grep '\.[0-9]/' | cut -d'>' -f 9 | cut -d'/' -f 1)
OLD=$(web_pipe "https://cdimage.debian.org/cdimage/archive/" | grep -e '>[1-9][0-9]\.' | grep -v 'live' | grep -v NEVER | cut -d'>' -f 9 | cut -d'/' -f 1 | tac | head -20)
#shellcheck disable=SC2086
echo ${NEW} ${OLD}
}
@ -1133,8 +1111,10 @@ function releases_ubuntu() {
local SUPPORTED_VERSIONS=()
local EOL_VERSIONS=()
VERSION_DATA="$(IFS=$'\n' web_pipe https://api.launchpad.net/devel/ubuntu/series | jq -r '.entries[]')"
SUPPORTED_VERSIONS=($(IFS=$'\n' jq -r 'select(.status=="Supported" or .status=="Current Stable Release") | .version' <<<${VERSION_DATA} | sort))
EOL_VERSIONS=($(IFS=$'\n' jq -r 'select(.status=="Obsolete") | .version' <<<${VERSION_DATA} | sort))
# shellcheck disable=SC2207
SUPPORTED_VERSIONS=($(IFS=$'\n' jq -r 'select(.status=="Supported" or .status=="Current Stable Release") | .version' <<<"${VERSION_DATA}" | sort))
# shellcheck disable=SC2207
EOL_VERSIONS=($(IFS=$'\n' jq -r 'select(.status=="Obsolete") | .version' <<<"${VERSION_DATA}" | sort))
case "${OS}" in
ubuntu)
echo "${SUPPORTED_VERSIONS[@]}" daily-live "${EOL_VERSIONS[@]/#/eol-}";;
@ -1151,8 +1131,10 @@ function releases_ubuntu() {
}
function releases_ubuntu-server() {
local ALL_VERSIONS=($(IFS=$'\n' web_pipe http://releases.ubuntu.com/streams/v1/com.ubuntu.releases:ubuntu-server.json | jq -r '.products[] | select(.arch=="amd64") | .version' | sort -rV))
echo "${ALL_VERSIONS[@]}"
local ALL_VERSIONS=()
# shellcheck disable=SC2207
ALL_VERSIONS=($(IFS=$'\n' web_pipe http://releases.ubuntu.com/streams/v1/com.ubuntu.releases:ubuntu-server.json | jq -r '.products[] | select(.arch=="amd64") | .version' | sort -rV))
echo daily-live "${ALL_VERSIONS[@]}"
}
function releases_vanillaos() {
@ -1278,7 +1260,7 @@ function web_get() {
test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}"
exit 0
elif [ "${OPERATION}" == "test" ]; then
CHECK=$(web_check "${URL}" && echo 'PASS' || echo 'FAIL')
CHECK=$(web_check "${URL}" && echo "PASS" || echo "FAIL")
test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" "${CHECK}"
exit 0
elif [ "${OPERATION}" == "download" ]; then
@ -1342,7 +1324,7 @@ function zsync_get() {
test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}"
exit 0
elif [ "${OPERATION}" == "test" ]; then
CHECK=$(web_check "${URL}" && echo 'PASS' || echo 'FAIL')
CHECK=$(web_check "${URL}" && echo "PASS" || echo "FAIL")
test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" "${CHECK}"
exit 0
elif command -v zsync &>/dev/null; then
@ -1552,7 +1534,7 @@ EOF
fi
fi
echo -e "\nTo start your $(pretty_name "${OS}") virtual machine run:"
if [ ${OS} == "slint" ]; then
if [ "${OS}" == "slint" ]; then
echo -e " quickemu --vm ${CONF_FILE}\nTo start Slint with braille support run:\n quickemu --vm --braille --display sdl ${CONF_FILE}"
else
echo " quickemu --vm ${CONF_FILE}"
@ -1880,6 +1862,7 @@ function get_fedora() {
Server|Kinoite|Onyx|Silverblue|Sericea|Workstation) VARIANT="${EDITION}";;
*) VARIANT="Spins";;
esac
#shellcheck disable=SC2086
JSON=$(web_pipe "https://getfedora.org/releases.json" | jq '.[] | select(.variant=="'${VARIANT}'" and .subvariant=="'"${EDITION}"'" and .arch=="x86_64" and .version=="'"${RELEASE}"'")')
URL=$(echo "${JSON}" | jq -r '.link' | head -n1)
HASH=$(echo "${JSON}" | jq -r '.sha256' | head -n1)
@ -2034,7 +2017,7 @@ function generate_id() {
local macRecoveryID=""
local TYPE="${1}"
local valid_chars=("0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F")
for ((i=0; i<$TYPE; i++)); do
for ((i=0; i<TYPE; i++)); do
macRecoveryID+="${valid_chars[$((RANDOM % 16))]}"
done
echo "${macRecoveryID}"
@ -2106,7 +2089,7 @@ function get_macos() {
if [ "${skipVerification,,}" != "y" ] && [ "${skipVerification,,}" != "yes" ]; then
exit 1
fi
echo 'Skipping verification' && skipVerification="true"
echo "Skipping verification" && skipVerification="true"
fi
OpenCore_qcow2="https://github.com/kholia/OSX-KVM/raw/master/OpenCore/OpenCore.qcow2"
@ -2132,7 +2115,7 @@ function get_macos() {
test_result "${OS}" "${RELEASE}" "" "${downloadLink}"
exit 0
elif [ "${OPERATION}" == "test" ]; then
CHECK=$(web_check "${downloadLink}" --header "Host: oscdn.apple.com" --header "Connection: close" --header "User-Agent: InternetRecovery/1.0" --header "Cookie: AssetToken=${downloadSession}" && echo 'PASS' || echo 'FAIL')
CHECK=$(web_check "${downloadLink}" --header "Host: oscdn.apple.com" --header "Connection: close" --header "User-Agent: InternetRecovery/1.0" --header "Cookie: AssetToken=${downloadSession}" && echo "PASS" || echo "FAIL")
test_result "${OS}" "${RELEASE}" "" "${downloadLink}" "${CHECK}"
exit 0
elif [ "${OPERATION}" == "download" ]; then
@ -2187,18 +2170,26 @@ function get_manjaro() {
local ISO=""
local MANIFEST=""
local URL=""
local TYPE=""
case ${RELEASE} in
sway) MANIFEST="$(web_pipe https://mirror.manjaro-sway.download/manjaro-sway/release.json)";;
gnome|xfce|plasma) TYPE="official";;
*) TYPE="community";;
local TYPE="official"
MANIFEST="$(web_pipe https://gitlab.manjaro.org/web/iso-info/-/raw/master/file-info.json)"
case "${RELEASE}" in
sway)
MANIFEST="$(web_pipe https://mirror.manjaro-sway.download/manjaro-sway/release.json)"
TYPE="sway"
;;
cinnamon|i3) TYPE="community";;
esac
[[ ${RELEASE} != "sway" ]] && MANIFEST="$(web_pipe https://gitlab.manjaro.org/web/iso-info/-/raw/master/file-info.json)"
[[ ${EDITION} == "minimal" && ${TYPE} != "sway" ]] && EDITION=".minimal" || EDITION=""
if [[ ${RELEASE} != "sway" ]]; then
URL="$(echo ${MANIFEST} | jq -r .${TYPE}.${RELEASE}${EDITION}.image)"
if [ "${EDITION}" == "minimal" ] && [ "${TYPE}" != "sway" ]; then
EDITION=".minimal"
else
URL=$(echo ${MANIFEST} | jq -r '.[] | select(.name|test("^manjaro-sway-.*[.]iso$")) | select(.name|contains("unstable")|not) | .url')
EDITION=""
fi
if [ "${RELEASE}" == "sway" ]; then
URL=$(echo "${MANIFEST}" | jq -r '.[] | select(.name|test("^manjaro-sway-.*[.]iso$")) | .url')
else
URL="$(echo "${MANIFEST}" | jq -r ."${TYPE}.${RELEASE}${EDITION}".image)"
fi
HASH=$(web_pipe "${URL}.sha512" | cut_1)
echo "${URL} ${HASH}"
@ -2541,6 +2532,7 @@ function get_trisquel() {
}
function get_truenas-scale() {
local HASH=""
local ISO=""
local URL=""
local DLINFO="https://www.truenas.com/download-truenas-scale/"
@ -2559,13 +2551,12 @@ function get_truenas-core() {
}
function get_tuxedo-os() {
local HASH=""
local ISO=""
local URL=""
local Current=
Current="$(web_pipe "https://os.tuxedocomputers.com/" | grep -m 1 current.iso | cut -d '=' -f 4 | cut -d '"' -f 2)"
URL="https://os.tuxedocomputers.com/${Current}"
HASH="$(web_pipe "https://os.tuxedocomputers.com/checksums/${Current}.sha256" | cut -d ' ' -f 1)"
echo "${URL} ${HASH}"
local URL="https://os.tuxedocomputers.com"
ISO="$(web_pipe "https://os.tuxedocomputers.com/" | grep -m 1 current.iso | cut -d '=' -f 4 | cut -d '"' -f 2)"
HASH="$(web_pipe "https://os.tuxedocomputers.com/checksums/${ISO}.sha256" | cut -d ' ' -f 1)"
echo "${URL}/${ISO} ${HASH}"
}
function get_ubuntu-server() {
@ -2573,7 +2564,7 @@ function get_ubuntu-server() {
local ISO=""
local NAME="live-server"
local URL=""
[[ $RELEASE = daily ]] && RELEASE=daily-live
if [[ "${RELEASE}" == "daily"* ]]; then
URL="https://cdimage.ubuntu.com/${OS}/${RELEASE}/current"
else
@ -2608,7 +2599,7 @@ function get_ubuntu() {
local HASH=""
local URL=""
local DATA=""
[[ $RELEASE = daily ]] && RELEASE=daily-live
if [[ "${RELEASE}" == "daily"* ]] && [ "${OS}" == "ubuntustudio" ]; then
# Ubuntu Studio daily-live images are in the dvd directory
RELEASE="dvd"
@ -2639,7 +2630,7 @@ function get_ubuntu() {
ISO=$(cut -d'*' -f2 <<<${DATA})
HASH=$(cut_1 <<<${DATA})
fi
if [ -z $ISO ] || [ -z $HASH ]; then
if [ -z "${ISO}" ] || [ -z "${HASH}" ]; then
echo "$(pretty_name $OS) ${RELEASE} is currently unavailable. Please select other OS/Release combination"
exit 1
fi
@ -3370,8 +3361,8 @@ function open_homepage() {
error_specify_os
else
URL="$(os_info "${1}" | cut -d'|' -f 4)"
# shellcheck disable=SC2034
XDG_OPEN=$(xdg-open "${URL}" || sensible-browser "${URL}" || x-www-browser "${URL}" || gnome-open "${URL}")
unset XDG_OPEN
exit 0
fi
}
@ -3387,36 +3378,38 @@ function create_vm() {
#echo "${HASH}"
web_get "${URL}" "${VM_PATH}"
if [ -n "${HASH}" ]; then
check_hash "${ISO}" "${HASH}"
check_hash "${ISO}" "${HASH}"
fi
if [ ${OS} == "freedos" ] && [[ $ISO =~ ".zip" ]]; then
unzip ${VM_PATH}/${ISO} -d ${VM_PATH}
ISO=$(ls ${VM_PATH} | grep -i '.iso')
fi
#if [ ${OS} == "guix" ] && [[ $ISO =~ ".qcow2" ]]; then
#cp ${VM_PATH}/${ISO} ${VM_PATH}/disc.qcow2
#fi
if [[ ${OS} == "batocera" ]] && [[ ${ISO} =~ ".gz" ]]; then
gzip -d "${VM_PATH}/${ISO}"
ISO="${ISO/.gz/}"
fi
# Could be other OS iso files compressed with bzip2 or gzip
# but for now we'll keep this to know cases
if [[ ${OS} == "dragonflybsd" ]] && [[ ${ISO} =~ ".bz2" ]]; then
bzip2 -d "${VM_PATH}/${ISO}"
ISO="${ISO/.bz2/}"
fi
if [[ ${OS} == "easyos" ]] && [[ ${ISO} =~ ".img" ]]; then
qemu-img convert -f raw -O qcow2 "${VM_PATH}/${ISO}" "${VM_PATH}/disk.qcow2"
ISO="${ISO/.img/}"
fi
if [ ${OS} == "reactos" ] && [[ $ISO =~ ".zip" ]]; then
unzip ${VM_PATH}/${ISO} -d ${VM_PATH}
ISO=$(ls ${VM_PATH} | grep -i '.iso' | grep -v '.zip')
fi
case "${OS}" in
batocera)
if [[ ${ISO} = *".gz"* ]]; then
gzip -d "${VM_PATH}/${ISO}"
ISO="${ISO/.gz/}"
fi;;
dragonflybsd)
# Could be other OS iso files compressed with bzip2 or gzip
# but for now we'll keep this to know cases
if [[ ${ISO} = *".bz2"* ]]; then
bzip2 -d "${VM_PATH}/${ISO}"
ISO="${ISO/.bz2/}"
fi;;
easyos)
if [[ ${ISO} = *".img"* ]]; then
qemu-img convert -f raw -O qcow2 "${VM_PATH}/${ISO}" "${VM_PATH}/disk.qcow2"
ISO="${ISO/.img/}"
fi;;
freedos)
if [[ ${ISO} = *".zip"* ]]; then
unzip ${VM_PATH}/${ISO} -d ${VM_PATH}
ISO=$(ls ${VM_PATH} | grep -i '.iso')
fi;;
reactos)
if [[ ${ISO} = *".zip"* ]]; then
unzip ${VM_PATH}/${ISO} -d ${VM_PATH}
ISO=$(ls ${VM_PATH} | grep -i '.iso' | grep -v '.zip')
fi;;
esac
make_vm_config "${ISO}"
}
@ -3439,22 +3432,22 @@ Usage:
quickget ubuntu 22.04
Advanced usage:
quickget <arg> [path] <os> [re] [ed]
quickget <arg> [path] <os> [release] [edition]
quickget --download ubuntu 22.04
Arguments:
-[12345] <os> : Show info* about OS
--download (-d) <os> <re> [ed] : Download image; no VM configuration
--create-config (-cc) <os> [path/url]: Create default VM config for image
--open-homepage (-o) <os> : Open homepage for the OS
--version (-v) : Show version
--help (-h) : Show this help message
-[12345] <os> : Show info* about OS
--download <os> <release> [edition] : Download image; no VM configuration
--create-config <os> [path/url] : Create VM config for a OS image
--open-homepage <os> : Open homepage for the OS
--version : Show version
--help : Show this help message
-------------------------- For testing & development ---------------------------
--url (-u) [os] [re] [ed] : Show image URL(s)
--check (-c) [os] [re] [ed] : Check image URL(s)
--list (-l) : List all supported systems
--list-csv (-lc) : List everything in csv format
--list-json (-lj) : List everything in json format
--url [os] [release] [edition] : Show image URL(s)
--check [os] [release] [edition] : Check image URL(s)
--list : List all supported systems
--list-csv : List everything in csv format
--list-json : List everything in json format
--------------------------------------------------------------------------------
*info: 1=Logo 2=Based of 3=Credentials 4=Homepage 5=Short info
Can be used in any combination like -13254 or -52
@ -3479,34 +3472,35 @@ if [ ! -e "${CURL}" ]; then
fi
CURL_VERSION=$("${CURL}" --version | head -1 | cut -d' ' -f2)
#TODO: Deprecate `list`, `list_csv`, and `list_json` in favor of `--list`, `--list-csv`, and `--list-json`
case "${1}" in
-1*|-2*|-3*|-4*|-5*)
show_os_info "${1}" "${2}"
exit 0
;;
'--download'|'-d')
--download|-download)
OPERATION="download"
shift
;;
'--create-config'|'-cc')
--create-config|-create-config)
OPERATION="config"
shift
create_config "${@}"
;;
'--open-homepage'|'-o')
--open-homepage|-open-homepage)
shift
open_homepage "${1}"
;;
'--version'|'-v')
--version|-version)
WHERE=$(dirname "${BASH_SOURCE[0]}")
"${WHERE}/quickemu" --version
exit 0
;;
'--help'|'-h')
--help|-help|--h|-h)
help_message
exit 0
;;
'--url'|'-u')
--url|-url)
OPERATION="show"
shift
if [ -z "${1}" ]; then
@ -3519,29 +3513,22 @@ case "${1}" in
exit 0
fi
;;
'--check'|'-c')
--check|-check)
OPERATION="test"
shift
if [ -z "${1}" ]; then
for OS in $(os_support); do
(test_all "${OS}")
done
exit 0
elif [ -z "${2}" ]; then
test_all "${1}"
exit 0
fi
exit 0
;;
#TODO: Argument without dashes should be DEPRECATED!
'--list-csv'|'-lc'|'list'|'list_csv'|'lc')
list_csv
;;
#TODO: Argument without dashes should be DEPRECATED!
'--list-json'|'-lj'|'list_json')
list_json
;;
'--list'|'-l')
list_supported
;;
--list-csv|-list-csv|list|list_csv) list_csv;;
--list-json|-list-json|list_json) list_json;;
--list|-list) list_supported;;
-*)
error_not_supported_argument
;;
@ -3561,7 +3548,8 @@ if [ -n "${2}" ]; then
# If the OS has an editions_() function, use it.
if [[ $(type -t "editions_${OS}") == function ]]; then
validate_release "releases_${OS}"
EDITIONS=($(editions_${OS}))
EDITIONS=("$(editions_${OS})")
# Default to the first edition if none is specified.
EDITION=${EDITIONS[0]}
if [ -n "${3}" ]; then
EDITION="${3}"
@ -3590,7 +3578,7 @@ if [ -n "${2}" ]; then
"languages_${OS}"
if [ -n "${3}" ]; then
LANG="${3}"
if [[ ! ${LANGS[*]} =~ "${LANG}" ]]; then
if [[ ! "${LANGS[*]}" =~ ${LANG} ]]; then
error_not_supported_lang
fi
VM_PATH="$(echo "${OS}-${RELEASE}-${LANG// /-}" | tr -d '()')"