85963dc320
REQ-043: install.sh pulls release binary from public Gitea URL. User-level default (~/.local/bin/orca), --system for system-level (/usr/local/bin/orca). Defaults to latest release; --version pins. Env-overridable GITEA_URL/OWNER/REPO for testability. REQ-044: in-place update detects existing binary, reads version via 'orca version --json', prints update message, overwrites binary, preserves namespace dir (config/db/certs). Idempotent re-install. REQ-016 (completion): README quickstart now documents the 1-liner install + --system variant + update-in-place pattern. Tests: 8/8 pass in scripts/install_test.sh (real public Gitea releases, no mock server; timeout-guarded to prevent hangs). Docs: docs/install.md covers user/system install, version pinning, in-place update, uninstall, troubleshooting. ---ci--- project: orca phase: 2 milestone: v0.5 status: verify ---/ci---
156 lines
5.0 KiB
Bash
Executable File
156 lines
5.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# install.sh — 1-liner installer for orca
|
|
#
|
|
# Usage:
|
|
# curl -fsSL https://git.cloudinit.dev/coreci/orca/raw/branch/main/scripts/install.sh | bash
|
|
# curl -fsSL https://git.cloudinit.dev/coreci/orca/raw/branch/main/scripts/install.sh | bash -s -- --system
|
|
# curl -fsSL https://git.cloudinit.dev/coreci/orca/raw/branch/main/scripts/install.sh | bash -s -- --version v0.4.2
|
|
#
|
|
# Options:
|
|
# --system Install at system level (/usr/local/bin/orca, namespace /root/.orca). Requires root.
|
|
# --version <tag> Pin a specific version (e.g. v0.4.2). Default: latest release.
|
|
# --help, -h Show this help.
|
|
#
|
|
# Behavior:
|
|
# - Downloads the release tarball from the public Gitea release URL.
|
|
# - Extracts the orca binary to the install path.
|
|
# - If an existing orca binary is found, reads its version and prints
|
|
# "updated from X to Y" (in-place update; preserves config/db/certs).
|
|
# - Idempotent: re-running with the same version reinstalls the binary.
|
|
# - Never touches the namespace dir (~/.orca or /root/.orca) — that's user state.
|
|
|
|
set -euo pipefail
|
|
|
|
GITEA_URL="${GITEA_URL:-https://git.cloudinit.dev}"
|
|
GITEA_OWNER="${GITEA_OWNER:-coreci}"
|
|
GITEA_REPO="${GITEA_REPO:-orca}"
|
|
|
|
SYSTEM=false
|
|
VERSION=""
|
|
INSTALL_BIN=""
|
|
NAMESPACE_DIR=""
|
|
|
|
err() { echo "install: error: $*" >&2; exit 1; }
|
|
info() { echo "install: $*"; }
|
|
|
|
usage() {
|
|
sed -n '2,/^$/p' "$0" | sed 's/^# \?//' >&2
|
|
exit 0
|
|
}
|
|
|
|
# --- parse args ------------------------------------------------------------
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--system) SYSTEM=true; shift ;;
|
|
--version) VERSION="${2:-}"; shift 2 ;;
|
|
--version=*) VERSION="${1#*=}"; shift ;;
|
|
--help|-h) usage ;;
|
|
*) err "unknown argument: $1 (try --help)" ;;
|
|
esac
|
|
done
|
|
|
|
# --- determine install paths ----------------------------------------------
|
|
|
|
if [ "$SYSTEM" = "true" ]; then
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
err "--system requires root (uid 0). Re-run with sudo or drop --system for user-level install."
|
|
fi
|
|
INSTALL_BIN="/usr/local/bin/orca"
|
|
NAMESPACE_DIR="/root/.orca"
|
|
else
|
|
INSTALL_BIN="${HOME}/.local/bin/orca"
|
|
NAMESPACE_DIR="${HOME}/.orca"
|
|
fi
|
|
|
|
INSTALL_DIR="$(dirname "$INSTALL_BIN")"
|
|
|
|
# --- determine version ----------------------------------------------------
|
|
|
|
if [ -z "$VERSION" ]; then
|
|
info "querying latest release from ${GITEA_URL}..."
|
|
VERSION="$(curl -fsSL "${GITEA_URL}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/releases/latest" \
|
|
| sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' \
|
|
| head -1)"
|
|
if [ -z "$VERSION" ]; then
|
|
err "could not determine latest release version from Gitea API"
|
|
fi
|
|
fi
|
|
info "version: ${VERSION}"
|
|
|
|
# --- detect arch ----------------------------------------------------------
|
|
|
|
ARCH="$(uname -m)"
|
|
case "$ARCH" in
|
|
x86_64) ARCH=amd64 ;;
|
|
aarch64|arm64) ARCH=arm64 ;;
|
|
armv7l) ARCH=armv7 ;;
|
|
*) err "unsupported architecture: ${ARCH} (supported: amd64, arm64, armv7)" ;;
|
|
esac
|
|
|
|
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
|
|
TARBALL="orca-${VERSION}-${OS}-${ARCH}.tar.gz"
|
|
|
|
# --- find asset download URL ----------------------------------------------
|
|
|
|
info "locating asset ${TARBALL}..."
|
|
ASSET_URL="$(curl -fsSL "${GITEA_URL}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/releases/tags/${VERSION}" \
|
|
| sed -n 's/.*"browser_download_url"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' \
|
|
| grep "/${TARBALL}\$" \
|
|
| head -1)"
|
|
|
|
if [ -z "$ASSET_URL" ]; then
|
|
err "could not find asset ${TARBALL} in release ${VERSION}. Check that the release exists and has a linux-${ARCH} tarball."
|
|
fi
|
|
info "asset: ${ASSET_URL}"
|
|
|
|
# --- in-place update detection -------------------------------------------
|
|
|
|
OLD_VERSION=""
|
|
if [ -x "$INSTALL_BIN" ]; then
|
|
OLD_VERSION="$("$INSTALL_BIN" version --json 2>/dev/null | sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1 || echo "")"
|
|
fi
|
|
|
|
# --- download + extract ---------------------------------------------------
|
|
|
|
TMPDIR="$(mktemp -d)"
|
|
trap 'rm -rf "$TMPDIR"' EXIT
|
|
|
|
info "downloading..."
|
|
curl -fsSL -o "${TMPDIR}/${TARBALL}" "$ASSET_URL"
|
|
|
|
info "extracting..."
|
|
tar -xzf "${TMPDIR}/${TARBALL}" -C "$TMPDIR"
|
|
|
|
if [ ! -f "${TMPDIR}/orca" ]; then
|
|
err "tarball did not contain an 'orca' binary"
|
|
fi
|
|
|
|
# --- install --------------------------------------------------------------
|
|
|
|
mkdir -p "$INSTALL_DIR"
|
|
install -m 0755 "${TMPDIR}/orca" "$INSTALL_BIN"
|
|
|
|
# --- report ---------------------------------------------------------------
|
|
|
|
if [ -n "$OLD_VERSION" ]; then
|
|
if [ "$OLD_VERSION" = "$VERSION" ]; then
|
|
info "✓ reinstalled orca ${VERSION} at ${INSTALL_BIN}"
|
|
else
|
|
info "✓ updated orca from ${OLD_VERSION} to ${VERSION} at ${INSTALL_BIN}"
|
|
fi
|
|
else
|
|
info "✓ installed orca ${VERSION} to ${INSTALL_BIN}"
|
|
fi
|
|
|
|
if [ "$SYSTEM" = "true" ]; then
|
|
info " namespace root: ${NAMESPACE_DIR} (use 'orca --system init' to initialize)"
|
|
else
|
|
info " namespace root: ${NAMESPACE_DIR} (use 'orca init' to initialize)"
|
|
if ! echo "$PATH" | grep -q "$INSTALL_DIR"; then
|
|
info " NOTE: $INSTALL_DIR is not on your PATH. Add it:"
|
|
info " export PATH=\"\$PATH:$INSTALL_DIR\""
|
|
fi
|
|
fi
|
|
|
|
info " verify: ${INSTALL_BIN} version" |