|
|
@@ -0,0 +1,425 @@ |
|
|
#!/usr/bin/env bash |
|
|
|
|
|
# Download VMware Workstation for Linux without a Broadcom account |
|
|
# |
|
|
# Use '-k' to keep the download file compressed, exiting after download. |
|
|
# Use '-v <Version>' to specify desired version (12.0.0 or higher required). |
|
|
|
|
|
BASE_URL="https://softwareupdate-prod.broadcom.com/cds/vmw-desktop/" |
|
|
CDN_MIRROR="softwareupdate-prod.broadcom.com:443:softwareupdate-prod.broadcom.com.cdn.cloudflare.net:443" |
|
|
|
|
|
read -r -d '' XML_DATA << 'EOF' |
|
|
<metalist> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.5.0/4352439/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>14.0.0</version> |
|
|
<url>ws/14.1.0/7370693/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>17.0.0</version> |
|
|
<url>ws/17.0.2/21581411/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>16.0.0</version> |
|
|
<url>ws/16.2.1/18811642/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>17.0.0</version> |
|
|
<url>ws/17.0.1/21139696/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>14.0.0</version> |
|
|
<url>ws/14.1.6/12368378/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>15.0.0</version> |
|
|
<url>ws/15.5.2/15785246/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>14.0.0</version> |
|
|
<url>ws/14.0.0/6661328/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>14.0.0</url> |
|
|
<url>ws/14.1.4/10722678/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>14.0.0</version> |
|
|
<url>ws/14.1.7/12989993/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.5.1/4542065/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>16.0.0</version> |
|
|
<url>ws/16.2.5/20904516/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.5.9/7535481/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>15.0.0</version> |
|
|
<url>ws/15.0.0/10134415/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.5.7/5813279/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>16.0.0</version> |
|
|
<url>ws/16.1.0/17198959/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>17.0.0</version> |
|
|
<url>ws/17.6.0/24238078/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>17.0.0</version> |
|
|
<url>ws/17.6.1/24319023/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>17.0.0</version> |
|
|
<url>ws/17.6.2/24409262/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>17.0.0</version> |
|
|
<url>ws/17.6.3/24583834/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>16.0.0</version> |
|
|
<url>ws/16.2.3/19376536/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>16.0.0</version> |
|
|
<url>ws/16.0.0/16894299/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>15.0.0</version> |
|
|
<url>ws/15.0.4/12990004/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>14.0.0</version> |
|
|
<url>ws/14.1.2/8497320/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.0.1/3160714/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.1.0/3272444/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.1.1/3770994/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>15.0.0</version> |
|
|
<url>ws/15.5.5/16285975/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>15.0.0</version> |
|
|
<url>ws/15.0.2/10952284/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>17.0.0</version> |
|
|
<url>ws/17.5.0/22583795/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.5.4/5192485/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.5.5/5234757/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>16.0.0</version> |
|
|
<url>ws/16.2.4/20089737/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>15.0.0</version> |
|
|
<url>ws/15.0.1/10737736/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>15.0.0</version> |
|
|
<url>ws/15.0.3/12422535/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>14.0.0</version> |
|
|
<url>ws/14.1.1/7528167/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>15.0.0</version> |
|
|
<url>ws/15.5.1/15018445/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>14.0.0</version> |
|
|
<url>ws/14.1.5/10950780/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>15.0.0</version> |
|
|
<url>ws/15.1.0/13591040/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>16.0.0</version> |
|
|
<url>ws/16.1.1/17801498/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>15.0.0</version> |
|
|
<url>ws/15.5.6/16341506/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>15.0.0</version> |
|
|
<url>ws/15.5.0/14665864/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.5.8/7098237/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.5.6/5528349/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.0.0/2985596/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>15.0.0</version> |
|
|
<url>ws/15.5.7/17171714/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>17.0.0</version> |
|
|
<url>ws/17.0.0/20800274/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.5.2/4638234/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>12.0.0</version> |
|
|
<url>ws/12.5.3/5115892/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>17.0.0</version> |
|
|
<url>ws/17.5.2/23775571/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>14.0.0</version> |
|
|
<url>ws/14.1.3/9474260/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>17.0.0</version> |
|
|
<url>ws/17.5.1/23298084/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>16.0.0</version> |
|
|
<url>ws/16.2.0/18760230/linux/core/</url> |
|
|
</metadata> |
|
|
<metadata> |
|
|
<version>16.0.0</version> |
|
|
<url>ws/16.1.2/17966106/linux/core/</url> |
|
|
</metadata> |
|
|
</metalist> |
|
|
EOF |
|
|
|
|
|
KEEP_COMPRESSED=false |
|
|
USER_VERSION="" |
|
|
VERSION="" |
|
|
BUILD="" |
|
|
|
|
|
while getopts "kv:" opt; do |
|
|
case $opt in |
|
|
k) KEEP_COMPRESSED=true ;; |
|
|
v) USER_VERSION=$OPTARG ;; |
|
|
*) echo "Usage: $0 [-k] [-v VERSION]" >&2; exit 1 ;; |
|
|
esac |
|
|
done |
|
|
|
|
|
requirements_check() { |
|
|
command -v curl >/dev/null 2>&1 || { echo "Error: curl is required but not installed." >&2; exit 1; } |
|
|
command -v grep >/dev/null 2>&1 || { echo "Error: grep is required but not installed." >&2; exit 1; } |
|
|
command -v awk >/dev/null 2>&1 || { echo "Error: awk is required but not installed." >&2; exit 1; } |
|
|
command -v sed >/dev/null 2>&1 || { echo "Error: sed is required but not installed." >&2; exit 1; } |
|
|
command -v tar >/dev/null 2>&1 || { echo "Error: tar is required but not installed." >&2; exit 1; } |
|
|
command -v sort >/dev/null 2>&1 || { echo "Error: sort is required but not installed." >&2; exit 1; } |
|
|
} |
|
|
|
|
|
requirements_check |
|
|
|
|
|
if [[ $(uname | tr '[:upper:]' '[:lower:]') != "linux"* ]]; then |
|
|
KEEP_COMPRESSED=true |
|
|
echo "Warning: Not running on Linux. Keeping file compressed." >&2 |
|
|
fi |
|
|
|
|
|
if sort --version 2>/dev/null | grep -q "GNU coreutils"; then |
|
|
SORT_CMD="sort -V" |
|
|
SORT_UNIQUE_CMD="sort -uV" |
|
|
else |
|
|
SORT_CMD="sort -t. -k1,1n -k2,2n -k3,3n -k4,4n" |
|
|
SORT_UNIQUE_CMD="sort -t. -k1,1n -k2,2n -k3,3n -k4,4n -u" |
|
|
fi |
|
|
|
|
|
version_gte() { |
|
|
printf '%s\n%s\n' "$1" "$2" | eval "$SORT_CMD" | head -n 1 | grep -q "^$2$" |
|
|
} |
|
|
|
|
|
get_base_versions() { |
|
|
echo "$XML_DATA" | awk ' |
|
|
BEGIN {FS="[<>]"} |
|
|
/<version>/ { |
|
|
if ($3 ~ /^[0-9]+\.0\.0$/) { |
|
|
print $3; |
|
|
} |
|
|
}' | eval "$SORT_UNIQUE_CMD" |
|
|
} |
|
|
|
|
|
get_full_versions_and_builds() { |
|
|
local selected_base_major="$1" |
|
|
local major_version_prefix=$(echo "$selected_base_major" | cut -d'.' -f1) |
|
|
|
|
|
echo "$XML_DATA" | awk -v target_major="$major_version_prefix" ' |
|
|
BEGIN { |
|
|
in_metadata = 0; |
|
|
current_version_tag = ""; |
|
|
} |
|
|
/<metadata>/ { in_metadata = 1; current_version_tag = ""; } |
|
|
/<\/metadata>/ { in_metadata = 0; } |
|
|
|
|
|
in_metadata && /<version>/ { |
|
|
current_version_tag = $0; |
|
|
gsub(/.*<version>|<\/version>.*/, "", current_version_tag); |
|
|
} |
|
|
|
|
|
in_metadata && /<url>/ { |
|
|
url_tag=$0; |
|
|
gsub(/.*<url>ws\/|<\/url>.*/, "", url_tag); |
|
|
split(url_tag, parts, "/"); |
|
|
|
|
|
if (current_version_tag == target_major ".0.0" && parts[1] ~ "^" target_major "\\..*") { |
|
|
print parts[1], parts[2]; |
|
|
} |
|
|
}' | eval "$SORT_UNIQUE_CMD" |
|
|
} |
|
|
|
|
|
get_specific_version_and_build() { |
|
|
local target_version="$1" |
|
|
local target_major_prefix=$(echo "$target_version" | cut -d'.' -f1) |
|
|
|
|
|
echo "$XML_DATA" | awk -v target_ver="$target_version" -v target_major_prefix_awk="$target_major_prefix" ' |
|
|
BEGIN { |
|
|
FS="[<>]"; |
|
|
current_version_tag_content = ""; |
|
|
} |
|
|
/<metadata>/ { current_version_tag_content = ""; } |
|
|
/<version>/ { current_version_tag_content = $3; } |
|
|
/<url>/ { |
|
|
if (current_version_tag_content == target_major_prefix_awk ".0.0") { |
|
|
split($3, url_parts, "/"); |
|
|
full_version = url_parts[2]; |
|
|
build_number = url_parts[3]; |
|
|
|
|
|
if (full_version == target_ver) { |
|
|
print full_version, build_number; |
|
|
exit; |
|
|
} |
|
|
} |
|
|
}' |
|
|
} |
|
|
|
|
|
check_url() { |
|
|
local url=$1 |
|
|
curl -s --head --connect-to "$CDN_MIRROR" "$url" | head -n 1 | grep "200" >/dev/null |
|
|
} |
|
|
|
|
|
if [[ -n "$USER_VERSION" ]]; then |
|
|
version_gte "${USER_VERSION}" "12.0.0" || { echo "Error: Specified version ${USER_VERSION} is not supported. Workstation 12.0.0 or higher is required." >&2; exit 1; } |
|
|
|
|
|
read -r VERSION BUILD <<< "$(get_specific_version_and_build "$USER_VERSION")" |
|
|
|
|
|
[[ -z "$VERSION" || -z "$BUILD" ]] && { echo "Error: Version ${USER_VERSION} not found in the embedded XML data or URL format is unexpected." >&2; exit 1; } |
|
|
else |
|
|
echo "Available base versions:" |
|
|
base_versions_array=() |
|
|
while IFS= read -r line; do |
|
|
base_versions_array+=("$line") |
|
|
done < <(get_base_versions) |
|
|
|
|
|
[[ ${#base_versions_array[@]} -eq 0 ]] && { echo "No base versions found in XML data. Exiting." >&2; exit 1; } |
|
|
|
|
|
PS3="Select a base version: " |
|
|
select base_version_selected in "${base_versions_array[@]}"; do |
|
|
[[ -n "$base_version_selected" ]] && break || echo "Invalid selection. Please try again." |
|
|
done |
|
|
|
|
|
echo "Available full versions for base version $base_version_selected:" |
|
|
full_versions_builds_array=() |
|
|
while IFS= read -r line; do |
|
|
full_versions_builds_array+=("$line") |
|
|
done < <(get_full_versions_and_builds "$base_version_selected") |
|
|
|
|
|
[[ ${#full_versions_builds_array[@]} -eq 0 ]] && { echo "No full versions found for base version $base_version_selected. Exiting." >&2; exit 1; } |
|
|
|
|
|
declare -a display_full_versions |
|
|
for item in "${full_versions_builds_array[@]}"; do |
|
|
display_full_versions+=("$(echo "$item" | awk '{print $1}')") |
|
|
done |
|
|
|
|
|
IFS=$'\n' sorted_display_full_versions=($(printf "%s\n" "${display_full_versions[@]}" | eval "$SORT_CMD")) |
|
|
unset IFS |
|
|
|
|
|
PS3="Select a full version: " |
|
|
select full_version_selected in "${sorted_display_full_versions[@]}"; do |
|
|
[[ -n "$full_version_selected" ]] && break || echo "Invalid selection. Please try again." |
|
|
done |
|
|
|
|
|
for item in "${full_versions_builds_array[@]}"; do |
|
|
read -r ver build_num <<< "$item" |
|
|
[[ "$ver" == "$full_version_selected" ]] && { BUILD="$build_num"; break; } |
|
|
done |
|
|
|
|
|
[[ -z "$BUILD" ]] && { echo "Error: Could not find build number for version '$full_version_selected'. This can happen if selection is invalid." >&2; exit 1; } |
|
|
|
|
|
VERSION="$full_version_selected" |
|
|
fi |
|
|
|
|
|
echo "Selected version: $VERSION with build: $BUILD" |
|
|
|
|
|
DOWNLOAD_URL="${BASE_URL}ws/${VERSION}/${BUILD}/linux/core/VMware-Workstation-${VERSION}-${BUILD}.x86_64.bundle.tar" |
|
|
DOWNLOAD_DIR="${HOME}" |
|
|
DOWNLOAD_FILE="${DOWNLOAD_DIR}/VMware-Workstation-${VERSION}-${BUILD}.x86_64.bundle.tar" |
|
|
EXTRACT_DIR="${DOWNLOAD_DIR}/VMware-Workstation-${VERSION}-${BUILD}" |
|
|
BUNDLE_PATH="${EXTRACT_DIR}/VMware-Workstation-${VERSION}-${BUILD}.x86_64.bundle" |
|
|
|
|
|
echo "Downloading VMware Workstation v${VERSION} (${BUILD})..." |
|
|
mkdir -p "${DOWNLOAD_DIR}" |
|
|
|
|
|
check_url "$DOWNLOAD_URL" || { echo "Error: Installer file not found at $DOWNLOAD_URL even via CDN. Please check the version/build or XML data." >&2; exit 1; } |
|
|
|
|
|
curl -k -q --progress-bar -f -o "${DOWNLOAD_FILE}" --connect-to "$CDN_MIRROR" "${DOWNLOAD_URL}" || { |
|
|
echo "Error: Download failed for ${DOWNLOAD_URL}." >&2 |
|
|
exit 1 |
|
|
} |
|
|
|
|
|
${KEEP_COMPRESSED} && { echo -e "\nFinished. Downloaded file location: ${DOWNLOAD_FILE}"; exit 0; } |
|
|
|
|
|
echo "Extracting tar..." |
|
|
mkdir -p "${EXTRACT_DIR}" && \ |
|
|
tar -xf "${DOWNLOAD_FILE}" -C "${EXTRACT_DIR}" || { |
|
|
echo "Error: Extraction of tar file failed and may be corrupt." >&2 |
|
|
echo "Downloaded file location: ${DOWNLOAD_FILE}" >&2 |
|
|
rm -rf "${EXTRACT_DIR}" |
|
|
exit 1 |
|
|
} |
|
|
|
|
|
echo "Cleaning up..." |
|
|
chmod +x "${EXTRACT_DIR}/VMware-Workstation-${VERSION}-${BUILD}.x86_64.bundle" |
|
|
rm -rf "${DOWNLOAD_FILE}" "${EXTRACT_DIR}/descriptor.xml" 2>/dev/null |
|
|
|
|
|
echo -e "\nFinished. You can now run the installer bundle.\nVMware Workstation bundle location: ${BUNDLE_PATH}" |