#!/bin/bash # Fix script for Raspberry Pi installation issues # Specifically handles the "No space left on device" error during pip install 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 print_header() { echo echo -e "${BLUE}════════════════════════════════════════════════${NC}" echo -e "${BLUE} Turmli Calendar - Installation Fix for RPi${NC}" echo -e "${BLUE}════════════════════════════════════════════════${NC}" echo } print_success() { echo -e "${GREEN}✓${NC} $1" } print_error() { echo -e "${RED}✗${NC} $1" } print_warning() { echo -e "${YELLOW}⚠${NC} $1" } print_info() { echo -e "${BLUE}ℹ${NC} $1" } # Configuration APP_DIR="/opt/turmli-calendar" APP_USER="pi" print_header # Check if running as root if [[ $EUID -ne 0 ]]; then print_error "This script must be run as root (use sudo)" exit 1 fi # Step 1: Clean up temporary files print_info "Cleaning up temporary files..." rm -rf /tmp/pip-* rm -rf /tmp/tmp* apt-get clean apt-get autoremove -y print_success "Temporary files cleaned" # Step 2: Check available space print_info "Checking available space..." echo "Disk usage:" df -h / /tmp /opt echo # Step 3: Create alternative temp directory print_info "Creating alternative temp directory..." CUSTOM_TEMP="$APP_DIR/tmp" mkdir -p "$CUSTOM_TEMP" chown ${APP_USER}:${APP_USER} "$CUSTOM_TEMP" print_success "Temp directory created at $CUSTOM_TEMP" # Step 4: Create optimized requirements file print_info "Creating optimized requirements file..." cat > "$APP_DIR/requirements-rpi.txt" << 'EOF' # Optimized requirements for Raspberry Pi # Avoids packages that require compilation fastapi>=0.104.0 # Use uvicorn without extras to avoid watchfiles compilation uvicorn>=0.24.0 httpx>=0.25.0 icalendar>=5.0.0 jinja2>=3.1.0 python-multipart>=0.0.6 apscheduler>=3.10.0 pytz>=2023.3 # These are the problematic packages we're excluding: # - watchfiles (requires Rust compilation) # - websockets with speedups # - httptools (requires C compilation) # - python-dotenv (not needed for production) # - uvloop (requires C compilation) EOF print_success "Optimized requirements file created" # Step 5: Install Python packages with custom temp directory print_info "Installing Python dependencies..." print_warning "This may take 10-20 minutes on Raspberry Pi Zero" # First, upgrade pip and basic tools sudo -u ${APP_USER} TMPDIR="$CUSTOM_TEMP" "$APP_DIR/venv/bin/pip" install \ --no-cache-dir \ --upgrade pip wheel setuptools # Install packages one by one to handle failures better PACKAGES=( "fastapi>=0.104.0" "uvicorn>=0.24.0" "httpx>=0.25.0" "icalendar>=5.0.0" "jinja2>=3.1.0" "python-multipart>=0.0.6" "apscheduler>=3.10.0" "pytz>=2023.3" ) for package in "${PACKAGES[@]}"; do print_info "Installing $package..." sudo -u ${APP_USER} TMPDIR="$CUSTOM_TEMP" "$APP_DIR/venv/bin/pip" install \ --no-cache-dir \ --prefer-binary \ --no-build-isolation \ "$package" || { print_warning "Failed to install $package, trying without isolation..." sudo -u ${APP_USER} TMPDIR="$CUSTOM_TEMP" "$APP_DIR/venv/bin/pip" install \ --no-cache-dir \ --no-deps \ "$package" || print_error "Failed to install $package" } done print_success "Dependencies installed" # Step 6: Clean up print_info "Cleaning up..." rm -rf "$CUSTOM_TEMP" print_success "Cleanup complete" # Step 7: Test the installation print_info "Testing Python installation..." if sudo -u ${APP_USER} "$APP_DIR/venv/bin/python" -c "import fastapi, uvicorn, httpx, icalendar, jinja2, apscheduler, pytz; print('All modules imported successfully')"; then print_success "All required Python modules are installed" else print_error "Some modules failed to import" exit 1 fi # Step 8: Create a test script print_info "Creating test script..." cat > "$APP_DIR/test_import.py" << 'EOF' #!/usr/bin/env python3 import sys print("Python version:", sys.version) print("\nTrying to import modules...") try: import fastapi print("✓ fastapi:", fastapi.__version__) except ImportError as e: print("✗ fastapi:", e) try: import uvicorn print("✓ uvicorn:", uvicorn.__version__) except ImportError as e: print("✗ uvicorn:", e) try: import httpx print("✓ httpx:", httpx.__version__) except ImportError as e: print("✗ httpx:", e) try: import icalendar print("✓ icalendar:", icalendar.__version__) except ImportError as e: print("✗ icalendar:", e) try: import jinja2 print("✓ jinja2:", jinja2.__version__) except ImportError as e: print("✗ jinja2:", e) try: import apscheduler print("✓ apscheduler:", apscheduler.__version__) except ImportError as e: print("✗ apscheduler:", e) try: import pytz print("✓ pytz:", pytz.__version__) except ImportError as e: print("✗ pytz:", e) print("\nAll critical modules checked!") EOF chmod +x "$APP_DIR/test_import.py" print_success "Test script created" # Step 9: Run the test print_info "Running import test..." sudo -u ${APP_USER} "$APP_DIR/venv/bin/python" "$APP_DIR/test_import.py" # Step 10: Try to start the application print_info "Attempting to start the application..." cd "$APP_DIR" # Test if the application can start timeout 10 sudo -u ${APP_USER} "$APP_DIR/venv/bin/python" -m uvicorn main:app --host 0.0.0.0 --port 8000 & PID=$! sleep 5 if kill -0 $PID 2>/dev/null; then print_success "Application started successfully!" kill $PID else print_warning "Application may have issues starting" fi # Final summary echo echo -e "${GREEN}════════════════════════════════════════════════${NC}" echo -e "${GREEN} Installation Fix Complete!${NC}" echo -e "${GREEN}════════════════════════════════════════════════${NC}" echo print_info "Next steps:" print_info "1. Start the service: sudo systemctl start turmli-calendar" print_info "2. Check status: sudo systemctl status turmli-calendar" print_info "3. View logs: sudo journalctl -u turmli-calendar -f" echo print_info "If you still have issues, try:" print_info "1. Increase swap: sudo nano /etc/dphys-swapfile (set CONF_SWAPSIZE=512)" print_info "2. Reboot: sudo reboot" print_info "3. Manual test: cd $APP_DIR && sudo -u pi ./venv/bin/python main.py" echo