feat: add installation script
This commit is contained in:
114
install.sh
Executable file
114
install.sh
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env bash
|
||||
# ==============================================================================
|
||||
# install.sh — HanaToolbox installer
|
||||
# Downloads the latest native AOT binary from Gitea and installs it.
|
||||
# Optionally runs the onboarding wizard for first-time setup.
|
||||
#
|
||||
# Usage:
|
||||
# curl -fsSL https://git.technopunk.space/tomi/HanaToolbox/raw/branch/main/install.sh | bash
|
||||
# # or with onboard:
|
||||
# curl -fsSL .../install.sh | bash -s -- --onboard
|
||||
# ==============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
# ── Config ────────────────────────────────────────────────────────────────────
|
||||
REPO_API="https://git.technopunk.space/api/v1/repos/tomi/HanaToolbox/releases/latest"
|
||||
BINARY_NAME="hanatoolbox"
|
||||
INSTALL_DIR="/usr/local/bin"
|
||||
INSTALL_PATH="${INSTALL_DIR}/${BINARY_NAME}"
|
||||
|
||||
# ── Colours ───────────────────────────────────────────────────────────────────
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'; RESET='\033[0m'
|
||||
|
||||
info() { echo -e "${CYAN}ℹ $*${RESET}"; }
|
||||
success() { echo -e "${GREEN}✅ $*${RESET}"; }
|
||||
warn() { echo -e "${YELLOW}⚠ $*${RESET}"; }
|
||||
error() { echo -e "${RED}❌ $*${RESET}" >&2; exit 1; }
|
||||
|
||||
# ── Arg parsing ───────────────────────────────────────────────────────────────
|
||||
RUN_ONBOARD=false
|
||||
for arg in "$@"; do
|
||||
[[ "$arg" == "--onboard" ]] && RUN_ONBOARD=true
|
||||
done
|
||||
|
||||
# ── Root check ────────────────────────────────────────────────────────────────
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
error "This installer must be run as root (sudo or root shell)."
|
||||
fi
|
||||
|
||||
# ── Dependency check ──────────────────────────────────────────────────────────
|
||||
for tool in curl jq; do
|
||||
if ! command -v "$tool" &>/dev/null; then
|
||||
error "Required tool '${tool}' is not installed. Install it and re-run."
|
||||
fi
|
||||
done
|
||||
|
||||
# ── Fetch latest release info ─────────────────────────────────────────────────
|
||||
info "Fetching latest release from Gitea..."
|
||||
RELEASE_JSON=$(curl -fsSL "$REPO_API") \
|
||||
|| error "Failed to fetch release info from ${REPO_API}"
|
||||
|
||||
TAG=$(echo "$RELEASE_JSON" | jq -r '.tag_name') \
|
||||
|| error "Could not parse tag_name from release JSON."
|
||||
|
||||
if [[ -z "$TAG" || "$TAG" == "null" ]]; then
|
||||
error "No release found in the repository yet. Publish a release first."
|
||||
fi
|
||||
|
||||
info "Latest release: ${TAG}"
|
||||
|
||||
# ── Find the binary asset ─────────────────────────────────────────────────────
|
||||
DOWNLOAD_URL=$(echo "$RELEASE_JSON" \
|
||||
| jq -r --arg name "$BINARY_NAME" \
|
||||
'.assets[] | select(.name == $name) | .browser_download_url')
|
||||
|
||||
if [[ -z "$DOWNLOAD_URL" || "$DOWNLOAD_URL" == "null" ]]; then
|
||||
error "No asset named '${BINARY_NAME}' found in release ${TAG}."
|
||||
fi
|
||||
|
||||
info "Download URL: ${DOWNLOAD_URL}"
|
||||
|
||||
# ── Download ──────────────────────────────────────────────────────────────────
|
||||
TMP_FILE=$(mktemp)
|
||||
trap 'rm -f "$TMP_FILE"' EXIT
|
||||
|
||||
info "Downloading ${BINARY_NAME} ${TAG}..."
|
||||
curl -fsSL --progress-bar -o "$TMP_FILE" "$DOWNLOAD_URL" \
|
||||
|| error "Download failed."
|
||||
|
||||
# ── Install ───────────────────────────────────────────────────────────────────
|
||||
# Backup current binary if it exists
|
||||
if [[ -f "$INSTALL_PATH" ]]; then
|
||||
cp "$INSTALL_PATH" "${INSTALL_PATH}.bak"
|
||||
warn "Previous binary backed up to ${INSTALL_PATH}.bak"
|
||||
fi
|
||||
|
||||
install -m 0755 "$TMP_FILE" "$INSTALL_PATH"
|
||||
success "${BINARY_NAME} ${TAG} installed to ${INSTALL_PATH}"
|
||||
|
||||
# ── Verify ────────────────────────────────────────────────────────────────────
|
||||
if ! "$INSTALL_PATH" --help &>/dev/null; then
|
||||
warn "Binary installed but failed self-test. Check architecture compatibility."
|
||||
else
|
||||
success "Self-test passed."
|
||||
fi
|
||||
|
||||
# ── Cron entry hint ───────────────────────────────────────────────────────────
|
||||
CRON_FILE="/etc/cron.d/hanatoolbox"
|
||||
if [[ ! -f "$CRON_FILE" ]]; then
|
||||
echo -e "\n${CYAN}To enable scheduled tasks, add this cron entry:${RESET}"
|
||||
echo -e " ${YELLOW}* * * * * root ${INSTALL_PATH} cron${RESET}"
|
||||
echo -e " e.g.: echo '* * * * * root ${INSTALL_PATH} cron' > ${CRON_FILE}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# ── Onboard ───────────────────────────────────────────────────────────────────
|
||||
if [[ "$RUN_ONBOARD" == true ]]; then
|
||||
echo ""
|
||||
info "Starting onboarding wizard..."
|
||||
exec "$INSTALL_PATH" onboard
|
||||
fi
|
||||
|
||||
echo ""
|
||||
success "Installation complete! Run '${BINARY_NAME} onboard' to configure."
|
||||
Reference in New Issue
Block a user