#!/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 # Latest cherrypick (or not) commit. Start from here... # https://github.com/quickemu-project/quickemu/tree/3da9edc9953340622db23be4661aefa4cd0632f2 export TEXTDOMAIN=quickget if [[ -n $Q_DEBUG ]]; then export TEXTDOMAINDIR="${PWD}/locale" else export TEXTDOMAINDIR=/usr/share/locale fi export LC_ALL=C function cleanup() { if [ -n "$(jobs -p)" ]; then kill "$(jobs -p)" 2>/dev/null fi } function show_os_info() { # shellcheck source=public/alpine . "public/${1}" echo echo " ${PRETTY}" echo $" Website: ${HOMEPAGE}" echo $" Based of: ${BASEDOF}" echo $"Description: ${DESCRIPTION}" echo $"Credentials: ${CREDENTIALS}" echo $"Releases: ${RELEASES}" | fmt -w $(tput cols) if [[ $(type -t "editions_") == function ]]; then echo -n $"Editions: ${EDITIONS}" | fmt -w $(tput cols) fi } function os_support() { DIR="actions" for file in "$DIR"/*; do if [[ -f "$file" ]]; then filename="${file##*/}" echo "$filename" fi done } function error_specify_os() { echo $"ERROR! You must specify an operating system." echo $"- Supported Operating Systems:" os_support | fmt -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 echo -e $"ERROR! ${OS} is not a supported OS.\n" os_support | fmt -w $(tput cols) exit 1 fi } function error_specify_release() { show_os_info "${OS}" echo -e $"\nERROR! You must specify a release." exit 1 } function error_not_supported_release() { if [[ ! "${RELEASES[*]}" =~ ${RELEASE} ]]; then echo -e $"ERROR! ${DISPLAY_NAME} ${RELEASE} is not a supported release.\n" echo -n $' - Supported releases: ' releases_ exit 1 fi } function error_not_supported_lang() { echo -e $"ERROR! ${I18N} is not a supported ${PRETTY} language\n" echo -n $' - Editions: ' for I18N in "${I18NS[@]}"; do echo -n "${I18N} " done exit 1 } function error_not_supported_argument() { echo $"ERROR! Not supported argument" echo $"To see all possible arguments, use:" echo " quickget -h or quickget --help" exit 1 } function error_unable_to_create_dir() { echo $"ERROR! Unable to create directory ${DIR}" exit 1 } function error_not_supported_image() { echo $"ERROR! Only ISO,IMG and QCOW2 file types are supported for --create-config" exit 1 } function is_valid_language() { local I18N="" local PASSED_I18N="${1}" for I18N in "${I18NS[@]}"; do if [[ "${I18N}" == "${PASSED_I18N}" ]]; then return 0 fi done return 1 } function handle_missing() { # Handle odd missing Fedora combinations case "${OS}" in fedora) # First we need to handle the Beta naming kludge if [[ "${RELEASE}" == *"_Beta" ]]; then NRELEASE="${RELEASE/_Beta/}" else NRELEASE="${RELEASE}" fi if [[ "${NRELEASE}" -lt 40 && "${EDITION}" == "Onyx" ]] || [[ "${NRELEASE}" -lt 40 && "${EDITION}" == "Sericea" ]]; then echo $"ERROR! Unsupported combination" echo $" Fedora ${RELEASE} ${EDITION} is not available, please choose another Release or Edition" exit 1 fi;; esac } function validate_release() { local DISPLAY_NAME="" local RELEASE_GENERATOR="" local RELEASES="" DISPLAY_NAME="${PRETTY}" case ${OS} in *ubuntu-server*) RELEASE_GENERATOR="releases_";; *ubuntu*) RELEASE_GENERATOR="releases_";; *) RELEASE_GENERATOR="${1}";; esac RELEASES=$(${RELEASE_GENERATOR}) error_not_supported_release } function list_json() { # Reference: https://stackoverflow.com/a/67359273 list_csv | jq -R 'split(",") as $h|reduce inputs as $in ([]; . += [$in|split(",")|. as $a|reduce range(0,length) as $i ({};.[$h[$i]]=$a[$i])])' exit 0 } function list_csv() { CSV_DATA="$(csv_data)" echo "Display Name,OS,Release,Option,Downloader,PNG,SVG" sort -t',' -k2,2 <<<"${CSV_DATA}" exit 0 } # OLD FUNCTIONS TO REMADE? list_supported() { # output OS RELEASE EDITION (usefull for straight testing...) local DL="" local FUNC local OPTION local OS for OS in $(os_support); do case ${OS} in *ubuntu-server*) FUNC="ubuntu-server";; *ubuntu*) FUNC="ubuntu";; *) FUNC="${OS}";; esac for RELEASE in $(releases_ | sed -Ee 's/eol-\S+//g' ); do # hide eol releases # If the OS has an editions_() function, use it. if [[ $(type -t editions_) == function ]]; then for OPTION in $(editions_); do echo "${OS} ${RELEASE} ${OPTION}" done elif [[ "${OS}" == "windows"* ]]; then "languages_" for OPTION in "${LANGS[@]}"; do echo "${OS} ${RELEASE} ${OPTION}" done else echo "${OS} ${RELEASE}" fi done done exit 0 } list_isos() { local URL local FUNC local OPTION local OS echo "OS|Release|Edition|URL" for OS in $(os_support); do case ${OS} in *ubuntu-server*) FUNC="ubuntu-server";; *ubuntu*) FUNC="ubuntu";; *) FUNC="${OS}";; esac for RELEASE in $(releases_ | sed -Ee 's/eol-\S+//g' ); do # hide eol releases # If the OS has an editions_() function, use it. if [[ $(type -t editions_) == function ]]; then for OPTION in $(editions_); do URL=$(./quickget -u "${OS}" "${RELEASE}" "${OPTION}") if [ -z "${URL}" ]; then echo "${OS}|${RELEASE}|${OPTION}|${URL}" else echo "${OS}|${RELEASE}|${OPTION}|${URL}" fi done elif [[ "${OS}" == "windows"* ]]; then languages_ for OPTION in "${LANGS[@]}"; do #URL=$(./quickget -u ${OS} ${RELEASE} ${OPTION}) if [ -n "${URL}" ]; then echo "${OS}|${RELEASE}|${OPTION}|" else echo "${OS}|${RELEASE}|${OPTION}|Strange!" #TODO fi done elif [[ "${OS}" == "macos" ]]; then echo "${OS}|${RELEASE}|${OPTION}|" else URL=$(./quickget -u "${OS}" "${RELEASE}") if [ -z "${URL}" ]; then echo "${OS}|${RELEASE}|${OPTION}|${URL}" else echo "${OS}|${RELEASE}|${OPTION}|${URL}" fi fi done done exit 0 } function csv_data() { local DISPLAY_NAME local DL="" local DOWNLOADER local FUNC local OPTION local OS local PNG local RELEASE local SVG local HAS_ZSYNC=0 # Check if zsync is available if command -v zsync &>/dev/null; then HAS_ZSYNC=1 fi for OS in $(os_support); do . "actions/${OS}" local EDITIONS="" DISPLAY_NAME="${PRETTY}" PNG="https://quickemu-project.github.io/quickemu-icons/png/${FUNC}/${FUNC}-quickemu-white-pinkbg.png" SVG="https://quickemu-project.github.io/quickemu-icons/svg/${FUNC}/${FUNC}-quickemu-white-pinkbg.svg" if [[ $(type -t editions_) == function ]]; then EDITIONS=$(editions_) fi for RELEASE in $(releases_); do if [[ "${OS}" == *"ubuntu"* ]] && [[ ${RELEASE} == *"daily"* ]] && [ ${HAS_ZSYNC} -eq 1 ]; then DOWNLOADER="zsync" else DOWNLOADER="${DL}" fi # If the OS has an editions_() function, use it. if [[ ${EDITIONS} ]]; then for OPTION in ${EDITIONS}; do echo "${DISPLAY_NAME},${OS},${RELEASE},${OPTION},${DOWNLOADER},${PNG},${SVG}" done elif [[ "${OS}" == "windows"* ]]; then languages_ for I18N in "${I18NS[@]}"; do echo "${DISPLAY_NAME},${OS},${RELEASE},${I18N},${DOWNLOADER},${PNG},${SVG}" done else echo "${DISPLAY_NAME},${OS},${RELEASE},,${DOWNLOADER},${PNG},${SVG}" fi done & done wait } function list_supported() { list_csv | cut -d ',' -f2,3,4 | tr ',' ' ' exit 0 } # OLD FUNCTIONS TO REMADE? function test_result() { local OS="${1}" local RELEASE="${2}" local EDITION="${3:-}" local URL="${4:-}" local RESULT="${5:-}" if [ -n "${EDITION}" ]; then OS="${OS}-${RELEASE}-${EDITION}" else OS="${OS}-${RELEASE}" fi if [ -n "${RESULT}" ]; then # Pad the OS string for consistent output OS=$(printf "%-35s" "${OS}") echo -e "${RESULT}: ${OS} ${URL}" else OS=$(printf "%-36s" "${OS}:") echo -e "${OS} ${URL}" fi } function test_all() { OS="${1}" os_supported local CHECK="" local FUNC="${OS}" if [[ "${OS}" == *ubuntu* && "${OS}" != "ubuntu-server" ]]; then FUNC="ubuntu" fi local URL="" . "actions/${OS}" for RELEASE in $(releases_); do . "actions/${OS}" if [ "${OS}" == 'rebornos' ]; then if curl -I "https://cdn.soulharsh007.dev/RebornOS-ISO/${ISO}"; then test_result "${OS} ${RELEASE} ${URL} PASS" else test_result "${OS} ${RELEASE} ${URL} FAIL" fi elif [[ $(type -t editions_) == function ]]; then . "actions/${OS}" for EDITION in $(editions_); do validate_release releases_ URL=$(get_ | cut -d' ' -f1 | head -n 1) if [ "${OPERATION}" == "show" ]; then test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" elif [ "${OPERATION}" == "test" ]; then CHECK=$(web_check "${URL}" && echo "PASS" || echo "FAIL") test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" "${CHECK}" fi done elif [[ "${OS}" == "windows"* ]]; then . "actions/${OS}" languages_ for I18N in "${I18NS[@]}"; do validate_release releases_ if [ "${OPERATION}" == "show" ]; then test_result "${OS}" "${RELEASE}" "${I18N}" "" elif [ "${OPERATION}" == "test" ]; then test_result "${OS}" "${RELEASE}" "${I18N}" "${URL}" "SKIP" fi done elif [[ "${OS}" == "macos" ]]; then validate_release releases_ (get_) elif [ "${OS}" == "ubuntu-server" ]; then validate_release releases_ (get_) elif [[ "${OS}" == *ubuntu* ]]; then validate_release releases_ (get_) else validate_release releases_ URL=$(get_ | cut -d' ' -f1 | head -n 1) if [ "${OPERATION}" == "show" ]; then test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" elif [ "${OPERATION}" == "test" ]; then CHECK=$(web_check "${URL}" && echo "PASS" || echo "FAIL") test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" "${CHECK}" fi fi done } function check_hash() { local iso="" local hash="" local hash_algo="" if [ "${OPERATION}" == "download" ]; then iso="${1}" else iso="${VM_PATH}/${1}" fi hash="${2}" # Guess the hash algorithm by the hash length case ${#hash} in 32) hash_algo=md5sum;; 40) hash_algo=sha1sum;; 64) hash_algo=sha256sum;; 128) hash_algo=sha512sum;; *) echo $"WARNING! Can't guess hash algorithm, not checking ${iso} hash." return;; esac echo -n $"Checking ${iso} with ${hash_algo}... " if ! echo "${hash} ${iso}" | ${hash_algo} --check --status; then echo $"ERROR!" echo $"${iso} doesn't match ${hash}. Try running 'quickget' again." exit 1 else echo $"Good!" fi } # Download a file from the web and pipe it to stdout function web_pipe() { curl --disable --silent --location "${1}" } # Download a JSON file from the web and pipe it to stdout function web_pipe_json() { curl --disable --silent --location --header "Accept: application/json" "${1}" } # Download a file from the web function web_get() { local CHECK="" local HEADERS=() local URL="${1}" local DIR="${2}" local FILE="" local USER_AGENT="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" if [ -n "${3}" ]; then FILE="${3}" else FILE="${URL##*/}" fi # Process any URL redirections after the file name has been extracted URL=$(web_redirect "${URL}") # Process any headers while (( "$#" )); do if [ "${1}" == "--header" ]; then HEADERS+=("${1}" "${2}") shift 2 else shift fi done # Test mode for ISO if [ "${OPERATION}" == "show" ]; then test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" exit 0 elif [ "${OPERATION}" == "test" ]; then CHECK=$(web_check "${URL}" && echo "PASS" || echo "FAIL") test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" "${CHECK}" exit 0 elif [ "${OPERATION}" == "download" ]; then DIR="$(pwd)" fi if [ "${DIR}" != "$(pwd)" ] && ! mkdir -p "${DIR}" 2>/dev/null; then error_unable_to_create_dir fi if [[ ${OS} != windows && ${OS} != macos && ${OS} != windows-server ]]; then echo $"Downloading ${PRETTY} ${RELEASE} ${EDITION}" echo $"- URL: ${URL}" fi if ! curl --disable --progress-bar --location --output "${DIR}/${FILE}" --continue-at - --user-agent "${USER_AGENT}" "${HEADERS[@]}" -- "${URL}"; then echo $"ERROR! Failed to download ${URL} with curl." rm -f "${DIR}/${FILE}" fi } # checks if a URL needs to be redirected and returns the final URL function web_redirect() { local REDIRECT_URL="" local URL="${1}" # Check for URL redirections # Output to nonexistent directory so the download fails fast REDIRECT_URL=$(curl --disable --silent --location --fail --write-out '%{url_effective}' --output /var/cache/${RANDOM}/${RANDOM} "${URL}") if [ "${REDIRECT_URL}" != "${URL}" ]; then echo "${REDIRECT_URL}" else echo "${URL}" fi } # checks if a URL is reachable function web_check() { local HEADERS=() local URL="${1}" # Process any headers while (( "$#" )); do if [ "${1}" == "--header" ]; then HEADERS+=("${1}" "${2}") shift 2 else shift fi done curl --disable --silent --location --head --output /dev/null --fail --connect-timeout 30 --max-time 30 --retry 3 "${HEADERS[@]}" "${URL}" } function zsync_get() { local CHECK="" local DIR="${2}" local FILE="${1##*/}" local OUT="" local URL="${1}" # Test mode for ISO if [ "${OPERATION}" == "show" ]; then test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" exit 0 elif [ "${OPERATION}" == "test" ]; then CHECK=$(web_check "${URL}" && echo "PASS" || echo "FAIL") test_result "${OS}" "${RELEASE}" "${EDITION}" "${URL}" "${CHECK}" exit 0 elif command -v zsync &>/dev/null; then if [ -n "${3}" ]; then OUT="${3}" else OUT="${FILE}" fi if ! mkdir -p "${DIR}" 2>/dev/null; then error_unable_to_create_dir fi echo $"Downloading ${PRETTY} ${RELEASE} ${EDITION} from ${URL}" # Only force http for zsync - not earlier because we might fall through here if ! zsync "${URL/https/http}.zsync" -i "${DIR}/${OUT}" -o "${DIR}/${OUT}" 2>/dev/null; then echo $"ERROR! Failed to download ${URL/https/http}.zsync" exit 1 fi if [ -e "${DIR}/${OUT}.zs-old" ]; then rm "${DIR}/${OUT}.zs-old" fi else echo $"INFO: zsync not found, falling back to curl" if [ -n "${3}" ]; then web_get "${1}" "${2}" "${3}" else web_get "${1}" "${2}" fi fi } function make_vm_config() { local CONF_FILE="" local IMAGE_FILE="" local ISO_FILE="" #local IMAGE_TYPE="" #local GUEST="" if [ "${OPERATION}" == "download" ]; then exit 0 fi IMAGE_FILE="${1}" ISO_FILE="${2}" if [ "${OS}" == 'custom' ]; then GUEST="${CUSTOM_OS}" IMAGE_TYPE="${CUSTOM_IMAGE_TYPE}" fi if [ -z "$GUEST" ]; then GUEST="linux" fi if [ -z "${IMAGE_TYPE}" ]; then IMAGE_TYPE="iso" fi CONF_FILE="${VM_PATH}.conf" if [ ! -e "${CONF_FILE}" ]; then echo $"Making ${CONF_FILE}" cat << EOF > "${CONF_FILE}" #!${QUICKEMU} --vm guest_os="${GUEST}" disk_img="${VM_PATH}/disk.qcow2" ${IMAGE_TYPE}="${VM_PATH}/${IMAGE_FILE}" EOF echo $" - Setting ${CONF_FILE} executable" chmod u+x "${CONF_FILE}" if [ -n "${ISO_FILE}" ]; then echo "fixed_iso=\"${VM_PATH}/${ISO_FILE}\"" >> "${CONF_FILE}" fi # OS specific tweaks #. "actions/${OS}" #specific_tweaks 2>/dev/null if [ "${OS}" == "ubuntu" ] && [[ ${RELEASE} == *"daily"* ]]; then # Minimum to install lobster testing is 18GB but 32GB are allocated for headroom echo "disk_size=\"32G\"" >> "${CONF_FILE}" fi if [[ "${OS}" == "windows"* ]]; then echo "disk_size=\"64G\"" >> "${CONF_FILE}" fi # Enable TPM for Windows 11 and Windows Server 2022 if [[ "${OS}" == "windows" && "${RELEASE}" == "11" || "${OS}" == "windows-server" && "${RELEASE}" == "2022" ]]; then echo "tpm=\"on\"" >> "${CONF_FILE}" echo "secureboot=\"off\"" >> "${CONF_FILE}" fi if [ "${OPERATION}" == ui ]; then echo gum confirm $"Run new ${OS} VM?" && quickemu --vm "${CONF_FILE}" fi fi echo -e $"\nTo start your ${PRETTY} virtual machine run:" 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}" fi echo unset GUEST IMAGE_TYPE exit 0 } function open_homepage() { # shellcheck source=actions/alpine . "actions/${1}" local XDG_OPEN="" if [ -z "${PRETTY}" ]; then error_specify_os else # shellcheck disable=SC2034 XDG_OPEN=$(xdg-open "${HOMEPAGE}" || sensible-browser "${HOMEPAGE}" || x-www-browser "${HOMEPAGE}" || gnome-open "${HOMEPAGE}") exit 0 fi } function create_vm() { # shellcheck disable=SC2206 local URL_HASH=(${1// / }) local URL="${URL_HASH[0]}" local HASH="${URL_HASH[1]}" local ISO="${URL##*/}" #echo "${URL}" #echo "${ISO}" #echo "${HASH}" web_get "${URL}" "${VM_PATH}" if [ -n "${HASH}" ]; then check_hash "${ISO}" "${HASH}" fi # shellcheck disable=SC2076 . "actions/${OS}" "distro_specific" 2>/dev/null make_vm_config "${ISO}" } function create_config() { local VM_PATH="${1}" local INPUT="${2}" local FIXED_ISO="" OS="custom" if ! mkdir "${VM_PATH}" 2>/dev/null; then echo $"WARNING! This will overwrite content of directory: ${VM_PATH}" fi if [[ "${INPUT}" == "http://"* ]] || [[ "${INPUT}" == "https://"* ]]; then INPUT="$(web_redirect "${INPUT}")" if [[ "${INPUT}" == *".iso" ]] || [[ "${INPUT}" == *".img" ]]; then web_get "${INPUT}" "${VM_PATH}" INPUT="${INPUT##*/}" else error_not_supported_image fi fi function moving_image() { echo $"Moving image to VM dir" } if [ ! -f "${INPUT}" ]; then echo $"ERROR! The input must be a valid URL or path to an ISO, IMG, or QCOW2 file." echo "#TODO exit 1" elif [[ "${INPUT}" == *".iso" ]]; then moving_image && mv "${INPUT}" "${VM_PATH}" CUSTOM_IMAGE_TYPE="iso" elif [[ "${INPUT}" == *".img" ]]; then moving_image && mv "${INPUT}" "${VM_PATH}" CUSTOM_IMAGE_TYPE="img" elif [[ "${INPUT}" == *".qcow2" ]]; then moving_image && mv "${INPUT}" "${VM_PATH}/disk.qcow2" CUSTOM_IMAGE_TYPE="qcow2" else error_not_supported_image fi INPUT="$(basename "${INPUT}")" echo $"Creating custom VM config for ${INPUT##*/}." case "${INPUT,,}" in *freebsd*) CUSTOM_OS="freebsd";; *kolibrios*) CUSTOM_OS="kolibrios";; *reactos*) CUSTOM_OS="reactos";; *windows-server*|*eval_oemret_x*|*eval_x*) CUSTOM_OS="windows-server";; *windows*|win*) CUSTOM_OS="windows" # Older windows 10 ISOs use the year followed by the month rather than the year & half). Match any text for language. if [ "${3}" != "--disable-unattended" ] && ( [ "${3}" == "--unattended" ] || grep -E -q 'Win(10|11)_([0-9]{2}H(1|2)|[0-9]{4})_[^.]*?(x64|x32)(v[0-9])?.iso' <<< "${INPUT}" ); then echo $"Creating unattended Windows installation files. To disable, pass --disable-unattended" echo echo $"Downloading VirtIO drivers..." web_get "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso" "${VM_PATH}" FIXED_ISO="virtio-win.iso" rm -f "${VM_PATH}/unattended.iso" unattended_windows "${VM_PATH}" fi ;; *) CUSTOM_OS="linux";; esac echo -e $"Selecting OS: ${CUSTOM_OS}. If this is incorrect, please modify the config file to include the correct OS.\n" make_vm_config "${INPUT}" "${FIXED_ISO}" } # Use command -v command to check if quickemu is in the system's PATH and # fallback to checking if quickemu is in the current directory. function resolve_quickemu() { command -v quickemu || \ if [ -x "./quickemu" ]; then echo "$(pwd)/quickemu" else echo $"quickemu not found" >&2 exit 1 fi } run_itself() { if [ -n "${1}" ]; then OS="${1,,}" else error_specify_os fi os_supported # shellcheck source=actions/alpine . "actions/${OS}" if [ -n "${2}" ]; then RELEASE="${2}" VM_PATH="${OS}-${RELEASE}" # If the OS has an editions_() function, use it. if [[ $(type -t editions_) == function ]]; then validate_release releases_ EDITIONS=$(editions_) if [ -n "${3}" ]; then EDITION="${3}" if [[ ! "${EDITIONS[*]}" = *"${EDITION}"* ]]; then echo -e $"ERROR! ${EDITION} is not a supported ${PRETTY} edition\n" echo -n $' - Supported editions: ' for EDITION in "${EDITIONS[@]}"; do echo -n "${EDITION} " done echo "" exit 1 fi else show_os_info "${OS}" echo -e $"\nERROR! You must specify an edition." exit 1 fi handle_missing VM_PATH="${OS}-${RELEASE}-${EDITION}" create_vm "$("get_" "${EDITION}")" elif [ "${OS}" == "macos" ]; then # macOS doesn't use create_vm() validate_release releases_ get_ elif [[ "${OS}" == *"ubuntu-server"* ]]; then # (Comes before regular Ubuntu, or the code tries to download the desktop) # # Ubuntu doesn't use create_vm() validate_release releases_ get_ elif [[ "${OS}" == *"ubuntu"* ]]; then # Ubuntu doesn't use create_vm() validate_release releases_ get_ elif [[ "${OS}" == "windows"* ]]; then I18N="English International" languages_"${OS}" if [ -n "${3}" ]; then I18N="${3}" if [[ ! "${I18NS[*]}" = *"${I18N}"* ]]; then error_not_supported_lang fi VM_PATH="$(echo "${OS}-${RELEASE}-${I18N// /-}" | tr -d '()')" fi validate_release releases_ get_ else validate_release releases_ create_vm "$("get_")" fi else error_specify_release fi } # shellcheck disable=SC2046 function run_ui() { if ! command -v gum &> /dev/null; then echo $"gum could not be found, please install it first" exit 1 fi OS=$(gum filter --height=17 --header="Select an OS:" $(os_support)) #os_info "${OS}" > "$TMPFILE" # shellcheck source=actions/alpine . "public/${OS}" RELEASE=$(gum filter --height=9 --header="Select $OS release:" ${RELEASES}) if declare -F editions_ > /dev/null; then EDITION=$(gum filter --height=9 --header="Select $OS $RELEASE edition:" ${EDITIONS}) echo '' run_itself "${OS}" "${RELEASE}" "${EDITION}" else echo '' run_itself "${OS}" "${RELEASE}" fi } function help_message() { #shellcheck disable=SC2016 printf ' _ _ _ __ _ _ _(_) ___| | ____ _ ___| |_ / _` | | | | |/ __| |/ / _` |/ _ \ __| | (_| | |_| | | (__| < (_| | __/ |_ \__, |\__,_|_|\___|_|\_\__, |\___|\__| |_| |___/ v%s, using curl %s -------------------------------------------------------------------------------- Project - https://github.com/quickemu-project/quickemu Discord - https://wimpysworld.io/discord -------------------------------------------------------------------------------- Usage: quickget [edition] quickget ubuntu 22.04 Advanced usage: quickget [path] [release] [edition] quickget --download ubuntu 22.04 Arguments: --download [edition] : Download image; no VM configuration --create-config [path/url] [flags] : Create VM config for an OS image --open-homepage : Open homepage for the OS --show [os] : Show OS information --version : Show version --help : Show this help message --ui : Run in UI mode ------------------------------------ Flags ------------------------------------- --create-config: --disable-unattended : Force quickget not to set up an unattended installation -------------------------- For testing & development --------------------------- --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 -------------------------------------------------------------------------------- Supported Operating Systems:\n\n' "$(${QUICKEMU} --version)" "${CURL_VERSION}" os_support | fmt -w 80 } trap cleanup EXIT if ((BASH_VERSINFO[0] < 4)); then echo $"Sorry, you need bash 4.0 or newer to run this script." exit 1 fi QUICKEMU=$(resolve_quickemu) I18NS=() OPERATION="" CURL=$(command -v curl) if [ ! -x "${CURL}" ]; then echo $"ERROR! curl not found. Please install curl" exit 1 fi CURL_VERSION=$("${CURL}" --version | head -n 1 | cut -d' ' -f2) #TODO: Deprecate `list`, `list_csv`, and `list_json` in favor of `--list`, `--list-csv`, and `--list-json` case "${1}" in --ui) OPERATION="ui" shift run_ui ;; --download|-download) OPERATION="download" shift ;; --create-config|-create-config) OPERATION="config" shift create_config "${@}" ;; --open-homepage|-open-homepage) shift open_homepage "${1}" ;; --show|-show) shift if [ -z "${1}" ]; then for OS in $(os_support); do show_os_info "${OS}" done else show_os_info "${1}" fi exit 0;; --version|-version) WHERE=$(dirname "${BASH_SOURCE[0]}") "${WHERE}/quickemu" --version exit 0;; --help|-help|--h|-h) help_message exit 0;; --url|-url) OPERATION="show" 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;; --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;; --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;; esac run_itself "$@" # vim:tabstop=4:shiftwidth=4:expandtab