Files
turmlibar-calendar/fix-python-compatibility.sh
2025-11-28 19:43:04 +01:00

243 lines
8.4 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Fix script for Python/Pydantic compatibility issues on Raspberry Pi
# This script helps resolve the Python 3.13 / Pydantic v1 incompatibility
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 functions
print_error() {
echo -e "${RED}$1${NC}"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_info() {
echo -e "${BLUE} $1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
# Detect container runtime
detect_runtime() {
if command -v podman &> /dev/null; then
RUNTIME="podman"
print_info "Using Podman"
elif command -v docker &> /dev/null; then
RUNTIME="docker"
print_info "Using Docker"
else
print_error "No container runtime found! Please install Podman or Docker."
exit 1
fi
}
# Main fix process
main() {
print_info "Python/Pydantic Compatibility Fix Script"
print_info "========================================="
# Detect runtime
detect_runtime
# Check current situation
print_info "Checking current container status..."
if ${RUNTIME} ps -a --format '{{.Names}}' | grep -q "^turmli-calendar$"; then
print_warning "Found existing turmli-calendar container"
# Show current Python version if container is running
if ${RUNTIME} ps --format '{{.Names}}' | grep -q "^turmli-calendar$"; then
print_info "Checking Python version in running container..."
PYTHON_VERSION=$(${RUNTIME} exec turmli-calendar python --version 2>&1 || echo "Unable to determine")
print_info "Current Python version: ${PYTHON_VERSION}"
fi
fi
print_info ""
print_info "This script will fix the Python compatibility issue by:"
print_info "1. Stopping and removing the existing container"
print_info "2. Removing the old container image"
print_info "3. Building a new image with Python 3.11 and compatible packages"
print_info ""
read -p "Do you want to proceed? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_info "Operation cancelled"
exit 0
fi
# Step 1: Stop and remove existing container
print_info "Step 1: Cleaning up existing container..."
if ${RUNTIME} ps -a --format '{{.Names}}' | grep -q "^turmli-calendar$"; then
${RUNTIME} stop turmli-calendar 2>/dev/null || true
${RUNTIME} rm turmli-calendar 2>/dev/null || true
print_success "Container removed"
else
print_info "No existing container found"
fi
# Step 2: Remove old image
print_info "Step 2: Removing old container image..."
if ${RUNTIME} images --format '{{.Repository}}' | grep -q "^turmli-calendar$"; then
${RUNTIME} rmi turmli-calendar 2>/dev/null || true
print_success "Old image removed"
else
print_info "No existing image found"
fi
# Step 3: Detect architecture and select appropriate Dockerfile
ARCH=$(uname -m)
print_info "Step 3: Selecting appropriate Dockerfile for architecture: ${ARCH}"
if [[ "$ARCH" == "armv6l" ]]; then
# Raspberry Pi Zero
if [ -f "Dockerfile.pizero" ]; then
DOCKERFILE="Dockerfile.pizero"
print_info "Using Dockerfile.pizero (Python 3.11 with Pydantic v1)"
else
print_error "Dockerfile.pizero not found!"
exit 1
fi
elif [[ "$ARCH" == "armv7l" ]] || [[ "$ARCH" == "aarch64" ]]; then
# Newer Raspberry Pi models
if [ -f "Dockerfile.pizero-py312" ]; then
DOCKERFILE="Dockerfile.pizero-py312"
print_info "Using Dockerfile.pizero-py312 (Python 3.12 with Pydantic v2)"
elif [ -f "Dockerfile.pizero" ]; then
DOCKERFILE="Dockerfile.pizero"
print_info "Using Dockerfile.pizero (Python 3.11 with Pydantic v1)"
else
print_error "No suitable Dockerfile found!"
exit 1
fi
else
# Other architectures
if [ -f "Dockerfile.minimal" ]; then
DOCKERFILE="Dockerfile.minimal"
print_info "Using Dockerfile.minimal"
elif [ -f "Dockerfile" ]; then
DOCKERFILE="Dockerfile"
print_info "Using standard Dockerfile"
else
print_error "No Dockerfile found!"
exit 1
fi
fi
# Step 4: Build new image
print_info "Step 4: Building new container image..."
print_info "This may take a few minutes, especially on Pi Zero..."
# Check available memory
TOTAL_MEM_KB=$(grep MemTotal /proc/meminfo | awk '{print $2}')
TOTAL_MEM_MB=$((TOTAL_MEM_KB / 1024))
if [ $TOTAL_MEM_MB -lt 512 ]; then
print_warning "Low memory detected: ${TOTAL_MEM_MB}MB"
print_info "Build may be slow. Consider adding swap if it fails."
fi
# Build with no cache to ensure fresh build
if ${RUNTIME} build --no-cache --file "${DOCKERFILE}" --tag turmli-calendar . ; then
print_success "Image built successfully!"
else
print_error "Build failed!"
print_info ""
print_info "Troubleshooting tips:"
print_info "1. If you're on a Pi Zero with low memory, try adding swap:"
print_info " sudo dd if=/dev/zero of=/swapfile bs=1M count=1024"
print_info " sudo chmod 600 /swapfile"
print_info " sudo mkswap /swapfile"
print_info " sudo swapon /swapfile"
print_info ""
print_info "2. Try building with the minimal Dockerfile:"
print_info " ${RUNTIME} build --no-cache --file Dockerfile.minimal --tag turmli-calendar ."
print_info ""
print_info "3. Use a pre-built image (if available):"
print_info " ${RUNTIME} pull ghcr.io/yourusername/turmli-calendar:armv6"
exit 1
fi
# Step 5: Create cache file if needed
if [ ! -f "calendar_cache.json" ]; then
echo "{}" > calendar_cache.json
print_info "Created cache file"
fi
# Step 6: Run the new container
print_info "Step 5: Starting new container..."
# Try to run with SELinux labels first (Fedora/RHEL)
if ${RUNTIME} run -d \
--name turmli-calendar \
-p 8000:8000 \
-v $(pwd)/calendar_cache.json:/app/calendar_cache.json:Z \
-e TZ=Europe/Berlin \
--restart unless-stopped \
turmli-calendar 2>/dev/null; then
print_success "Container started with SELinux labels!"
else
# Retry without SELinux labels (Debian/Ubuntu/Raspbian)
if ${RUNTIME} run -d \
--name turmli-calendar \
-p 8000:8000 \
-v $(pwd)/calendar_cache.json:/app/calendar_cache.json \
-e TZ=Europe/Berlin \
--restart unless-stopped \
turmli-calendar; then
print_success "Container started!"
else
print_error "Failed to start container!"
print_info "Check logs with: ${RUNTIME} logs turmli-calendar"
exit 1
fi
fi
# Step 7: Verify the fix
print_info "Step 6: Verifying the fix..."
sleep 3
# Check if container is running
if ${RUNTIME} ps --format '{{.Names}}' | grep -q "^turmli-calendar$"; then
print_success "Container is running!"
# Check Python version
PYTHON_VERSION=$(${RUNTIME} exec turmli-calendar python --version 2>&1)
print_info "Python version in container: ${PYTHON_VERSION}"
# Check if app is responding
if curl -s -f http://localhost:8000/api/events > /dev/null 2>&1; then
print_success "Application is responding!"
print_info ""
print_success "✨ Fix completed successfully! ✨"
print_info "Access your calendar at:"
print_info " http://$(hostname -I | awk '{print $1}'):8000"
print_info " http://localhost:8000"
else
print_warning "Application not responding yet, checking logs..."
${RUNTIME} logs --tail 10 turmli-calendar
print_info ""
print_info "The application may still be starting up."
print_info "Check full logs with: ${RUNTIME} logs -f turmli-calendar"
fi
else
print_error "Container failed to start!"
print_info "Checking logs..."
${RUNTIME} logs turmli-calendar
exit 1
fi
}
# Run main function
main