Files
openobserve/downloadO2.sh
T

170 lines
5.8 KiB
Bash
Executable File

#!/bin/sh
# Downloads an OpenObserve release binary.
#
# curl -L https://raw.githubusercontent.com/openobserve/openobserve/main/downloadO2.sh | sh -s [edition] [version]
#
# edition: opensource | enterprise (default: enterprise)
# version: e.g. v1.0.4 (default: latest release)
#
# Kept to POSIX sh: the documented one-liner pipes into `sh`, which is dash on
# Debian/Ubuntu, so bash-only syntax (e.g. `==` inside `[ ]`) silently misbehaves.
BASE_URL="https://downloads.openobserve.ai/releases"
REPO_URL="https://github.com/openobserve/openobserve"
RELEASES_API="https://api.github.com/repos/openobserve/openobserve/releases?per_page=30"
# Bounded network calls, so a dropped connection fails fast instead of hanging.
NET="--connect-timeout 10 --max-time 30"
usage() {
echo "Usage: sh downloadO2.sh [opensource|enterprise] [version]" >&2
echo "Example: sh downloadO2.sh opensource v1.0.4" >&2
}
# 1. Edition (default: enterprise). An unknown value is an error, not a
# silent fallback, so a typo never downloads the wrong edition.
case "${1:-enterprise}" in
opensource|oss)
EDITION="opensource"
URL="${BASE_URL}/openobserve"
BINARY_NAME="openobserve"
;;
enterprise|o2-enterprise|ee)
EDITION="enterprise"
URL="${BASE_URL}/o2-enterprise"
BINARY_NAME="openobserve-ee"
;;
*)
echo "Error: unknown edition '$1'." >&2
usage
exit 1
;;
esac
echo "Edition: $EDITION"
# 2. Detect platform
echo "Detecting platform..."
case "$(uname -s)" in
Linux*) PLATFORM="linux" ;;
Darwin*) PLATFORM="darwin" ;;
CYGWIN*|MINGW32*|MSYS*|MINGW*) PLATFORM="windows" ;;
*) echo "Error: unsupported platform '$(uname -s)'." >&2; exit 1 ;;
esac
echo "Platform: $PLATFORM"
# 3. Detect architecture (and musl libc, e.g. Alpine, which needs its own build)
echo "Detecting architecture..."
ARCH=$(uname -m)
case "$ARCH" in
x86_64|amd64) ARCH="amd64" ;;
arm64|aarch64) ARCH="arm64" ;;
*) echo "Error: unsupported architecture '$ARCH'." >&2; exit 1 ;;
esac
LIBC=""
if [ "$PLATFORM" = "linux" ] && { ls /lib/ld-musl-* >/dev/null 2>&1 || ldd --version 2>&1 | grep -qi musl; }; then
LIBC="-musl"
fi
echo "Architecture: $ARCH$LIBC"
# Builds that are never published: say so, rather than probing every release.
case "$EDITION/$PLATFORM/$ARCH$LIBC" in
enterprise/darwin/amd64|*/windows/arm64|enterprise/linux/arm64-musl)
echo "Error: no $EDITION build is published for $PLATFORM-$ARCH$LIBC." >&2
[ "$EDITION" = "enterprise" ] && echo "The opensource edition may be available: sh -s opensource" >&2
exit 1
;;
esac
# Windows builds ship as .zip, everything else as .tar.gz.
EXT="tar.gz"
[ "$PLATFORM" = "windows" ] && EXT="zip"
artifact_url() {
echo "${URL}/$1/${BINARY_NAME}-$1-${PLATFORM}-${ARCH}${LIBC}.${EXT}"
}
# 4. Version (default: the newest stable release with a build for this
# edition/platform). The first release GitHub lists is not always it:
# backports of older lines can be published after a newer release, release
# candidates are not marked as pre-releases, and the enterprise build is
# uploaded some time after the release is published.
VERSION=$2
[ "$VERSION" = "latest" ] && VERSION=""
if [ -z "$VERSION" ]; then
echo "Resolving latest version..."
# Split on commas so parsing works whether or not GitHub pretty-prints.
# shellcheck disable=SC2086
TAGS=$(curl -fsSL $NET -A downloadO2.sh "$RELEASES_API" 2>/dev/null \
| tr ',' '\n' \
| sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\(v[0-9][0-9.]*\)".*/\1/p' \
| sed 's/^v//' | sort -u -t. -k1,1nr -k2,2nr -k3,3nr | sed 's/^/v/')
if [ -z "$TAGS" ]; then
# API unreachable or rate-limited: fall back to the "latest release" redirect.
# shellcheck disable=SC2086
TAGS=$(curl -fsSI $NET "$REPO_URL/releases/latest" 2>/dev/null \
| tr -d '\r' | sed -n 's#^[Ll]ocation:.*/tag/\(v[0-9][0-9.]*\)$#\1#p')
fi
if [ -z "$TAGS" ]; then
echo "Error: could not determine the latest release (offline or rate-limited?); pass a version explicitly." >&2
usage
exit 1
fi
for TAG in $TAGS; do
# shellcheck disable=SC2086
if curl -fsIL $NET "$(artifact_url "$TAG")" >/dev/null 2>&1; then
VERSION=$TAG
break
fi
done
if [ -z "$VERSION" ]; then
echo "Error: none of the recent releases has a $EDITION build for $PLATFORM-$ARCH$LIBC yet; pass a version explicitly." >&2
exit 1
fi
fi
# Release tags are v-prefixed; accept "1.0.4" and "V1.0.4" as well as "v1.0.4".
case "$VERSION" in
v*) ;;
V*) VERSION="v${VERSION#V}" ;;
*) VERSION="v$VERSION" ;;
esac
echo "Version: $VERSION"
# 5. Download
DOWNLOAD_URL=$(artifact_url "$VERSION")
ARCHIVE="latest_release.${EXT}"
trap 'rm -f "$ARCHIVE"' INT TERM
echo "Downloading: $DOWNLOAD_URL"
if ! curl -fLo "$ARCHIVE" "$DOWNLOAD_URL"; then
echo "Error: Download failed. Check that $VERSION has a $EDITION build for $PLATFORM-$ARCH$LIBC." >&2
rm -f "$ARCHIVE"
exit 1
fi
# 6. Extract and clean up
echo "Extracting..."
if [ "$EXT" = "zip" ]; then
# GNU tar (first on Git Bash/Cygwin's PATH) cannot read zips; Windows' own tar can.
WIN_TAR=""
if command -v cygpath >/dev/null 2>&1 && [ -n "$SYSTEMROOT" ]; then
WIN_TAR="$(cygpath -u "$SYSTEMROOT")/System32/tar.exe"
fi
if command -v unzip >/dev/null 2>&1; then
unzip -o -q "$ARCHIVE"
elif [ -n "$WIN_TAR" ] && [ -x "$WIN_TAR" ]; then
"$WIN_TAR" -xf "$ARCHIVE"
else
echo "Error: extracting the .zip needs 'unzip'; install it and retry." >&2
false
fi
else
tar -xzf "$ARCHIVE"
fi
STATUS=$?
rm -f "$ARCHIVE"
if [ "$STATUS" -ne 0 ]; then
echo "Error: extraction failed." >&2
exit 1
fi
echo "✅ Download and extraction complete!"