#!/bin/bash # Rust and SAL Installation Script # Defensively installs Rust and clones/updates SAL repository # Compatible with Ubuntu/Debian systems set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color log() { echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}" } warn() { echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}" } error() { echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}" exit 1 } info() { echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')] INFO: $1${NC}" } # Get the directory where this script is located SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" log "Script directory: $SCRIPT_DIR" # Define target directory for SAL repository SAL_TARGET_DIR="/root/code/git.threefold.info/herocode/sal" SAL_REPO_URL="git@git.threefold.info:herocode/sal.git" # Function to check if ssh-agent is loaded and has keys check_ssh_agent() { log "Checking SSH agent status..." if [ -z "$SSH_AUTH_SOCK" ]; then warn "SSH_AUTH_SOCK is not set. SSH agent may not be running." return 1 fi if ! ssh-add -l &>/dev/null; then warn "SSH agent is running but no keys are loaded or agent is not accessible." info "You may need to run: ssh-add ~/.ssh/id_rsa (or your key file)" return 1 fi log "✅ SSH agent is loaded and has keys available" return 0 } # Function to test SSH connection to git server test_ssh_connection() { log "Testing SSH connection to git.threefold.info..." if ssh -T -o ConnectTimeout=10 -o StrictHostKeyChecking=no git@git.threefold.info 2>&1 | grep -q "successfully authenticated"; then log "✅ SSH connection to git.threefold.info successful" return 0 else warn "SSH connection test failed. Continuing anyway..." return 1 fi } # Function to defensively install Rust install_rust_defensively() { log "Starting defensive Rust installation..." # Check if install_rust.sh exists in the same directory RUST_INSTALLER="$SCRIPT_DIR/install_rust.sh" if [ ! -f "$RUST_INSTALLER" ]; then error "install_rust.sh not found at: $RUST_INSTALLER" fi if [ ! -x "$RUST_INSTALLER" ]; then log "Making install_rust.sh executable..." chmod +x "$RUST_INSTALLER" fi log "Calling install_rust.sh from: $RUST_INSTALLER" # Run the Rust installer defensively if ! "$RUST_INSTALLER"; then error "Rust installation failed" fi log "✅ Rust installation completed successfully" } # Function to clone or update SAL repository handle_sal_repository() { log "Handling SAL repository at: $SAL_TARGET_DIR" # Create parent directories if they don't exist SAL_PARENT_DIR="$(dirname "$SAL_TARGET_DIR")" if [ ! -d "$SAL_PARENT_DIR" ]; then log "Creating parent directory: $SAL_PARENT_DIR" mkdir -p "$SAL_PARENT_DIR" fi if [ -d "$SAL_TARGET_DIR" ]; then log "SAL directory exists. Checking if it's a git repository..." if [ -d "$SAL_TARGET_DIR/.git" ]; then log "Found existing git repository. Pulling latest changes..." cd "$SAL_TARGET_DIR" # Check if we're in a clean state if ! git status --porcelain | grep -q .; then log "Repository is clean. Pulling changes..." if git pull origin main 2>/dev/null || git pull origin master 2>/dev/null; then log "✅ Successfully pulled latest changes" else warn "Pull failed. Repository may be up to date or have conflicts." fi else warn "Repository has uncommitted changes. Skipping pull." git status --short fi else warn "Directory exists but is not a git repository. Removing and cloning fresh..." rm -rf "$SAL_TARGET_DIR" clone_sal_repository fi else log "SAL directory does not exist. Cloning repository..." clone_sal_repository fi } # Function to clone SAL repository clone_sal_repository() { log "Cloning SAL repository from: $SAL_REPO_URL" log "Target directory: $SAL_TARGET_DIR" # Ensure parent directory exists mkdir -p "$(dirname "$SAL_TARGET_DIR")" if git clone "$SAL_REPO_URL" "$SAL_TARGET_DIR"; then log "✅ Successfully cloned SAL repository" cd "$SAL_TARGET_DIR" log "Repository cloned to: $(pwd)" log "Current branch: $(git branch --show-current 2>/dev/null || echo 'unknown')" else error "Failed to clone SAL repository. Check SSH keys and network connectivity." fi } # Function to verify SAL repository verify_sal_repository() { log "Verifying SAL repository..." if [ ! -d "$SAL_TARGET_DIR" ]; then error "SAL directory does not exist: $SAL_TARGET_DIR" fi if [ ! -d "$SAL_TARGET_DIR/.git" ]; then error "SAL directory is not a git repository: $SAL_TARGET_DIR" fi cd "$SAL_TARGET_DIR" # Get repository information REPO_URL=$(git remote get-url origin 2>/dev/null || echo "unknown") CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") LAST_COMMIT=$(git log -1 --format="%h - %s (%cr)" 2>/dev/null || echo "unknown") log "✅ SAL repository verification successful" log "Repository URL: $REPO_URL" log "Current branch: $CURRENT_BRANCH" log "Last commit: $LAST_COMMIT" } # Main execution main() { log "Starting Rust and SAL installation process..." log "==========================================" # Step 1: Install Rust defensively install_rust_defensively # Step 2: Check SSH agent if ! check_ssh_agent; then warn "SSH agent issues detected. Continuing anyway..." warn "You may need to set up SSH keys and agent before git operations." fi # Step 3: Test SSH connection (optional, continues on failure) test_ssh_connection # Step 4: Handle SAL repository (clone or pull) handle_sal_repository # Step 5: Verify SAL repository verify_sal_repository log "==========================================" log "✅ Installation process completed successfully!" log "" log "Summary:" log "- Rust: Installed and verified" log "- SAL repository: Available at $SAL_TARGET_DIR" log "" log "Next steps:" log "- Source Rust environment: source ~/.cargo/env (if not root)" log "- Navigate to SAL: cd $SAL_TARGET_DIR" log "- Build SAL project: cargo build" } # Trap to handle script interruption trap 'error "Script interrupted"' INT TERM # Run main function main "$@"