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