Update tools.func

This commit is contained in:
CanbiZ 2025-06-02 15:23:33 +02:00
parent 6377c7d468
commit 97978c2272

View File

@ -675,22 +675,6 @@ install_mongodb() {
msg_ok "MongoDB $MONGO_VERSION installed and started"
}
install_from_gh_release() {
local app="$1"
local repo="$2"
local mode="${3:-source}" # Default: source
local version="${4:-}" # Default: latest
local deb_name="${5:-}" # Default: empty
APP="$app"
INSTALL_DIR="/opt/$app"
VERSION="$version"
SOURCE_PACKAGE="$deb_name"
BUILD_SOURCE=$([[ "$mode" == "binary" ]] && echo 0 || echo 1)
fetch_and_deploy_gh_release "$repo"
}
# ------------------------------------------------------------------------------
# Downloads and deploys latest GitHub release tarball.
#
@ -705,22 +689,24 @@ install_from_gh_release() {
# ------------------------------------------------------------------------------
fetch_and_deploy_gh_release() {
local repo="$1"
local raw_app="${APP:-$APPLICATION}"
local app=$(echo "${raw_app,,}" | tr -d ' ')
local api_url="https://api.github.com/repos/$repo/releases/latest"
local header=()
local attempt=0
local max_attempts=3
local api_response tag http_code
local current_version=""
local app="$1"
local repo="$2"
local mode="${3:-tarball}" # tarball | source | binary
local version="${4:-latest}" # optional, default "latest"
local target="${5:-/opt/$app}" # optional target dir
local app_lc=$(echo "${app,,}" | tr -d ' ')
local version_file="$HOME/.${app_lc}/${app_lc}_version.txt"
local curl_timeout="--connect-timeout 10 --max-time 30"
# Check if the app directory exists and if there's a version file
if [[ -f "/opt/${app}_version.txt" ]]; then
current_version=$(cat "/opt/${app}_version.txt")
mkdir -p "$(dirname "$version_file")"
local current_version=""
if [[ -f "$version_file" ]]; then
current_version=$(<"$version_file")
$STD msg_info "Current version: $current_version"
fi
# ensure that jq is installed
if ! command -v jq &>/dev/null; then
$STD msg_info "Installing jq..."
$STD apt-get update -qq &>/dev/null
@ -729,136 +715,97 @@ fetch_and_deploy_gh_release() {
return 1
}
fi
local api_url="https://api.github.com/repos/$repo/releases"
[[ "$version" != "latest" ]] && api_url="$api_url/tags/$version" || api_url="$api_url/latest"
local header=()
[[ -n "${GITHUB_TOKEN:-}" ]] && header=(-H "Authorization: token $GITHUB_TOKEN")
until [[ $attempt -ge $max_attempts ]]; do
((attempt++)) || true
$STD msg_info "[$attempt/$max_attempts] Fetching GitHub release for $repo...\n"
api_response=$(curl $curl_timeout -fsSL -w "%{http_code}" -o /tmp/gh_resp.json "${header[@]}" "$api_url")
http_code="${api_response:(-3)}"
if [[ "$http_code" == "404" ]]; then
msg_error "Repository $repo has no Release candidate (404)"
return 1
fi
if [[ "$http_code" != "200" ]]; then
$STD msg_info "Request failed with HTTP $http_code, retrying...\n"
sleep $((attempt * 2))
continue
fi
api_response=$(</tmp/gh_resp.json)
if echo "$api_response" | grep -q "API rate limit exceeded"; then
msg_error "GitHub API rate limit exceeded."
return 1
fi
if echo "$api_response" | jq -e '.message == "Not Found"' &>/dev/null; then
msg_error "Repository not found: $repo"
return 1
fi
tag=$(echo "$api_response" | jq -r '.tag_name // .name // empty')
[[ "$tag" =~ ^v[0-9] ]] && tag="${tag:1}"
version="${tag#v}"
if [[ -z "$tag" ]]; then
$STD msg_info "Empty tag received, retrying...\n"
sleep $((attempt * 2))
continue
fi
$STD msg_ok "Found release: $tag for $repo"
break
done
if [[ -z "$tag" ]]; then
msg_error "Failed to fetch release for $repo after $max_attempts attempts."
exit 1
fi
# Version comparison (if we already have this version, skip)
if [[ "$current_version" == "$tag" ]]; then
$STD msg_info "Already running the latest version ($tag). Skipping update."
$STD msg_info "Fetching release metadata for $repo ($version)..."
local resp http_code
resp=$(curl $curl_timeout -fsSL -w "%{http_code}" -o /tmp/gh_rel.json "${header[@]}" "$api_url")
http_code="${resp:(-3)}"
[[ "$http_code" != "200" ]] && {
msg_error "Failed to fetch release: HTTP $http_code"
return 1
}
local json
json=$(</tmp/gh_rel.json)
local tag_name
tag_name=$(echo "$json" | jq -r '.tag_name // .name // empty')
[[ "$tag_name" =~ ^v ]] && version="${tag_name:1}" || version="$tag_name"
if [[ "$current_version" == "$version" ]]; then
$STD msg_info "Already on latest version ($version)"
return 0
fi
local base_url="https://github.com/$repo/releases/download/v$tag"
local tmpdir
tmpdir=$(mktemp -d) || return 1
# Extract list of assets from the Release API
local assets urls
assets=$(echo "$api_response" | jq -r '.assets[].browser_download_url') || true
# Detect current architecture
local arch
if command -v dpkg &>/dev/null; then
arch=$(dpkg --print-architecture)
elif command -v uname &>/dev/null; then
case "$(uname -m)" in
x86_64) arch="amd64" ;;
aarch64) arch="arm64" ;;
armv7l) arch="armv7" ;;
armv6l) arch="armv6" ;;
*) arch="unknown" ;;
esac
else
arch="unknown"
fi
$STD msg_info "Detected system architecture: $arch"
# Try to find a matching asset for our architecture
local filename=""
local url=""
for u in $assets; do
if [[ "$u" =~ $arch.*\.tar\.gz$ ]]; then
url="$u"
$STD msg_info "Found matching architecture asset: $url"
break
fi
done
# Fallback to other architectures if our specific one isn't found
if [[ -z "$url" ]]; then
if [[ "$mode" == "tarball" || "$mode" == "source" ]]; then
url=$(echo "$json" | jq -r '.tarball_url // empty')
[[ -z "$url" ]] && url="https://github.com/$repo/archive/refs/tags/v$version.tar.gz"
filename="${app_lc}-${version}.tar.gz"
$STD msg_info "Downloading source tarball: $url"
curl $curl_timeout -fsSL -o "$tmpdir/$filename" "$url" || {
msg_error "Download failed: $url"
rm -rf "$tmpdir"
return 1
}
mkdir -p "$target"
tar -xzf "$tmpdir/$filename" -C "$tmpdir"
local unpack_dir
unpack_dir=$(find "$tmpdir" -mindepth 1 -maxdepth 1 -type d | head -n1)
shopt -s dotglob nullglob
cp -r "$unpack_dir"/* "$target/"
shopt -u dotglob nullglob
elif [[ "$mode" == "binary" ]]; then
local arch
arch=$(dpkg --print-architecture 2>/dev/null || uname -m)
[[ "$arch" == "x86_64" ]] && arch="amd64"
[[ "$arch" == "aarch64" ]] && arch="arm64"
local assets url_match
assets=$(echo "$json" | jq -r '.assets[].browser_download_url')
for u in $assets; do
if [[ "$u" =~ (x86_64|amd64|arm64|armv7|armv6).*\.tar\.gz$ ]]; then
url="$u"
$STD msg_info "Architecture-specific asset not found, using: $url"
if [[ "$u" =~ $arch.*\.deb$ ]]; then
url_match="$u"
break
fi
done
fi
# Fallback to any tar.gz
if [[ -z "$url" ]]; then
for u in $assets; do
if [[ "$u" =~ \.tar\.gz$ ]]; then
url="$u"
$STD msg_info "Using generic tarball: $url"
break
fi
done
fi
# Final fallback to GitHub source tarball
if [[ -z "$url" ]]; then
# Use tarball_url directly from API response instead of constructing our own URL
url=$(echo "$api_response" | jq -r '.tarball_url // empty')
# If tarball_url is empty for some reason, fall back to a constructed URL as before
if [[ -z "$url" ]]; then
url="https://github.com/$repo/archive/refs/tags/v$version.tar.gz"
if [[ -z "$url_match" ]]; then
msg_error "No matching .deb asset for arch '$arch'"
rm -rf "$tmpdir"
return 1
fi
$STD msg_info "Using GitHub source tarball: $url"
fi
local filename="${url##*/}"
$STD msg_info "Downloading $url"
if ! curl $curl_timeout -fsSL -o "$tmpdir/$filename" "$url"; then
msg_error "Failed to download release asset from $url"
filename="${url_match##*/}"
$STD msg_info "Downloading binary .deb: $url_match"
curl $curl_timeout -fsSL -o "$tmpdir/$filename" "$url_match" || {
msg_error "Download failed: $url_match"
rm -rf "$tmpdir"
return 1
}
$STD msg_info "Installing $filename via apt"
apt-get install -y "$tmpdir/$filename" || {
msg_error "Failed to install $filename"
rm -rf "$tmpdir"
return 1
}
else
msg_error "Unknown mode: $mode"
rm -rf "$tmpdir"
return 1
fi
mkdir -p "/opt/$app"
tar -xzf "$tmpdir/$filename" -C "$tmpdir"
local content_root
content_root=$(find "$tmpdir" -mindepth 1 -maxdepth 1 -type d)
if [[ $(echo "$content_root" | wc -l) -eq 1 ]]; then
shopt -s dotglob nullglob
cp -r "$content_root"/* "/opt/$app/"
shopt -u dotglob nullglob
else
shopt -s dotglob nullglob
cp -r "$tmpdir"/* "/opt/$app/"
shopt -u dotglob nullglob
fi
echo "$version" >"/opt/${app}_version.txt"
$STD msg_ok "Deployed $app v$version to /opt/$app"
echo "$version" >"$version_file"
$STD msg_ok "$app deployed (version: $version)"
rm -rf "$tmpdir"
}