diff --git a/changelog.md b/changelog.md index d4a516b..0fae497 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2026-03-15 - 1.13.0 - feat(install) +improve installer with version selection, service restart handling, and upgrade documentation + +- Adds installer command-line options for help, specific version selection, and custom install directory. +- Fetches the latest release from the Gitea API when no version is provided and installs the matching platform binary. +- Preserves Onebox data directories, stops and restarts the systemd service during updates, and refreshes installation instructions in the README including upgrade usage. + ## 2026-03-15 - 1.12.1 - fix(package.json) update package metadata diff --git a/install.sh b/install.sh index 940c31d..77cddb6 100755 --- a/install.sh +++ b/install.sh @@ -1,192 +1,308 @@ #!/bin/bash + +# Onebox Installer Script +# Downloads and installs pre-compiled Onebox binary from Gitea releases # -# Onebox installer script +# Usage: +# Direct piped installation (recommended): +# curl -sSL https://code.foss.global/serve.zone/onebox/raw/branch/main/install.sh | sudo bash # +# With version specification: +# curl -sSL https://code.foss.global/serve.zone/onebox/raw/branch/main/install.sh | sudo bash -s -- --version v1.11.0 +# +# Options: +# -h, --help Show this help message +# --version VERSION Install specific version (e.g., v1.11.0) +# --install-dir DIR Installation directory (default: /opt/onebox) set -e -# Configuration -REPO_URL="https://code.foss.global/serve.zone/onebox" +# Default values +SHOW_HELP=0 +SPECIFIED_VERSION="" INSTALL_DIR="/opt/onebox" -BIN_LINK="/usr/local/bin/onebox" +GITEA_BASE_URL="https://code.foss.global" +GITEA_REPO="serve.zone/onebox" +SERVICE_NAME="smartdaemon_onebox" -# Colors -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color +# Parse command line arguments +while [[ $# -gt 0 ]]; do + case $1 in + -h|--help) + SHOW_HELP=1 + shift + ;; + --version) + SPECIFIED_VERSION="$2" + shift 2 + ;; + --install-dir) + INSTALL_DIR="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" + echo "Use -h or --help for usage information" + exit 1 + ;; + esac +done -# Functions -error() { - echo -e "${RED}Error: $1${NC}" >&2 - exit 1 -} - -info() { - echo -e "${GREEN}$1${NC}" -} - -warn() { - echo -e "${YELLOW}$1${NC}" -} - -# Detect platform and architecture -detect_platform() { - OS=$(uname -s | tr '[:upper:]' '[:lower:]') - ARCH=$(uname -m) - - case "$OS" in - linux) - PLATFORM="linux" - ;; - darwin) - PLATFORM="macos" - ;; - *) - error "Unsupported operating system: $OS" - ;; - esac - - case "$ARCH" in - x86_64|amd64) - ARCH="x64" - ;; - aarch64|arm64) - ARCH="arm64" - ;; - *) - error "Unsupported architecture: $ARCH" - ;; - esac - - BINARY_NAME="onebox-${PLATFORM}-${ARCH}" -} - -# Get latest version from Gitea API -get_latest_version() { - info "Fetching latest version..." - VERSION=$(curl -s "${REPO_URL}/releases" | grep -o '"tag_name":"v[^"]*' | head -1 | cut -d'"' -f4 | cut -c2-) - - if [ -z "$VERSION" ]; then - warn "Could not fetch latest version, using 'main' branch" - VERSION="main" - else - info "Latest version: v${VERSION}" - fi -} +if [ $SHOW_HELP -eq 1 ]; then + echo "Onebox Installer Script" + echo "Downloads and installs pre-compiled Onebox binary" + echo "" + echo "Usage: $0 [options]" + echo "" + echo "Options:" + echo " -h, --help Show this help message" + echo " --version VERSION Install specific version (e.g., v1.11.0)" + echo " --install-dir DIR Installation directory (default: /opt/onebox)" + echo "" + echo "Examples:" + echo " # Install latest version" + echo " curl -sSL https://code.foss.global/serve.zone/onebox/raw/branch/main/install.sh | sudo bash" + echo "" + echo " # Install specific version" + echo " curl -sSL https://code.foss.global/serve.zone/onebox/raw/branch/main/install.sh | sudo bash -s -- --version v1.11.0" + exit 0 +fi # Check if running as root -check_root() { - if [ "$EUID" -ne 0 ]; then - error "This script must be run as root (use sudo)" - fi +if [ "$EUID" -ne 0 ]; then + echo "Please run as root (sudo bash install.sh or pipe to sudo bash)" + exit 1 +fi + +# Helper function to detect OS and architecture +detect_platform() { + local os=$(uname -s) + local arch=$(uname -m) + + # Map OS + case "$os" in + Linux) + os_name="linux" + ;; + Darwin) + os_name="macos" + ;; + MINGW*|MSYS*|CYGWIN*) + os_name="windows" + ;; + *) + echo "Error: Unsupported operating system: $os" + echo "Supported: Linux, macOS, Windows" + exit 1 + ;; + esac + + # Map architecture + case "$arch" in + x86_64|amd64) + arch_name="x64" + ;; + aarch64|arm64) + arch_name="arm64" + ;; + *) + echo "Error: Unsupported architecture: $arch" + echo "Supported: x86_64/amd64 (x64), aarch64/arm64 (arm64)" + exit 1 + ;; + esac + + # Construct binary name + if [ "$os_name" = "windows" ]; then + echo "onebox-${os_name}-${arch_name}.exe" + else + echo "onebox-${os_name}-${arch_name}" + fi } +# Get latest release version from Gitea API +get_latest_version() { + echo "Fetching latest release version from Gitea..." >&2 + + local api_url="${GITEA_BASE_URL}/api/v1/repos/${GITEA_REPO}/releases/latest" + local response=$(curl -sSL "$api_url" 2>/dev/null) + + if [ $? -ne 0 ] || [ -z "$response" ]; then + echo "Error: Failed to fetch latest release information from Gitea API" >&2 + echo "URL: $api_url" >&2 + exit 1 + fi + + # Extract tag_name from JSON response + local version=$(echo "$response" | grep -o '"tag_name":"[^"]*"' | cut -d'"' -f4) + + if [ -z "$version" ]; then + echo "Error: Could not determine latest version from API response" >&2 + exit 1 + fi + + echo "$version" +} + +# Main installation process +echo "================================================" +echo " Onebox Installation Script" +echo "================================================" +echo "" + +# Detect platform +BINARY_NAME=$(detect_platform) +echo "Detected platform: $BINARY_NAME" +echo "" + +# Determine version to install +if [ -n "$SPECIFIED_VERSION" ]; then + VERSION="$SPECIFIED_VERSION" + echo "Installing specified version: $VERSION" +else + VERSION=$(get_latest_version) + echo "Installing latest version: $VERSION" +fi +echo "" + +# Construct download URL +DOWNLOAD_URL="${GITEA_BASE_URL}/${GITEA_REPO}/releases/download/${VERSION}/${BINARY_NAME}" +echo "Download URL: $DOWNLOAD_URL" +echo "" + +# Check if service is running and stop it +SERVICE_WAS_RUNNING=0 +if systemctl is-enabled --quiet "$SERVICE_NAME" 2>/dev/null || systemctl is-active --quiet "$SERVICE_NAME" 2>/dev/null; then + SERVICE_WAS_RUNNING=1 + if systemctl is-active --quiet "$SERVICE_NAME" 2>/dev/null; then + echo "Stopping Onebox service..." + systemctl stop "$SERVICE_NAME" + fi +fi + +# Clean installation directory - ensure only binary exists +if [ -d "$INSTALL_DIR" ]; then + echo "Cleaning installation directory: $INSTALL_DIR" + rm -rf "$INSTALL_DIR" +fi + +# Create fresh installation directory +echo "Creating installation directory: $INSTALL_DIR" +mkdir -p "$INSTALL_DIR" + # Download binary -download_binary() { - info "Downloading Onebox ${VERSION} for ${PLATFORM}-${ARCH}..." +echo "Downloading Onebox binary..." +TEMP_FILE="$INSTALL_DIR/onebox.download" +curl -sSL "$DOWNLOAD_URL" -o "$TEMP_FILE" - # Create temp directory - TMP_DIR=$(mktemp -d) - TMP_FILE="${TMP_DIR}/${BINARY_NAME}" +if [ $? -ne 0 ]; then + echo "Error: Failed to download binary from $DOWNLOAD_URL" + echo "" + echo "Please check:" + echo " 1. Your internet connection" + echo " 2. The specified version exists: ${GITEA_BASE_URL}/${GITEA_REPO}/releases" + echo " 3. The platform binary is available for this release" + rm -f "$TEMP_FILE" + exit 1 +fi - # Try release download first - if [ "$VERSION" != "main" ]; then - DOWNLOAD_URL="${REPO_URL}/releases/download/v${VERSION}/${BINARY_NAME}" - else - DOWNLOAD_URL="${REPO_URL}/raw/branch/main/dist/binaries/${BINARY_NAME}" - fi +# Check if download was successful (file exists and not empty) +if [ ! -s "$TEMP_FILE" ]; then + echo "Error: Downloaded file is empty or does not exist" + rm -f "$TEMP_FILE" + exit 1 +fi - if ! curl -L -f -o "$TMP_FILE" "$DOWNLOAD_URL"; then - error "Failed to download binary from $DOWNLOAD_URL" - fi +# Move to final location +BINARY_PATH="$INSTALL_DIR/onebox" +mv "$TEMP_FILE" "$BINARY_PATH" - # Verify download - if [ ! -f "$TMP_FILE" ] || [ ! -s "$TMP_FILE" ]; then - error "Downloaded file is empty or missing" - fi +if [ $? -ne 0 ] || [ ! -f "$BINARY_PATH" ]; then + echo "Error: Failed to move binary to $BINARY_PATH" + rm -f "$TEMP_FILE" 2>/dev/null + exit 1 +fi - info "✓ Download complete" -} +# Make executable +chmod +x "$BINARY_PATH" -# Install binary -install_binary() { - info "Installing Onebox to ${INSTALL_DIR}..." +if [ $? -ne 0 ]; then + echo "Error: Failed to make binary executable" + exit 1 +fi - # Create install directory - mkdir -p "$INSTALL_DIR" +echo "Binary installed successfully to: $BINARY_PATH" +echo "" - # Copy binary - cp "$TMP_FILE" "${INSTALL_DIR}/onebox" - chmod +x "${INSTALL_DIR}/onebox" +# Check if /usr/local/bin is in PATH +if [[ ":$PATH:" == *":/usr/local/bin:"* ]]; then + BIN_DIR="/usr/local/bin" +else + BIN_DIR="/usr/bin" +fi - # Create symlink - ln -sf "${INSTALL_DIR}/onebox" "$BIN_LINK" +# Create symlink for global access +ln -sf "$BINARY_PATH" "$BIN_DIR/onebox" +echo "Symlink created: $BIN_DIR/onebox -> $BINARY_PATH" +echo "" - # Cleanup temp files - rm -rf "$TMP_DIR" +# Create data directories +mkdir -p /var/lib/onebox +mkdir -p /var/www/certbot - info "✓ Installation complete" -} +# Restart service if it was running before update +if [ $SERVICE_WAS_RUNNING -eq 1 ]; then + echo "Restarting Onebox service..." + systemctl restart "$SERVICE_NAME" + echo "Service restarted successfully." + echo "" +fi -# Initialize database and config -initialize() { - info "Initializing Onebox..." +echo "================================================" +echo " Onebox Installation Complete!" +echo "================================================" +echo "" +echo "Installation details:" +echo " Binary location: $BINARY_PATH" +echo " Symlink location: $BIN_DIR/onebox" +echo " Version: $VERSION" +echo "" - # Create data directory - mkdir -p /var/lib/onebox - - # Create certbot directory for ACME challenges - mkdir -p /var/www/certbot - - info "✓ Initialization complete" -} - -# Print success message -print_success() { - echo "" - info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - info " Onebox installed successfully!" - info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo "" - echo "Next steps:" - echo "" - echo "1. Configure Cloudflare (optional):" - echo " onebox config set cloudflareAPIKey " - echo " onebox config set cloudflareEmail " - echo " onebox config set cloudflareZoneID " - echo " onebox config set serverIP " - echo "" - echo "2. Configure ACME email:" - echo " onebox config set acmeEmail " - echo "" - echo "3. Install daemon:" - echo " onebox daemon install" - echo "" - echo "4. Start daemon:" - echo " onebox daemon start" - echo "" - echo "5. Deploy your first service:" - echo " onebox service add myapp --image nginx:latest --domain app.example.com" - echo "" - echo "Web UI: http://localhost:3000" - echo "Default credentials: admin / admin" - echo "" -} - -# Main installation flow -main() { - info "Onebox Installer" - echo "" - - check_root - detect_platform - get_latest_version - download_binary - install_binary - initialize - print_success -} - -# Run main function -main +# Check if database exists (indicates existing installation) +if [ -f "/var/lib/onebox/onebox.db" ]; then + echo "Data directory: /var/lib/onebox (preserved)" + echo "" + echo "Your existing data has been preserved." + if [ $SERVICE_WAS_RUNNING -eq 1 ]; then + echo "The service has been restarted with your current settings." + else + echo "Start the service with: onebox daemon start" + fi +else + echo "Get started:" + echo "" + echo " onebox --version" + echo " onebox --help" + echo "" + echo " 1. Configure Cloudflare (optional):" + echo " onebox config set cloudflareAPIKey " + echo " onebox config set cloudflareEmail " + echo " onebox config set cloudflareZoneID " + echo " onebox config set serverIP " + echo "" + echo " 2. Configure ACME email:" + echo " onebox config set acmeEmail " + echo "" + echo " 3. Install daemon:" + echo " onebox daemon install" + echo "" + echo " 4. Start daemon:" + echo " onebox daemon start" + echo "" + echo " 5. Deploy your first service:" + echo " onebox service add myapp --image nginx:latest --domain app.example.com" + echo "" + echo " Web UI: http://localhost:3000" + echo " Default credentials: admin / admin" +fi +echo "" diff --git a/readme.md b/readme.md index 535dd84..b17aad0 100644 --- a/readme.md +++ b/readme.md @@ -47,10 +47,11 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community ### Installation ```bash -# Download the latest release for your platform -curl -sSL https://code.foss.global/serve.zone/onebox/releases/latest/download/onebox-linux-x64 -o onebox -chmod +x onebox -sudo mv onebox /usr/local/bin/ +# One-line install (recommended) +curl -sSL https://code.foss.global/serve.zone/onebox/raw/branch/main/install.sh | sudo bash + +# Install a specific version +curl -sSL https://code.foss.global/serve.zone/onebox/raw/branch/main/install.sh | sudo bash -s -- --version v1.11.0 # Or install from npm pnpm install -g @serve.zone/onebox @@ -242,6 +243,13 @@ onebox config set cloudflareZoneID your-zone-id onebox status ``` +### Upgrade + +```bash +# Upgrade to the latest version (requires root) +sudo onebox upgrade +``` + ## Configuration 🔧 ### System Requirements diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index a3ec639..0d8bb2c 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/onebox', - version: '1.12.1', + version: '1.13.0', description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers' } diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index a3ec639..0d8bb2c 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/onebox', - version: '1.12.1', + version: '1.13.0', description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers' }