#!/bin/sh # Backup Ring agent installer # Usage: curl -fsSL https://get.backupring.app | sh # # Options (env vars): # BACKUPRING_VERSION - specific version to install (default: latest) # BACKUPRING_DIR - install directory (default: ~/.local/bin) set -e REPO="backup-rings/repo" API_URL="https://api.backupring.app" BINARY_NAME="backupring" # --- Platform detection --- detect_os() { case "$(uname -s)" in Linux*) echo "linux" ;; Darwin*) echo "darwin" ;; *) echo "unsupported"; return 1 ;; esac } detect_arch() { case "$(uname -m)" in x86_64|amd64) echo "amd64" ;; aarch64|arm64) echo "arm64" ;; *) echo "unsupported"; return 1 ;; esac } # --- Helpers --- info() { printf ' \033[1;32m%s\033[0m %s\n' "$1" "$2"; } warn() { printf ' \033[1;33m%s\033[0m %s\n' "$1" "$2"; } error() { printf ' \033[1;31m%s\033[0m %s\n' "error:" "$1" >&2; exit 1; } need_cmd() { if ! command -v "$1" > /dev/null 2>&1; then error "need '$1' (command not found)" fi } # --- Main --- main() { need_cmd uname need_cmd curl OS=$(detect_os) || error "unsupported operating system: $(uname -s)" ARCH=$(detect_arch) || error "unsupported architecture: $(uname -m)" info "platform:" "${OS}/${ARCH}" # Resolve version if [ -n "$BACKUPRING_VERSION" ]; then VERSION="$BACKUPRING_VERSION" else info "fetching:" "latest version" VERSION=$(curl -fsSL "${API_URL}/v1/releases/latest" | grep -o '"version":"[^"]*"' | head -1 | cut -d'"' -f4) if [ -z "$VERSION" ]; then # Fallback: check GitHub releases VERSION=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" | grep -o '"tag_name":"[^"]*"' | head -1 | cut -d'"' -f4) VERSION="${VERSION#v}" fi if [ -z "$VERSION" ]; then error "could not determine latest version" fi fi info "version:" "$VERSION" # Install directory INSTALL_DIR="${BACKUPRING_DIR:-$HOME/.local/bin}" mkdir -p "$INSTALL_DIR" # Download URL ARCHIVE="${BINARY_NAME}-v${VERSION}-${OS}-${ARCH}.tar.gz" DOWNLOAD_URL="https://github.com/${REPO}/releases/download/v${VERSION}/${ARCHIVE}" info "downloading:" "$DOWNLOAD_URL" TMPDIR=$(mktemp -d) trap 'rm -rf "$TMPDIR"' EXIT curl -fsSL "$DOWNLOAD_URL" -o "${TMPDIR}/${ARCHIVE}" # Verify checksum if available CHECKSUM_URL="https://github.com/${REPO}/releases/download/v${VERSION}/checksums.txt" if curl -fsSL "$CHECKSUM_URL" -o "${TMPDIR}/checksums.txt" 2>/dev/null; then EXPECTED=$(grep "$ARCHIVE" "${TMPDIR}/checksums.txt" | awk '{print $1}') if [ -n "$EXPECTED" ]; then if command -v b3sum > /dev/null 2>&1; then ACTUAL=$(b3sum "${TMPDIR}/${ARCHIVE}" | awk '{print $1}') if [ "$ACTUAL" != "$EXPECTED" ]; then error "checksum mismatch: expected ${EXPECTED}, got ${ACTUAL}" fi info "checksum:" "verified (blake3)" elif command -v sha256sum > /dev/null 2>&1; then warn "note:" "b3sum not found, skipping checksum verification" fi fi fi # Extract and install tar -xzf "${TMPDIR}/${ARCHIVE}" -C "$TMPDIR" mv "${TMPDIR}/${BINARY_NAME}" "${INSTALL_DIR}/${BINARY_NAME}" chmod +x "${INSTALL_DIR}/${BINARY_NAME}" info "installed:" "${INSTALL_DIR}/${BINARY_NAME}" # Check if install dir is in PATH case ":${PATH}:" in *":${INSTALL_DIR}:"*) ;; *) warn "note:" "${INSTALL_DIR} is not in your PATH" echo "" echo " Add it with:" echo " export PATH=\"${INSTALL_DIR}:\$PATH\"" echo "" echo " Or add to your shell profile (~/.bashrc, ~/.zshrc, etc.):" echo " echo 'export PATH=\"${INSTALL_DIR}:\$PATH\"' >> ~/.bashrc" ;; esac echo "" info "done!" "Run 'backupring init' to get started." echo "" } main "$@"