294 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			294 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/bash
 | 
						||
 | 
						||
# Turmli Bar Calendar Tool - Podman Deployment Script
 | 
						||
# Compatible with Podman and Podman-compose
 | 
						||
 | 
						||
set -e  # Exit on error
 | 
						||
 | 
						||
# 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"
 | 
						||
DEFAULT_PORT=8000
 | 
						||
CACHE_FILE="calendar_cache.json"
 | 
						||
 | 
						||
# 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}"
 | 
						||
}
 | 
						||
 | 
						||
# Check for podman or docker
 | 
						||
check_container_runtime() {
 | 
						||
    if command -v podman &> /dev/null; then
 | 
						||
        RUNTIME="podman"
 | 
						||
        print_success "Podman is installed"
 | 
						||
    elif command -v docker &> /dev/null; then
 | 
						||
        RUNTIME="docker"
 | 
						||
        print_warning "Podman not found, using Docker instead"
 | 
						||
    else
 | 
						||
        print_error "Neither Podman nor Docker is installed. Please install Podman or Docker first."
 | 
						||
        exit 1
 | 
						||
    fi
 | 
						||
}
 | 
						||
 | 
						||
# Check for podman-compose or docker-compose
 | 
						||
check_compose() {
 | 
						||
    if command -v podman-compose &> /dev/null; then
 | 
						||
        COMPOSE="podman-compose"
 | 
						||
        COMPOSE_FILE="podman-compose.yml"
 | 
						||
        print_success "podman-compose is installed"
 | 
						||
    elif command -v docker-compose &> /dev/null; then
 | 
						||
        COMPOSE="docker-compose"
 | 
						||
        COMPOSE_FILE="docker-compose.yml"
 | 
						||
        print_warning "podman-compose not found, using docker-compose instead"
 | 
						||
    else
 | 
						||
        print_warning "Compose tool not found. Will use standalone container commands."
 | 
						||
        COMPOSE=""
 | 
						||
    fi
 | 
						||
}
 | 
						||
 | 
						||
build() {
 | 
						||
    print_info "Building container image..."
 | 
						||
    
 | 
						||
    # Use Containerfile if it exists, otherwise fall back to Dockerfile
 | 
						||
    if [ -f "Containerfile" ]; then
 | 
						||
        BUILD_FILE="Containerfile"
 | 
						||
    else
 | 
						||
        BUILD_FILE="Dockerfile"
 | 
						||
    fi
 | 
						||
    
 | 
						||
    ${RUNTIME} build -f ${BUILD_FILE} -t ${IMAGE_NAME} . || {
 | 
						||
        print_error "Failed to build container image"
 | 
						||
        exit 1
 | 
						||
    }
 | 
						||
    print_success "Container image built successfully"
 | 
						||
}
 | 
						||
 | 
						||
start() {
 | 
						||
    print_info "Starting calendar application..."
 | 
						||
    
 | 
						||
    # Create cache file if it doesn't exist
 | 
						||
    if [ ! -f "${CACHE_FILE}" ]; then
 | 
						||
        echo "{}" > ${CACHE_FILE}
 | 
						||
        print_info "Created cache file: ${CACHE_FILE}"
 | 
						||
    fi
 | 
						||
    
 | 
						||
    if [ -n "$COMPOSE" ] && [ -f "$COMPOSE_FILE" ]; then
 | 
						||
        # Use compose if available
 | 
						||
        print_info "Starting with ${COMPOSE}..."
 | 
						||
        ${COMPOSE} -f ${COMPOSE_FILE} up -d || {
 | 
						||
            print_error "Failed to start application with compose"
 | 
						||
            exit 1
 | 
						||
        }
 | 
						||
    else
 | 
						||
        # Use standalone container command
 | 
						||
        print_info "Starting with ${RUNTIME}..."
 | 
						||
        
 | 
						||
        # Check if container already exists
 | 
						||
        if ${RUNTIME} ps -a --format '{{.Names}}' 2>/dev/null | grep -q "^${CONTAINER_NAME}$"; then
 | 
						||
            print_info "Container already exists, removing it..."
 | 
						||
            ${RUNTIME} rm -f ${CONTAINER_NAME}
 | 
						||
        fi
 | 
						||
        
 | 
						||
        # Run container with Podman-specific options
 | 
						||
        ${RUNTIME} run -d \
 | 
						||
            --name ${CONTAINER_NAME} \
 | 
						||
            -p ${PORT:-$DEFAULT_PORT}:8000 \
 | 
						||
            -e TZ=${TZ:-Europe/Berlin} \
 | 
						||
            -e PYTHONUNBUFFERED=1 \
 | 
						||
            -v $(pwd)/${CACHE_FILE}:/app/${CACHE_FILE}:Z \
 | 
						||
            --restart unless-stopped \
 | 
						||
            ${IMAGE_NAME} || {
 | 
						||
                print_error "Failed to start container"
 | 
						||
                exit 1
 | 
						||
            }
 | 
						||
    fi
 | 
						||
    
 | 
						||
    print_success "Application started successfully"
 | 
						||
    print_info "Access the calendar at: http://localhost:${PORT:-$DEFAULT_PORT}"
 | 
						||
}
 | 
						||
 | 
						||
stop() {
 | 
						||
    print_info "Stopping calendar application..."
 | 
						||
    
 | 
						||
    if [ -n "$COMPOSE" ] && [ -f "$COMPOSE_FILE" ]; then
 | 
						||
        ${COMPOSE} -f ${COMPOSE_FILE} down || true
 | 
						||
    else
 | 
						||
        ${RUNTIME} stop ${CONTAINER_NAME} 2>/dev/null || true
 | 
						||
        ${RUNTIME} rm ${CONTAINER_NAME} 2>/dev/null || true
 | 
						||
    fi
 | 
						||
    
 | 
						||
    print_success "Application stopped"
 | 
						||
}
 | 
						||
 | 
						||
restart() {
 | 
						||
    stop
 | 
						||
    start
 | 
						||
}
 | 
						||
 | 
						||
logs() {
 | 
						||
    if [ -n "$COMPOSE" ] && [ -f "$COMPOSE_FILE" ]; then
 | 
						||
        ${COMPOSE} -f ${COMPOSE_FILE} logs -f
 | 
						||
    else
 | 
						||
        ${RUNTIME} logs -f ${CONTAINER_NAME}
 | 
						||
    fi
 | 
						||
}
 | 
						||
 | 
						||
status() {
 | 
						||
    echo -e "${BLUE}Container Status:${NC}"
 | 
						||
    
 | 
						||
    if [ -n "$COMPOSE" ] && [ -f "$COMPOSE_FILE" ]; then
 | 
						||
        ${COMPOSE} -f ${COMPOSE_FILE} ps
 | 
						||
    else
 | 
						||
        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}"
 | 
						||
        else
 | 
						||
            print_info "Container is not running"
 | 
						||
            return
 | 
						||
        fi
 | 
						||
    fi
 | 
						||
    
 | 
						||
    echo ""
 | 
						||
    print_info "Testing application..."
 | 
						||
    if curl -s -f http://localhost:${PORT:-$DEFAULT_PORT}/api/events > /dev/null 2>&1; then
 | 
						||
        print_success "Application is healthy and responding"
 | 
						||
    else
 | 
						||
        print_error "Application is not responding"
 | 
						||
    fi
 | 
						||
}
 | 
						||
 | 
						||
clean() {
 | 
						||
    print_info "Cleaning up..."
 | 
						||
    stop
 | 
						||
    
 | 
						||
    # Remove image
 | 
						||
    ${RUNTIME} rmi ${IMAGE_NAME} 2>/dev/null || true
 | 
						||
    
 | 
						||
    # Clean up build cache (Podman specific)
 | 
						||
    if [ "$RUNTIME" = "podman" ]; then
 | 
						||
        ${RUNTIME} system prune -f 2>/dev/null || true
 | 
						||
    fi
 | 
						||
    
 | 
						||
    print_success "Cleanup complete"
 | 
						||
}
 | 
						||
 | 
						||
# Generate systemd service for rootless Podman
 | 
						||
generate_systemd() {
 | 
						||
    if [ "$RUNTIME" != "podman" ]; then
 | 
						||
        print_error "Systemd generation is only available for Podman"
 | 
						||
        exit 1
 | 
						||
    fi
 | 
						||
    
 | 
						||
    print_info "Generating systemd service for rootless Podman..."
 | 
						||
    
 | 
						||
    # Check if container is running
 | 
						||
    if ! ${RUNTIME} ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
 | 
						||
        print_error "Container must be running to generate systemd service"
 | 
						||
        print_info "Run './deploy-podman.sh start' first"
 | 
						||
        exit 1
 | 
						||
    fi
 | 
						||
    
 | 
						||
    # Create user systemd directory if it doesn't exist
 | 
						||
    mkdir -p ~/.config/systemd/user/
 | 
						||
    
 | 
						||
    # Generate systemd files
 | 
						||
    ${RUNTIME} generate systemd --name --files --new ${CONTAINER_NAME}
 | 
						||
    
 | 
						||
    # Move to user systemd directory
 | 
						||
    mv container-${CONTAINER_NAME}.service ~/.config/systemd/user/
 | 
						||
    
 | 
						||
    print_success "Systemd service generated"
 | 
						||
    print_info "To enable the service:"
 | 
						||
    echo "  systemctl --user daemon-reload"
 | 
						||
    echo "  systemctl --user enable container-${CONTAINER_NAME}.service"
 | 
						||
    echo "  systemctl --user start container-${CONTAINER_NAME}.service"
 | 
						||
}
 | 
						||
 | 
						||
# Show help
 | 
						||
show_help() {
 | 
						||
    echo "Turmli Bar Calendar - Podman Deployment Script"
 | 
						||
    echo ""
 | 
						||
    echo "Usage: $0 {build|start|stop|restart|logs|status|clean|systemd|help}"
 | 
						||
    echo ""
 | 
						||
    echo "Commands:"
 | 
						||
    echo "  build     - Build the container image"
 | 
						||
    echo "  start     - Build and start the application"
 | 
						||
    echo "  stop      - Stop the application"
 | 
						||
    echo "  restart   - Restart the application"
 | 
						||
    echo "  logs      - Show application logs"
 | 
						||
    echo "  status    - Check application status"
 | 
						||
    echo "  clean     - Remove containers and images"
 | 
						||
    echo "  systemd   - Generate systemd service (Podman only)"
 | 
						||
    echo "  help      - Show this help message"
 | 
						||
    echo ""
 | 
						||
    echo "Environment Variables:"
 | 
						||
    echo "  PORT      - Port to expose (default: 8000)"
 | 
						||
    echo "  TZ        - Timezone (default: Europe/Berlin)"
 | 
						||
}
 | 
						||
 | 
						||
# Main script
 | 
						||
case "$1" in
 | 
						||
    build)
 | 
						||
        check_container_runtime
 | 
						||
        build
 | 
						||
        ;;
 | 
						||
    start)
 | 
						||
        check_container_runtime
 | 
						||
        check_compose
 | 
						||
        build
 | 
						||
        start
 | 
						||
        ;;
 | 
						||
    stop)
 | 
						||
        check_container_runtime
 | 
						||
        check_compose
 | 
						||
        stop
 | 
						||
        ;;
 | 
						||
    restart)
 | 
						||
        check_container_runtime
 | 
						||
        check_compose
 | 
						||
        restart
 | 
						||
        ;;
 | 
						||
    logs)
 | 
						||
        check_container_runtime
 | 
						||
        check_compose
 | 
						||
        logs
 | 
						||
        ;;
 | 
						||
    status)
 | 
						||
        check_container_runtime
 | 
						||
        check_compose
 | 
						||
        status
 | 
						||
        ;;
 | 
						||
    clean)
 | 
						||
        check_container_runtime
 | 
						||
        clean
 | 
						||
        ;;
 | 
						||
    systemd)
 | 
						||
        check_container_runtime
 | 
						||
        generate_systemd
 | 
						||
        ;;
 | 
						||
    help)
 | 
						||
        show_help
 | 
						||
        ;;
 | 
						||
    *)
 | 
						||
        show_help
 | 
						||
        exit 1
 | 
						||
        ;;
 | 
						||
esac |