Files
turmlibar-calendar/build-pi.sh
2025-10-30 16:16:33 +01:00

245 lines
7.1 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
# Build script for Raspberry Pi Zero/ARM devices
# Optimized for low memory and no compilation
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
# Configuration
IMAGE_NAME="turmli-calendar"
CONTAINER_NAME="turmli-calendar"
# 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 system
detect_system() {
ARCH=$(uname -m)
OS=$(cat /etc/os-release | grep "^ID=" | cut -d= -f2 | tr -d '"')
VERSION=$(cat /etc/os-release | grep "^VERSION_CODENAME=" | cut -d= -f2 | tr -d '"')
print_info "System: ${OS} ${VERSION} on ${ARCH}"
# Check if we're on a Raspberry Pi
if [ -f /proc/device-tree/model ]; then
MODEL=$(tr -d '\0' < /proc/device-tree/model)
print_info "Raspberry Pi detected: ${MODEL}"
fi
# Check available memory
if [ -f /proc/meminfo ]; then
TOTAL_MEM=$(grep MemTotal /proc/meminfo | awk '{print $2}')
TOTAL_MEM_MB=$((TOTAL_MEM / 1024))
print_info "Available RAM: ${TOTAL_MEM_MB}MB"
if [ $TOTAL_MEM_MB -lt 512 ]; then
print_warning "Low memory detected! Build may be slow."
print_info "Tip: Consider adding swap space if build fails"
fi
fi
}
# Check for container runtime
check_runtime() {
if command -v podman &> /dev/null; then
RUNTIME="podman"
print_success "Using Podman"
elif command -v docker &> /dev/null; then
RUNTIME="docker"
print_success "Using Docker"
else
print_error "No container runtime found!"
print_info "Install Podman (recommended) or Docker:"
echo " sudo apt-get update"
echo " sudo apt-get install podman"
exit 1
fi
}
# Build the container
build_container() {
print_info "Building container image..."
# Choose the right Dockerfile
if [ -f "Dockerfile.pizero" ] && [[ "$ARCH" == "armv6l" ]]; then
DOCKERFILE="Dockerfile.pizero"
print_info "Using Pi Zero optimized Dockerfile"
elif [ -f "Dockerfile.minimal" ]; then
DOCKERFILE="Dockerfile.minimal"
print_info "Using minimal Dockerfile (no compilation)"
elif [ -f "Dockerfile" ]; then
DOCKERFILE="Dockerfile"
print_warning "Using standard Dockerfile (may require compilation)"
else
print_error "No Dockerfile found!"
exit 1
fi
# Build without memory limits (they may not be supported on all systems)
${RUNTIME} build \
--file "${DOCKERFILE}" \
--tag "${IMAGE_NAME}" \
. || {
print_error "Build failed!"
if [ $TOTAL_MEM_MB -lt 512 ]; then
print_info "Try these solutions for low memory:"
echo " 1. Add swap space:"
echo " sudo dd if=/dev/zero of=/swapfile bs=1M count=1024"
echo " sudo mkswap /swapfile"
echo " sudo swapon /swapfile"
echo " 2. Use pre-built image:"
echo " ${RUNTIME} pull docker.io/yourusername/turmli-calendar:armv6"
fi
exit 1
}
print_success "Container image built successfully!"
}
# Run the container
run_container() {
print_info "Starting container..."
# Check if container already exists
if ${RUNTIME} ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
print_info "Container already exists, removing it..."
${RUNTIME} stop ${CONTAINER_NAME} 2>/dev/null || true
${RUNTIME} rm ${CONTAINER_NAME} 2>/dev/null || true
fi
# Create cache file if it doesn't exist
if [ ! -f "calendar_cache.json" ]; then
echo "{}" > calendar_cache.json
print_info "Created cache file"
fi
# Run container (without memory limits as they may not be supported)
print_info "Starting container..."
${RUNTIME} run -d \
--name ${CONTAINER_NAME} \
-p 8000:8000 \
-v $(pwd)/calendar_cache.json:/app/calendar_cache.json:Z \
-e TZ=Europe/Berlin \
--restart unless-stopped \
${IMAGE_NAME} || {
# If it fails with :Z flag (SELinux label), try without it
print_warning "Retrying without SELinux labels..."
${RUNTIME} run -d \
--name ${CONTAINER_NAME} \
-p 8000:8000 \
-v $(pwd)/calendar_cache.json:/app/calendar_cache.json \
-e TZ=Europe/Berlin \
--restart unless-stopped \
${IMAGE_NAME}
}
print_success "Container started!"
print_info "Access the calendar at: http://$(hostname -I | awk '{print $1}'):8000"
print_info "or http://localhost:8000"
}
# Check container status
check_status() {
print_info "Checking container status..."
if ${RUNTIME} ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -q ${CONTAINER_NAME}; then
${RUNTIME} ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "NAMES|${CONTAINER_NAME}"
# Test if the app is responding
print_info "Testing application..."
sleep 3
if curl -s -f http://localhost:8000/api/events > /dev/null 2>&1; then
print_success "Application is running and healthy!"
else
print_warning "Application not responding yet, checking logs..."
${RUNTIME} logs --tail 20 ${CONTAINER_NAME}
fi
else
print_warning "Container is not running"
fi
}
# Show logs
show_logs() {
${RUNTIME} logs -f ${CONTAINER_NAME}
}
# Main script
case "${1:-build}" in
build)
detect_system
check_runtime
build_container
;;
run)
detect_system
check_runtime
run_container
check_status
;;
start)
detect_system
check_runtime
build_container
run_container
check_status
;;
status)
check_runtime
check_status
;;
logs)
check_runtime
show_logs
;;
stop)
check_runtime
print_info "Stopping container..."
${RUNTIME} stop ${CONTAINER_NAME}
print_success "Container stopped"
;;
help)
echo "Raspberry Pi Build Script for Turmli Calendar"
echo ""
echo "Usage: $0 [COMMAND]"
echo ""
echo "Commands:"
echo " build - Build the container image (default)"
echo " run - Run the container"
echo " start - Build and run"
echo " status - Check container status"
echo " logs - Show container logs"
echo " stop - Stop the container"
echo " help - Show this help"
echo ""
echo "This script is optimized for Raspberry Pi Zero and other"
echo "low-resource ARM devices. It uses Pydantic v1 to avoid"
echo "Rust compilation requirements."
;;
*)
echo "Unknown command: $1"
echo "Run '$0 help' for usage"
exit 1
;;
esac