#!/bin/sh # HeliosDB Nano installer # curl -fsSL https://install.heliosdb.com | sh # curl -fsSL https://install.heliosdb.com | sh -s -- v4.41.0 # a specific release # # Downloads the prebuilt heliosdb-nano binary for this OS/CPU from the official # GitHub release (github.com/HeliosDatabase/HeliosDB-Nano), verifies it against # that release's SHA256SUMS, and installs it. Nothing is executed before the # checksum matches. # # Environment overrides: # HELIOS_VERSION release tag to install (default: the latest release) # HELIOS_INSTALL_DIR install directory (default: /usr/local/bin when root # or writable, otherwise ~/.local/bin) # HELIOS_SKIP_GLIBC_CHECK=1 install even if glibc looks older than 2.39 # # Invoked via `curl | sh`, so this stays POSIX sh (no bashisms, no `echo -e`) # and fails closed: -e aborts on any error, -u on an unset variable. set -eu REPO="HeliosDatabase/HeliosDB-Nano" GH="https://github.com/$REPO" IMAGE="ghcr.io/heliosdatabase/heliosdb-nano" VERSION="${1:-${HELIOS_VERSION:-}}" if [ -t 1 ]; then B='\033[1m'; D='\033[2m'; G='\033[0;32m'; C='\033[0;36m'; Y='\033[1;33m'; R='\033[0;31m'; N='\033[0m' else B=''; D=''; G=''; C=''; Y=''; R=''; N='' fi say() { printf '%b\n' "$*"; } info() { say "${C}==>${N} $*"; } fail() { say "${R}error:${N} $*" >&2; exit 1; } docker_hint() { say "" say " ${B}Docker (any Linux, macOS or Windows host):${N}" say " docker run -d --name heliosdb -p 5432:5432 -e HELIOSDB_PASSWORD=change-me \\" say " -v heliosdb_data:/data $IMAGE:latest" say " ${B}From source:${N} cargo install heliosdb-nano --locked" } command -v curl >/dev/null 2>&1 || fail "curl is required" command -v tar >/dev/null 2>&1 || fail "tar is required" if command -v sha256sum >/dev/null 2>&1; then SHA="sha256sum" elif command -v shasum >/dev/null 2>&1; then SHA="shasum -a 256" else fail "sha256sum or shasum is required to verify the download" fi # ---- platform ------------------------------------------------------------- OS="$(uname -s)" ARCH="$(uname -m)" case "$OS" in Linux) case "$ARCH" in x86_64|amd64) TARGET="x86_64-unknown-linux-gnu" ;; aarch64|arm64) TARGET="aarch64-unknown-linux-gnu" ;; *) say "No prebuilt binary for Linux/$ARCH."; docker_hint; exit 1 ;; esac # Release binaries are built on Ubuntu 24.04 and need glibc >= 2.39 # (Debian 13, Ubuntu 24.04, Fedora 40, RHEL 10 or newer). if ldd --version 2>&1 | grep -qi musl; then say "musl libc (e.g. Alpine) detected; the prebuilt binaries need glibc." docker_hint; exit 1 fi glibc="$(ldd --version 2>/dev/null | head -n1 | grep -oE '[0-9]+\.[0-9]+$' || true)" if [ -n "$glibc" ] && [ "${HELIOS_SKIP_GLIBC_CHECK:-0}" != "1" ]; then gmaj="${glibc%%.*}"; gmin="${glibc#*.}" if [ "$gmaj" -lt 2 ] || { [ "$gmaj" -eq 2 ] && [ "$gmin" -lt 39 ]; }; then say "This system has glibc $glibc; the prebuilt binaries need glibc 2.39 or newer." docker_hint say " ${D}(set HELIOS_SKIP_GLIBC_CHECK=1 to install anyway)${N}" exit 1 fi fi ;; Darwin) case "$ARCH" in arm64) TARGET="aarch64-apple-darwin" ;; *) say "Prebuilt macOS binaries are Apple Silicon only."; docker_hint; exit 1 ;; esac ;; *) say "Unsupported OS: $OS. On Windows, download the .zip from $GH/releases/latest" docker_hint; exit 1 ;; esac # ---- version ---------------------------------------------------------------- if [ -z "$VERSION" ]; then info "resolving the latest release" # Follow github.com's /releases/latest redirect instead of the rate-limited API. latest_url="$(curl -fsSLI --proto '=https' --tlsv1.2 -o /dev/null -w '%{url_effective}' "$GH/releases/latest")" \ || fail "could not reach github.com" VERSION="${latest_url##*/}" fi case "$VERSION" in v*) : ;; *) VERSION="v$VERSION" ;; esac echo "$VERSION" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$' \ || fail "not a release tag: $VERSION" ASSET="heliosdb-nano-${VERSION}-${TARGET}.tar.gz" BASE="$GH/releases/download/$VERSION" # ---- download + verify ---------------------------------------------------------- TMP="$(mktemp -d)" trap 'rm -rf "$TMP"' EXIT INT TERM info "downloading $ASSET" curl -fsSL --proto '=https' --tlsv1.2 -o "$TMP/$ASSET" "$BASE/$ASSET" \ || fail "download failed: $BASE/$ASSET" curl -fsSL --proto '=https' --tlsv1.2 -o "$TMP/SHA256SUMS" "$BASE/SHA256SUMS" \ || fail "download failed: $BASE/SHA256SUMS" info "verifying SHA-256 checksum" expected="$(awk -v f="$ASSET" '$2 == f || $2 == "*" f { print $1 }' "$TMP/SHA256SUMS")" [ -n "$expected" ] || fail "$ASSET is not listed in SHA256SUMS" actual="$(cd "$TMP" && $SHA "$ASSET" | awk '{print $1}')" [ "$expected" = "$actual" ] || fail "checksum mismatch for $ASSET (expected $expected, got $actual)" tar -xzf "$TMP/$ASSET" -C "$TMP" heliosdb-nano chmod 755 "$TMP/heliosdb-nano" # ---- install -------------------------------------------------------------------- if [ -n "${HELIOS_INSTALL_DIR:-}" ]; then DIR="$HELIOS_INSTALL_DIR" elif [ "$(id -u)" -eq 0 ] || [ -w /usr/local/bin ]; then DIR="/usr/local/bin" else DIR="$HOME/.local/bin" fi mkdir -p "$DIR" mv -f "$TMP/heliosdb-nano" "$DIR/heliosdb-nano" info "installed $("$DIR/heliosdb-nano" --version) to $DIR/heliosdb-nano" case ":$PATH:" in *":$DIR:"*) : ;; *) say "${Y}note:${N} $DIR is not on your PATH; add: export PATH=\"$DIR:\$PATH\"" ;; esac say "" say " ${G}${B}HeliosDB Nano $VERSION is ready.${N}" say "" say " Try it: heliosdb-nano repl --memory" say " Run a server: heliosdb-nano start --data-dir ./data" say " psql postgresql://localhost:5432/postgres" say "" say " ${D}Docs: https://www.heliosdb.com/docs/nano/${N}" say " ${D}Releases: $GH/releases${N}" say " ${D}Docker: $IMAGE:latest${N}" say " ${D}Playground: https://www.heliosdb.com/playground.html${N}" say ""