#!/bin/bash set -euo pipefail # InternalAI Platform Setup Script # This script handles authentication and clones the private internalai monorepo # ============================================================================ # Configuration # ============================================================================ PLATFORM_NAME="InternalAI Platform" DEFAULT_INSTALL_DIR="$HOME/internalai" REPO_URL="https://gitea.app.monadical.io/monadical/internalai.git" REPO_SSH="git@gitea.app.monadical.io:monadical/internalai.git" CLI_INSTALL_DIR="/usr/local/bin" CLI_NAME="internalai" VERSION="1.0.0" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' BOLD='\033[1m' NC='\033[0m' # ============================================================================ # Logging Functions # ============================================================================ log_info() { echo -e "${BLUE}ℹ${NC} $1" } log_success() { echo -e "${GREEN}✓${NC} $1" } log_warning() { echo -e "${YELLOW}⚠${NC} $1" } log_error() { echo -e "${RED}✗${NC} $1" } log_header() { echo "" echo -e "${CYAN}═══════════════════════════════════════════════════════════${NC}" echo -e "${CYAN} $1${NC}" echo -e "${CYAN}═══════════════════════════════════════════════════════════${NC}" echo "" } print_banner() { clear echo -e "${BOLD}${CYAN}" cat << 'EOF' ╔═════════════════════════════════════════════════════════════════════════════════════════╗ ║ ║ ║ ██╗███╗ ██╗████████╗███████╗██████╗ ███╗ ██╗ █████╗ ██╗ █████╗ ██╗ ║ ║ ██║████╗ ██║╚══██╔══╝██╔════╝██╔══██╗████╗ ██║██╔══██╗██║ ██╔══██╗██║ ║ ║ ██║██╔██╗ ██║ ██║ █████╗ ██████╔╝██╔██╗ ██║███████║██║ ███████║██║ ║ ║ ██║██║╚██╗██║ ██║ ██╔══╝ ██╔══██╗██║╚██╗██║██╔══██║██║ ██╔══██║██║ ║ ║ ██║██║ ╚████║ ██║ ███████╗██║ ██║██║ ╚████║██║ ██║███████╗ ██║ ██║██║ ║ ║ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝╚═╝ ║ ║ ║ ║ Platform Setup v${VERSION} ║ ╚═════════════════════════════════════════════════════════════════════════════════════════╝ EOF echo -e "${NC}" } # ============================================================================ # Utility Functions # ============================================================================ prompt() { local varname=$1 local prompt_text=$2 local default_value=$3 local is_secret=${4:-false} if [ -n "$default_value" ]; then prompt_text="$prompt_text [${default_value}]" fi if [ "$is_secret" = true ]; then echo -ne "${YELLOW}${prompt_text}: ${NC}" value="" while IFS= read -r -s -n1 char; do if [[ $char == $'\0' ]]; then break fi if [[ $char == $'\177' ]] || [[ $char == $'\b' ]]; then if [ ${#value} -gt 0 ]; then value="${value%?}" echo -ne "\b \b" fi else value+="$char" echo -n "*" fi done echo "" else read -p "$(echo -e ${YELLOW}${prompt_text}: ${NC})" value fi if [ -z "$value" ] && [ -n "$default_value" ]; then value="$default_value" fi eval "$varname='$value'" } # ============================================================================ # Dependency Checking # ============================================================================ check_dependencies() { log_header "Checking Dependencies" local deps_ok=true # Check Git if command -v git &> /dev/null; then log_success "git installed ($(git --version | head -n1))" else log_error "git is not installed" deps_ok=false fi # Check Docker if command -v docker &> /dev/null; then log_success "docker installed ($(docker --version | head -n1))" else log_error "docker is not installed" deps_ok=false fi # Check Docker Compose if docker compose version &> /dev/null 2>&1; then log_success "docker compose installed ($(docker compose version | head -n1))" elif command -v docker-compose &> /dev/null; then log_success "docker-compose installed ($(docker-compose --version | head -n1))" else log_error "docker compose is not installed" deps_ok=false fi # Check Just if command -v just &> /dev/null; then log_success "just installed ($(just --version | head -n1))" else log_warning "just is not installed (will attempt to install)" install_just fi if [ "$deps_ok" = false ]; then log_error "Please install missing dependencies and try again" echo "" log_info "Installation guides:" log_info " • Git: https://git-scm.com/downloads" log_info " • Docker: https://docs.docker.com/get-docker/" log_info " • Just: https://github.com/casey/just#installation" exit 1 fi } install_just() { if [[ "$OSTYPE" == "darwin"* ]]; then if command -v brew &> /dev/null; then log_info "Installing just via Homebrew..." brew install just log_success "just installed" else log_error "Homebrew not found. Please install just manually: https://github.com/casey/just#installation" exit 1 fi elif [[ "$OSTYPE" == "linux-gnu"* ]]; then if command -v cargo &> /dev/null; then log_info "Installing just via cargo..." cargo install just log_success "just installed" else log_error "Cargo not found. Please install Rust or just manually: https://github.com/casey/just#installation" exit 1 fi else log_error "Unsupported OS. Please install just manually: https://github.com/casey/just#installation" exit 1 fi } # ============================================================================ # Gitea Authentication # ============================================================================ AUTH_TYPE="" GITEA_TOKEN="" setup_gitea_auth() { log_header "Gitea Authentication" log_info "The InternalAI platform repository is private and requires authentication." echo "" log_info "Choose authentication method:" echo " 1) Personal Access Token (recommended)" echo " 2) SSH Key (if already configured)" echo "" prompt AUTH_CHOICE "Select authentication method" "1" case "$AUTH_CHOICE" in 1) AUTH_TYPE="token" echo "" log_info "To create a personal access token:" log_info " 1. Go to: https://gitea.app.monadical.io/user/settings/applications" log_info " 2. Click 'Generate New Token'" log_info " 3. Give it a name (e.g., 'InternalAI Setup')" log_info " 4. Give it Read repository scope" log_info " 5. Click 'Generate Token' and copy it" echo "" prompt GITEA_TOKEN "Enter your Gitea Personal Access Token" "" true if [ -z "$GITEA_TOKEN" ]; then log_error "Token is required" exit 1 fi ;; 2) AUTH_TYPE="ssh" log_info "Using SSH authentication" log_info "Ensure your SSH key is added to Gitea:" log_info " https://gitea.app.monadical.io/user/settings/keys" # Test SSH connection echo "" log_info "Testing SSH connection..." if ssh -T git@gitea.app.monadical.io 2>&1 | grep -q "Hi there"; then log_success "SSH connection successful" else log_warning "Could not verify SSH connection, but will try to continue..." fi ;; *) log_error "Invalid choice" exit 1 ;; esac } prepare_git_url() { if [ "$AUTH_TYPE" = "token" ] && [ -n "$GITEA_TOKEN" ]; then echo "$REPO_URL" | sed "s|https://gitea.app.monadical.io/|https://${GITEA_TOKEN}@gitea.app.monadical.io/|" elif [ "$AUTH_TYPE" = "ssh" ]; then echo "$REPO_SSH" else echo "$REPO_URL" fi } # ============================================================================ # Git Credential Caching # ============================================================================ configure_git_credentials() { log_header "Configuring Git Credentials" if [ "$AUTH_TYPE" = "ssh" ]; then log_info "Using SSH - no credential caching needed" return fi # Detect OS and configure appropriate credential helper if [[ "$OSTYPE" == "darwin"* ]]; then # macOS - use keychain log_info "Configuring git to use macOS Keychain..." git config --global credential.helper osxkeychain log_success "Git credentials will be stored in macOS Keychain" elif [[ "$OSTYPE" == "linux-gnu"* ]]; then # Linux - try to use libsecret, fall back to cache if command -v git-credential-libsecret &> /dev/null; then log_info "Configuring git to use libsecret..." git config --global credential.helper libsecret log_success "Git credentials will be stored in system keyring" else log_info "Configuring git credential cache (1 hour)..." git config --global credential.helper 'cache --timeout=3600' log_success "Git credentials will be cached in memory for 1 hour" log_info "For persistent storage, install: libsecret" fi else # Unknown OS - use cache log_info "Configuring git credential cache (1 hour)..." git config --global credential.helper 'cache --timeout=3600' log_success "Git credentials will be cached in memory for 1 hour" fi # Store credentials by triggering a git operation if [ "$AUTH_TYPE" = "token" ] && [ -n "$INSTALL_DIR" ] && [ -d "$INSTALL_DIR/.git" ]; then log_info "Caching credentials..." cd "$INSTALL_DIR" # Trigger credential storage by doing a fetch (which uses credentials) git fetch --dry-run 2>&1 | grep -v "password\|token" > /dev/null || true log_success "Credentials cached successfully" fi } # ============================================================================ # Repository Cloning # ============================================================================ clone_repository() { log_header "Cloning Repository" prompt INSTALL_DIR "Installation directory" "$DEFAULT_INSTALL_DIR" if [ -d "$INSTALL_DIR" ]; then if [ -d "$INSTALL_DIR/.git" ]; then log_warning "Directory already exists and appears to be a git repository" prompt UPDATE_CHOICE "Update existing repository? (y/n)" "y" if [[ "$UPDATE_CHOICE" =~ ^[Yy] ]]; then log_info "Pulling latest changes..." cd "$INSTALL_DIR" git pull log_success "Repository updated" return else log_info "Using existing repository" return fi else log_error "Directory exists but is not a git repository" log_info "Please remove or rename: $INSTALL_DIR" exit 1 fi fi local git_url=$(prepare_git_url) log_info "Cloning repository to: $INSTALL_DIR" log_info "This may take a few minutes..." if git clone "$git_url" "$INSTALL_DIR" 2>&1 | grep -v "password\|token"; then log_success "Repository cloned successfully" else log_error "Failed to clone repository" log_info "Please check your credentials and try again" exit 1 fi } # ============================================================================ # CLI Installation # ============================================================================ install_cli() { log_header "Installing CLI Tool" local cli_script="$INSTALL_DIR/scripts/$CLI_NAME" if [ ! -f "$cli_script" ]; then log_error "CLI script not found at: $cli_script" exit 1 fi log_info "Installing $CLI_NAME to $CLI_INSTALL_DIR..." if [ -w "$CLI_INSTALL_DIR" ]; then cp "$cli_script" "$CLI_INSTALL_DIR/$CLI_NAME" chmod +x "$CLI_INSTALL_DIR/$CLI_NAME" else log_warning "Need sudo permissions to write to $CLI_INSTALL_DIR" sudo cp "$cli_script" "$CLI_INSTALL_DIR/$CLI_NAME" sudo chmod +x "$CLI_INSTALL_DIR/$CLI_NAME" fi if command -v "$CLI_NAME" &> /dev/null; then log_success "$CLI_NAME installed successfully!" else log_warning "$CLI_NAME installed but not found in PATH" log_info "You may need to restart your terminal or run:" log_info " export PATH=\"$CLI_INSTALL_DIR:\$PATH\"" fi } # ============================================================================ # Post-Installation # ============================================================================ show_next_steps() { log_header "Installation Complete!" echo -e "${GREEN}${BOLD}The InternalAI platform has been set up successfully!${NC}" echo "" echo -e "${BOLD}Platform Location:${NC} ${CYAN}$INSTALL_DIR${NC}" echo "" echo -e "${BOLD}Next Steps:${NC}" echo "" echo " 1. Configure and start the platform:" echo -e " ${GREEN}$CLI_NAME install${NC}" echo "" echo " 2. View available commands:" echo -e " ${GREEN}$CLI_NAME help${NC}" echo "" echo " 3. Check platform status:" echo -e " ${GREEN}$CLI_NAME status${NC}" echo "" echo -e "${BOLD}Documentation:${NC}" echo " • Platform docs: $INSTALL_DIR/docs/" echo " • README: $INSTALL_DIR/README.md" echo "" } # ============================================================================ # Main Installation Flow # ============================================================================ main() { print_banner log_info "Starting InternalAI Platform setup..." echo "" check_dependencies setup_gitea_auth clone_repository configure_git_credentials install_cli show_next_steps echo -e "${GREEN}${BOLD}Setup completed successfully!${NC}" echo "" } main "$@"