#!/bin/sh # install.sh — installer for orch-tunnel # Usage: curl -sL https://get.tunnel.threesix.ai | sh set -e REPO="orchard9/tunnel" BINARY_NAME="orch-tunnel" INSTALL_DIR="/usr/local/bin" FALLBACK_DIR="${HOME}/.local/bin" RELEASES_BASE="${RELEASES_BASE:-https://get.tunnel.threesix.ai}" # --- Helpers --- say() { printf " %s\n" "$1" >&2 } err() { printf "\n Error: %s\n\n" "$1" >&2 exit 1 } need_cmd() { if ! command -v "$1" >/dev/null 2>&1; then err "Required command not found: $1. Please install it and try again." fi } # --- Platform detection --- detect_platform() { _os="$(uname -s)" _arch="$(uname -m)" case "$_os" in Linux) _os="linux" ;; Darwin) _os="darwin" ;; *) err "Unsupported OS: ${_os}. orch-tunnel supports Linux and macOS (linux/amd64, linux/arm64, darwin/amd64, darwin/arm64). See https://github.com/${REPO}/releases for manual download options." ;; esac case "$_arch" in x86_64) _arch="amd64" ;; aarch64 | arm64) _arch="arm64" ;; *) err "Unsupported architecture: ${_arch}. orch-tunnel supports amd64 and arm64 (linux/amd64, linux/arm64, darwin/amd64, darwin/arm64). See https://github.com/${REPO}/releases for manual download options." ;; esac PLATFORM="${_os}/${_arch}" BINARY_FILENAME="${BINARY_NAME}-${_os}-${_arch}" } # --- Checksum verification --- compute_checksum() { _file="$1" if command -v sha256sum >/dev/null 2>&1; then sha256sum "$_file" | awk '{print $1}' elif command -v shasum >/dev/null 2>&1; then shasum -a 256 "$_file" | awk '{print $1}' else err "No checksum utility found (sha256sum or shasum). Cannot verify the downloaded binary." fi } # --- Cleanup --- _TMPDIR="" cleanup() { if [ -n "$_TMPDIR" ] && [ -d "$_TMPDIR" ]; then rm -rf "$_TMPDIR" fi } trap cleanup EXIT INT TERM # --- Main --- main() { say "" say "Installing ${BINARY_NAME}..." say "" need_cmd curl need_cmd uname need_cmd chmod need_cmd mv detect_platform say "Detected: ${PLATFORM}" # Check if already installed if command -v "$BINARY_NAME" >/dev/null 2>&1; then _installed_ver="$("$BINARY_NAME" --version 2>/dev/null || true)" say "Found existing installation: ${_installed_ver:-unknown version}" say "Upgrading..." fi # Create a temporary working directory _TMPDIR="$(mktemp -d 2>/dev/null || mktemp -d -t orch-tunnel)" _binary_url="${RELEASES_BASE}/${BINARY_FILENAME}" _sums_url="${RELEASES_BASE}/sha256sums.txt" _tmp_binary="${_TMPDIR}/${BINARY_FILENAME}" _tmp_sums="${_TMPDIR}/sha256sums.txt" # Download binary say "Downloading ${BINARY_NAME} (${PLATFORM})..." if ! curl --fail --location --progress-bar --output "$_tmp_binary" "$_binary_url" 2>&1; then err "Download failed from ${_binary_url}. Check your internet connection or visit https://github.com/${REPO}/releases to download manually." fi # Download checksums say "Verifying checksum..." if ! curl --fail --location --silent --output "$_tmp_sums" "$_sums_url"; then err "Failed to download checksums from ${_sums_url}. Cannot verify the binary integrity." fi _expected="$(grep "${BINARY_FILENAME}" "$_tmp_sums" 2>/dev/null | awk '{print $1}')" if [ -z "$_expected" ]; then err "Checksum not found for '${BINARY_FILENAME}' in sha256sums.txt. The release may be incomplete." fi _actual="$(compute_checksum "$_tmp_binary")" if [ "$_actual" != "$_expected" ]; then err "Checksum mismatch for ${BINARY_FILENAME}. Expected: ${_expected} Got: ${_actual} The download may be corrupt or tampered with. Aborting." fi chmod +x "$_tmp_binary" # Install binary — try /usr/local/bin, then sudo, then ~/.local/bin _install_path="" _warn_path="" say "Installing to ${INSTALL_DIR}/${BINARY_NAME}..." if [ -w "$INSTALL_DIR" ]; then mv "$_tmp_binary" "${INSTALL_DIR}/${BINARY_NAME}" _install_path="${INSTALL_DIR}/${BINARY_NAME}" elif command -v sudo >/dev/null 2>&1; then say " (${INSTALL_DIR} is not writable — trying sudo)" if sudo mv "$_tmp_binary" "${INSTALL_DIR}/${BINARY_NAME}" 2>/dev/null; then _install_path="${INSTALL_DIR}/${BINARY_NAME}" else say " sudo failed or was declined — installing to ${FALLBACK_DIR}" mkdir -p "$FALLBACK_DIR" mv "$_tmp_binary" "${FALLBACK_DIR}/${BINARY_NAME}" _install_path="${FALLBACK_DIR}/${BINARY_NAME}" _warn_path=1 fi else say " (${INSTALL_DIR} is not writable — installing to ${FALLBACK_DIR})" mkdir -p "$FALLBACK_DIR" mv "$_tmp_binary" "${FALLBACK_DIR}/${BINARY_NAME}" _install_path="${FALLBACK_DIR}/${BINARY_NAME}" _warn_path=1 fi _version="$("$_install_path" --version 2>/dev/null || echo "installed")" say "" say "${BINARY_NAME} ${_version} installed successfully." say "" if [ -n "$_warn_path" ]; then say " Installed to: ${_install_path}" say " To use ${BINARY_NAME} from any directory, add ${FALLBACK_DIR} to your PATH:" say "" say " export PATH=\"\$HOME/.local/bin:\$PATH\"" say "" say " Add the above line to your ~/.profile or ~/.zshrc to make it permanent." say "" fi say "Run: ${BINARY_NAME} --url http://localhost:PORT" say "" # Print install path to stdout for scripting printf "%s\n" "$_install_path" } main "$@"